code: function (doFlush) {
              // Shortcuts
              var data = this._data;
              var dataWords = data.words;
              var dataSigBytes = data.sigBytes;
              var blockSize = this.blockSize;
              var blockSizeBytes = blockSize * 4;
  
              // Count blocks ready
              var nBlocksReady = dataSigBytes / blockSizeBytes;
              if (doFlush) {
                  // Round up to include partial blocks
                  nBlocksReady = Math.ceil(nBlocksReady);
              } else {
                  // Round down to include only full blocks,
                  // less the number of blocks that must remain in the buffer
                  nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
              }
  
              // Count words ready
              var nWordsReady = nBlocksReady * blockSize;
  
              // Count bytes ready
              var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
  
              // Process blocks
              if (nWordsReady) {
                  for (var offset = 0; offset < nWordsReady; offset += blockSize) {
                      // Perform concrete-algorithm logic
                      this._doProcessBlock(dataWords, offset);
                  }
  
                  // Remove processed words
                  var processedWords = dataWords.splice(0, nWordsReady);
                  data.sigBytes -= nBytesReady;
              }
  
              // Return processed words
              return new WordArray.init(processedWords, nBytesReady);
          }
docs: Processes available data blocks.
  
  This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
  
  @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
  
  @return {WordArray} The processed data.
  
  @example
  
  var processedData = bufferedBlockAlgorithm._process();
  var processedData = bufferedBlockAlgorithm._process(!!'flush');