function deflate_slow(s, flush) {
  let hash_head; /* head of hash chain */
  let bflush; /* set if current block must be flushed */
  let 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 === STATUS.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;
    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 && s.prev_length < s.max_lazy_match &&
      s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD
    ) {
      /* 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)
      ) {
        /* 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 === STATUS.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) {
  let hash_head; 
  let bflush; 
  let max_insert;
   for (;;) {
     if (s.lookahead < MIN_LOOKAHEAD) {
      fill_window(s);
      if (s.lookahead < MIN_LOOKAHEAD && flush === STATUS.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 === STATUS.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 ) { let hash_head ; let bflush ; let max_insert ; for ( ; ; ) { if ( s . lookahead < MIN_LOOKAHEAD ) { fill_window ( s ) ; if ( s . lookahead < MIN_LOOKAHEAD && flush === STATUS . 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 === STATUS . 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:
     */ /*** INSERT_STRING(s, s.strstart, hash_head); ***/ /***/ /* Find the longest match, discarding those <= prev_length.
     */ /* 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 */ /* 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); ***/ /***/