anchor.diff:     * @param data List of object
      * @param columns column definition
      */
  -  SlickGrid(this.container, this._data, this.allColumns, [Map options]){
  +  SlickGrid(this.container, this._data, this.allColumns, [Map options]) {
       this.columns = new List<Column>.from(this.allColumns.where((c) => c.visible));
       this._options.addAll(options);
       _storeFormatter();
  
positive.code:     getViewportWidth();
      _getViewportHeight();
  // Account for Frozen Rows
       if (hasFrozenRows) {
           if (_options.frozenBottom) {
               paneTopH = viewportH - frozenRowsHeight - scrollbarDimensions['height'];
               paneBottomH = frozenRowsHeight + scrollbarDimensions['height'];
           } else {
               paneTopH = frozenRowsHeight;
               paneBottomH = viewportH - frozenRowsHeight;
           }
       } else {
           paneTopH = viewportH;
       }
  
  // The top pane includes the top panel and the header row
       paneTopH += topPanelH + headerRowH;
  
       if (_options.frozenColumn> -1 && _options.autoHeight) {
           paneTopH += scrollbarDimensions['height'];
       }
  
       // The top viewport does not contain the top panel or header row
       viewportTopH = paneTopH - topPanelH - headerRowH;
  
       if (_options.autoHeight==true) {
           if (_options.frozenColumn> -1) {
               container.style.height = '${paneTopH + int.parse($headerScrollerL.style.height.replaceFirst("px", ""), onError: (_)=>0)}px';
           }
           $paneTopL.style.position= 'relative';
       }
       $paneTopL.style.top= '${$paneHeaderL.contentEdge.height}px';
       $paneTopL.style.height= '${paneTopH}px';
       //fix me, replase offsetTo to other
      // int paneBottomTop = ($paneTopL.offsetTo($paneTopL.parent).y + paneTopH).round();
       int paneBottomTop = ($paneTopL.offset.top + paneTopH).round();
       $viewportTopL.style.height ='${viewportTopH}px';
  
       if (_options.frozenColumn> -1) {
           $paneTopR.style.top='${$paneHeaderL.contentEdge.height}px';
           $paneTopR.style.height='${paneTopH}px';
  
           $viewportTopR.style.height = '${viewportTopH}px';
  
           if (hasFrozenRows) {
             $paneBottomL.style.top='${paneBottomTop}px';
             $paneBottomL.style.height='${paneBottomH}px';
             $paneBottomR.style.top='${paneBottomTop}px';
             $paneBottomR.style.height='${paneBottomH}px';
             $viewportBottomR.style.height ='${paneBottomH}px';
           }
       } else {
           if (hasFrozenRows) {
               $paneBottomL.style.width='100%';
               $paneBottomL.style.height='${paneBottomH}px';
               $paneBottomL.style.top='${paneBottomTop}px';
           }
       }
  
       if (hasFrozenRows) {
           $viewportBottomL.style.height =  '${paneBottomH}px';
  
           if (_options.frozenBottom) {
               $canvasBottomL.style.height = '${frozenRowsHeight}px';
  
               if (_options.frozenColumn> -1) {
                   $canvasBottomR.style.height = '${frozenRowsHeight}px';
               }
           } else {
               $canvasTopL.style.height =  '${frozenRowsHeight}px';
  
               if (_options.frozenColumn> -1) {
                   $canvasTopR.style.height ='${frozenRowsHeight}px'; //(frozenRowsHeight);
               }
           }
       } else {
         if (_options.frozenColumn> -1) {//no frozen row, but frozen column
                          $viewportTopR.style.height = '${viewportTopH}px'; //(viewportTopH);
         }
       }
  
       if (_options.forceFitColumns==true) {
           autosizeColumns();
       }
  
      /* this looks like duplicate code from line #761.
       * It is very hard to tell if this is outside of the last closing }
  
negative.code:   Element $headerScrollerL;
    Element $headerScrollerR;
  
    Element $headerL;
    Element $headerR;
  
    Element $headerRowScrollerL;
    Element $headerRowScrollerR;
  
    Element $headerRowL;
    Element $headerRowR;
  
    Element $topPanelScrollerL;
    Element $topPanelScrollerR;
  
    Element $topPanelL;
    Element $topPanelR;
  
    Element $viewportTopL;
    Element $viewportTopR;
    Element $viewportBottomL;
    Element $viewportBottomR;
  
    // canvas,
    // very long and wide area that hold real row elements
    Element $canvasTopL;
    Element $canvasTopR;
    Element $canvasBottomL;
    Element $canvasBottomR;
  
    Element $viewportScrollContainerX;
    Element $viewportScrollContainerY;
    Element $headerScrollContainer;
    Element $headerRowScrollContainer;
  
    //  {}
    //   1~N => block
    //   N+1 ~ 2N => block
    //  2N+1 ~ 3N => block
    // sort => re calculat every row
    // insert => increase height of block and shift of each block
    //
  
    /////////////////////////////one line accesser
    int getDataLength() => _data.length;
    int getColumnIndex(String id) => columnsById[id];
    List getSortColumns() => sortColumns;
    List<Column> getColumns() => columns;
    handleSelectedRangesChanged(core.EventData e, List<core.Range> ranges) {
      selectedRows = [];
      Map<int, Map<String, String>> hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          if (!hash.containsKey(j)) {
            // prevent duplicates
            selectedRows.add(j);
            hash[j] = {};
          }
  