function deflate_slow(s, flush) {
	  var hash_head;          /* head of hash chain */
	  var bflush;              /* set if current block must be flushed */
	
	  var max_insert;
	
	  /* Process the input block. */
	  for (;;) {
	    /* Make sure that we always have enough lookahead, except
	     * at the end of the input file. We need MAX_MATCH bytes
	     * for the next match, plus MIN_MATCH bytes to insert the
	     * string following the next match.
	     */
	    if (s.lookahead < MIN_LOOKAHEAD) {
	      fill_window(s);
	      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
	        return BS_NEED_MORE;
	      }
	      if (s.lookahead === 0) { break; } /* flush the current block */
	    }
	
	    /* Insert the string window[strstart .. strstart+2] in the
	     * dictionary, and set hash_head to the head of the hash chain:
	     */
	    hash_head = 0/*NIL*/;
	    if (s.lookahead >= MIN_MATCH) {
	      /*** INSERT_STRING(s, s.strstart, hash_head); ***/
	      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
	      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
	      s.head[s.ins_h] = s.strstart;
	      /***/
	    }
	
	    /* Find the longest match, discarding those <= prev_length.
	     */
	    s.prev_length = s.match_length;
	    s.prev_match = s.match_start;
	    s.match_length = MIN_MATCH-1;
	
	    if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
	        s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
	      /* To simplify the code, we prevent matches with the string
	       * of window index 0 (in particular we have to avoid a match
	       * of the string with itself at the start of the input file).
	       */
	      s.match_length = longest_match(s, hash_head);
	      /* longest_match() sets match_start */
	
	      if (s.match_length <= 5 &&
	         (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
	
	        /* If prev_match is also MIN_MATCH, match_start is garbage
	         * but we will ignore the current match anyway.
	         */
	        s.match_length = MIN_MATCH-1;
	      }
	    }
	    /* If there was a match at the previous step and the current
	     * match is not better, output the previous match:
	     */
	    if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
	      max_insert = s.strstart + s.lookahead - MIN_MATCH;
	      /* Do not insert strings in hash table beyond this. */
	
	      //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
	
	      /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
	                     s.prev_length - MIN_MATCH, bflush);***/
	      bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH);
	      /* Insert in hash table all strings up to the end of the match.
	       * strstart-1 and strstart are already inserted. If there is not
	       * enough lookahead, the last two strings are not inserted in
	       * the hash table.
	       */
	      s.lookahead -= s.prev_length-1;
	      s.prev_length -= 2;
	      do {
	        if (++s.strstart <= max_insert) {
	          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
	          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
	          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
	          s.head[s.ins_h] = s.strstart;
	          /***/
	        }
	      } while (--s.prev_length !== 0);
	      s.match_available = 0;
	      s.match_length = MIN_MATCH-1;
	      s.strstart++;
	
	      if (bflush) {
	        /*** FLUSH_BLOCK(s, 0); ***/
	        flush_block_only(s, false);
	        if (s.strm.avail_out === 0) {
	          return BS_NEED_MORE;
	        }
	        /***/
	      }
	
	    } else if (s.match_available) {
	      /* If there was no match at the previous position, output a
	       * single literal. If there was a match but the current match
	       * is longer, truncate the previous match to a single literal.
	       */
	      //Tracevv((stderr,"%c", s->window[s->strstart-1]));
	      /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
	      bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]);
	
	      if (bflush) {
	        /*** FLUSH_BLOCK_ONLY(s, 0) ***/
	        flush_block_only(s, false);
	        /***/
	      }
	      s.strstart++;
	      s.lookahead--;
	      if (s.strm.avail_out === 0) {
	        return BS_NEED_MORE;
	      }
	    } else {
	      /* There is no previous match to compare with, wait for
	       * the next step to decide.
	       */
	      s.match_available = 1;
	      s.strstart++;
	      s.lookahead--;
	    }
	  }
	  //Assert (flush != Z_NO_FLUSH, "no flush?");
	  if (s.match_available) {
	    //Tracevv((stderr,"%c", s->window[s->strstart-1]));
	    /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
	    bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]);
	
	    s.match_available = 0;
	  }
	  s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1;
	  if (flush === Z_FINISH) {
	    /*** FLUSH_BLOCK(s, 1); ***/
	    flush_block_only(s, true);
	    if (s.strm.avail_out === 0) {
	      return BS_FINISH_STARTED;
	    }
	    /***/
	    return BS_FINISH_DONE;
	  }
	  if (s.last_lit) {
	    /*** FLUSH_BLOCK(s, 0); ***/
	    flush_block_only(s, false);
	    if (s.strm.avail_out === 0) {
	      return BS_NEED_MORE;
	    }
	    /***/
	  }
	
	  return BS_BLOCK_DONE;
	}
/* ===========================================================================
	 * Same as above, but achieves better compression. We use a lazy
	 * evaluation for matches: a match is finally adopted only if there is
	 * no better match at the next window position.
	 */
Same as above, but achieves better compression. We use a lazy
evaluation for matches: a match is finally adopted only if there is
no better match at the next window position.
Same as above but achieves better compression . We use a lazy evaluation for matches : a match is finally adopted only if there is no better match at the next window position .
function deflate_slow(s, flush) {
	  var hash_head;          
	  var bflush;              
	  var max_insert;
	  for (;;) {
	    if (s.lookahead < MIN_LOOKAHEAD) {
	      fill_window(s);
	      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
	        return BS_NEED_MORE;
	      }
	      if (s.lookahead === 0) { break; } 
	    }
	    hash_head = 0;
	    if (s.lookahead >= MIN_MATCH) {
	      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
	      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
	      s.head[s.ins_h] = s.strstart;
	    }
	    s.prev_length = s.match_length;
	    s.prev_match = s.match_start;
	    s.match_length = MIN_MATCH-1;
	    if (hash_head !== 0 && s.prev_length < s.max_lazy_match &&
	        s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)) {
	      s.match_length = longest_match(s, hash_head);
	      if (s.match_length <= 5 &&
	         (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096))) {
	        s.match_length = MIN_MATCH-1;
	      }
	    }
	    if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
	      max_insert = s.strstart + s.lookahead - MIN_MATCH;
	      bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH);
	      s.lookahead -= s.prev_length-1;
	      s.prev_length -= 2;
	      do {
	        if (++s.strstart <= max_insert) {
	          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
	          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
	          s.head[s.ins_h] = s.strstart;
	        }
	      } while (--s.prev_length !== 0);
	      s.match_available = 0;
	      s.match_length = MIN_MATCH-1;
	      s.strstart++;
	      if (bflush) {
	        flush_block_only(s, false);
	        if (s.strm.avail_out === 0) {
	          return BS_NEED_MORE;
	        }
	      }
	    } else if (s.match_available) {
	      bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]);
	      if (bflush) {
	        flush_block_only(s, false);
	      }
	      s.strstart++;
	      s.lookahead--;
	      if (s.strm.avail_out === 0) {
	        return BS_NEED_MORE;
	      }
	    } else {
	      s.match_available = 1;
	      s.strstart++;
	      s.lookahead--;
	    }
	  }
	  if (s.match_available) {
	    bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]);
	    s.match_available = 0;
	  }
	  s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1;
	  if (flush === Z_FINISH) {
	    flush_block_only(s, true);
	    if (s.strm.avail_out === 0) {
	      return BS_FINISH_STARTED;
	    }
	    return BS_FINISH_DONE;
	  }
	  if (s.last_lit) {
	    flush_block_only(s, false);
	    if (s.strm.avail_out === 0) {
	      return BS_NEED_MORE;
	    }
	  }
	  return BS_BLOCK_DONE;
	}
function deflate_slow ( s , flush ) { var hash_head ; var bflush ; var max_insert ; for ( ; ; ) { if ( s . lookahead < MIN_LOOKAHEAD ) { fill_window ( s ) ; if ( s . lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH ) { return BS_NEED_MORE ; } if ( s . lookahead === 0 ) { break ; } } hash_head = 0 ; if ( s . lookahead >= MIN_MATCH ) { s . ins_h = ( ( s . ins_h << s . hash_shift ) ^ s . window [ s . strstart + MIN_MATCH - 1 ] ) & s . hash_mask ; hash_head = s . prev [ s . strstart & s . w_mask ] = s . head [ s . ins_h ] ; s . head [ s . ins_h ] = s . strstart ; } s . prev_length = s . match_length ; s . prev_match = s . match_start ; s . match_length = MIN_MATCH - 1 ; if ( hash_head !== 0 && s . prev_length < s . max_lazy_match && s . strstart - hash_head <= ( s . w_size - MIN_LOOKAHEAD ) ) { s . match_length = longest_match ( s , hash_head ) ; if ( s . match_length <= 5 && ( s . strategy === Z_FILTERED || ( s . match_length === MIN_MATCH && s . strstart - s . match_start > 4096 ) ) ) { s . match_length = MIN_MATCH - 1 ; } } if ( s . prev_length >= MIN_MATCH && s . match_length <= s . prev_length ) { max_insert = s . strstart + s . lookahead - MIN_MATCH ; bflush = trees . _tr_tally ( s , s . strstart - 1 - s . prev_match , s . prev_length - MIN_MATCH ) ; s . lookahead -= s . prev_length - 1 ; s . prev_length -= 2 ; do { if ( ++ s . strstart <= max_insert ) { s . ins_h = ( ( s . ins_h << s . hash_shift ) ^ s . window [ s . strstart + MIN_MATCH - 1 ] ) & s . hash_mask ; hash_head = s . prev [ s . strstart & s . w_mask ] = s . head [ s . ins_h ] ; s . head [ s . ins_h ] = s . strstart ; } } while ( -- s . prev_length !== 0 ) ; s . match_available = 0 ; s . match_length = MIN_MATCH - 1 ; s . strstart ++ ; if ( bflush ) { flush_block_only ( s , false ) ; if ( s . strm . avail_out === 0 ) { return BS_NEED_MORE ; } } } else if ( s . match_available ) { bflush = trees . _tr_tally ( s , 0 , s . window [ s . strstart - 1 ] ) ; if ( bflush ) { flush_block_only ( s , false ) ; } s . strstart ++ ; s . lookahead -- ; if ( s . strm . avail_out === 0 ) { return BS_NEED_MORE ; } } else { s . match_available = 1 ; s . strstart ++ ; s . lookahead -- ; } } if ( s . match_available ) { bflush = trees . _tr_tally ( s , 0 , s . window [ s . strstart - 1 ] ) ; s . match_available = 0 ; } s . insert = s . strstart < MIN_MATCH - 1 ? s . strstart : MIN_MATCH - 1 ; if ( flush === Z_FINISH ) { flush_block_only ( s , true ) ; if ( s . strm . avail_out === 0 ) { return BS_FINISH_STARTED ; } return BS_FINISH_DONE ; } if ( s . last_lit ) { flush_block_only ( s , false ) ; if ( s . strm . avail_out === 0 ) { return BS_NEED_MORE ; } } return BS_BLOCK_DONE ; }
Same as above, but achieves better compression.
Same as above but achieves better compression .
/* head of hash chain */ /* set if current block must be flushed */ /* Process the input block. */ /* Make sure that we always have enough lookahead, except
	     * at the end of the input file. We need MAX_MATCH bytes
	     * for the next match, plus MIN_MATCH bytes to insert the
	     * string following the next match.
	     */ /* flush the current block */ /* Insert the string window[strstart .. strstart+2] in the
	     * dictionary, and set hash_head to the head of the hash chain:
	     */ /*NIL*/ /*** INSERT_STRING(s, s.strstart, hash_head); ***/ /***/ /* Find the longest match, discarding those <= prev_length.
	     */ /*NIL*/ /*MAX_DIST(s)*/ /* To simplify the code, we prevent matches with the string
	       * of window index 0 (in particular we have to avoid a match
	       * of the string with itself at the start of the input file).
	       */ /* longest_match() sets match_start */ /*TOO_FAR*/ /* If prev_match is also MIN_MATCH, match_start is garbage
	         * but we will ignore the current match anyway.
	         */ /* If there was a match at the previous step and the current
	     * match is not better, output the previous match:
	     */ /* Do not insert strings in hash table beyond this. */ //check_match(s, s.strstart-1, s.prev_match, s.prev_length); /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
	                     s.prev_length - MIN_MATCH, bflush);***/ /* Insert in hash table all strings up to the end of the match.
	       * strstart-1 and strstart are already inserted. If there is not
	       * enough lookahead, the last two strings are not inserted in
	       * the hash table.
	       */ /*** INSERT_STRING(s, s.strstart, hash_head); ***/ /***/ /*** FLUSH_BLOCK(s, 0); ***/ /***/ /* If there was no match at the previous position, output a
	       * single literal. If there was a match but the current match
	       * is longer, truncate the previous match to a single literal.
	       */ //Tracevv((stderr,"%c", s->window[s->strstart-1])); /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ /*** FLUSH_BLOCK_ONLY(s, 0) ***/ /***/ /* There is no previous match to compare with, wait for
	       * the next step to decide.
	       */ //Assert (flush != Z_NO_FLUSH, "no flush?"); //Tracevv((stderr,"%c", s->window[s->strstart-1])); /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ /*** FLUSH_BLOCK(s, 1); ***/ /***/ /*** FLUSH_BLOCK(s, 0); ***/ /***/