<commit_before>var FORMAT_TYPE = (function(){
  (function f_uint8(data){
    var num;

    num = data.shift();

    return num;
  });

  (function f_uint16(data){
    var num;

    num = data.shift();
    num += Math.pow(2, 8) * data.shift();

    return num;
  });

  (function f_uint32(data){
    var num;

    num = data.shift();
    num += Math.pow(2, 8) * data.shift();
    num += Math.pow(2, 16) * data.shift();
    num += Math.pow(2, 24) * data.shift();

    return num;
  });

  (function f_sint8(data){
    var num;

    num = f_uint8(data);

    if(num > (Math.pow(2, 7) - 1)){
      num = num - Math.pow(2, 8);
    }

    return num;
  });

  (function f_sint16(data){
    var num;

    num = f_uint16(data);

    if(num > (Math.pow(2, 15) - 1)){
      num = num - Math.pow(2, 16);
    }

    return num;
  });

  (function f_sint32(data){
    var num;

    num = f_uint32(data);

    if(num > (Math.pow(2, 31) - 1)){
      num = num - Math.pow(2, 32);
    }

    return num;
  });

  (function f_hex8(data){
    var num;

    num = f_uint8(data);

    return "0x" + ("00"+ num.toString(16)).slice(-2);
  });

  (function f_hex16(data){
    var num;

    num = f_uint16(data);

    return "0x" + ("0000"+ num.toString(16)).slice(-4);
  });

  (function f_hex32(data){
    var num;

    num = f_uint32(data);

    return "0x" + ("00000000"+ num.toString(16)).slice(-8);
  });

  (function f_bit8(data){
    var num;

    num = f_uint8(data);

    return "b" + num.toString(2);
  });

  (function f_bit16(data){
    var num;

    num = f_uint16(data);

    return "b" + num.toString(2);
  });

  (function f_bit32(data){
    var num;

    num = f_uint32(data);

    return "b" + num.toString(2);
  });

  (function f_oct8(data){
    var num;

    num = f_uint8(data);

    return "0" + num.toString(8);
  });

  (function f_oct16(data){
    var num;

    num = f_uint16(data);

    return "0" + num.toString(8);
  });

  (function f_oct32(data){
    var num;

    num = f_uint32(data);

    return "0" + num.toString(8);
  });

  (function f_dummy8(data){
    f_uint8(data);

    return null;
  });

  (function f_dummy16(data){
    f_uint16(data);

    return null;
  });

  (function f_dummy32(data){
    f_uint32(data);

    return null;
  });

  return [
     { "type" : "UINT8"   , "size" : 1, "func" : f_uint8   }
    ,{ "type" : "UINT16"  , "size" : 2, "func" : f_uint16  }
    ,{ "type" : "UINT32"  , "size" : 4, "func" : f_uint32  }
    ,{ "type" : "SINT8"   , "size" : 1, "func" : f_sint8   }
    ,{ "type" : "SINT16"  , "size" : 2, "func" : f_sint16  }
    ,{ "type" : "SINT32"  , "size" : 4, "func" : f_sint32  }
    ,{ "type" : "HEX8"    , "size" : 1, "func" : f_hex8    }
    ,{ "type" : "HEX16"   , "size" : 2, "func" : f_hex16   }
    ,{ "type" : "HEX32"   , "size" : 4, "func" : f_hex32   }
    ,{ "type" : "BIT8"    , "size" : 1, "func" : f_bit8    }
    ,{ "type" : "BIT16"   , "size" : 2, "func" : f_bit16   }
    ,{ "type" : "BIT32"   , "size" : 4, "func" : f_bit32   }
    ,{ "type" : "OCT8"    , "size" : 1, "func" : f_oct8    }
    ,{ "type" : "OCT16"   , "size" : 2, "func" : f_oct16   }
    ,{ "type" : "OCT32"   , "size" : 4, "func" : f_oct32   }
    ,{ "type" : "DUMMY8"  , "size" : 1, "func" : f_dummy8  }
    ,{ "type" : "DUMMY16" , "size" : 2, "func" : f_dummy16 }
    ,{ "type" : "DUMMY32" , "size" : 4, "func" : f_dummy32 }
  ];
})();

var wTrTool = {};

// command line argument
(function(){
  var opt = {};

  var objArgs = WScript.Arguments;

  optGet = (function(objArgs, key , default_value){
    if(objArgs.Named.Exists(key) && (objArgs.Named.Item(key) !== undefined)){
      return objArgs.Named.Item(key);
    }else{
      return default_value;
    }
  });

  var options = [
                /* key,     default_value */
                ["input",   "input.dat"]
              , ["output",  "output.csv"]
              , ["format",  "format.json"]
              , ["pattern", "sample"]
              , ["endian",  true]
            ];

  for(var i = 0; i < options.length; i++){
    opt[options[i][0]] = optGet(objArgs, options[i][0], options[i][1]);
  }

//  WScript.Echo( "opt = " + JSON.stringify(opt) );

  wTrTool.option = opt;
})();

// pattern select
(function(){

  var objFS = new ActiveXObject("Scripting.FileSystemObject");

  var format_stream = objFS.OpenTextFile(wTrTool.option.format, 1, false, -2);
  var format_txt = format_stream.ReadAll();
  var formats = JSON.parse(format_txt);
  var pattern = null;

  for(var i = 0; i < formats.length; i++){
    if(formats[i].patternname === wTrTool.option.pattern){
      pattern = formats[i];
      break;
    }
  }

  if(pattern === null){
    WScript.Echo( "Error: pattern not found" );
    WScript.Quit(-1);
  }

  wTrTool.pattern = pattern;

})();

// format preproc
(function(){
  var format = [];
  var prefix = "";
  var suffix = "";

  (function format_convert(format, pattern, prefix, suffix){
    for(var i = 0; i < pattern.length; i++){
      if("union" in pattern[i]){
        // WScript.Echo( "union" );
        var union_obj = {};
        union_obj.label = pattern[i].label;
        union_obj.union = [];
        for(var k = 0; k < pattern[i].union.length; k++){
          var tbl = [];
          var union_prefix_top = "";
          var union_prefix_bottom = "";
          if(prefix === ""){
            union_prefix_top = "";
          }else{
            union_prefix_top = prefix + ".";
          }
          union_prefix_bottom = pattern[i].label + "." + pattern[i].union[k].label + ".";
          format_convert(tbl, pattern[i].union[k].format, union_prefix_top + union_prefix_bottom, suffix);
          union_obj.union.push( tbl );
        }
        format.push(union_obj);
      }else if("array" in pattern[i]){
        // WScript.Echo( "array" );
        for(var j = 0; j < pattern[i].array.num; j++){
          var array_suffix = "[" + j + "]";
          var array_prefix = "";
          if(prefix === ""){
            array_prefix = pattern[i].label;
          }else{
            array_prefix = prefix + suffix + "." + pattern[i].label;
          }
          format_convert(format, pattern[i].array.format, array_prefix, array_suffix);
        }
      }else{
        // WScript.Echo( "member" );
        var obj = {};
        obj.type = pattern[i].type;
        if(suffix === ""){
          obj.label = prefix + pattern[i].label;
        }else{
          if(pattern[i].label === ""){
            obj.label = prefix + suffix;
          }else{
            obj.label = prefix + suffix + "." + pattern[i].label;
          }
        }
        format.push(obj);
      }
    }
  })(format, wTrTool.pattern.format, prefix, suffix);

  wTrTool.format = format;
})();

// input file read
(function(){

  var a = WSH_BINARY.Readfile2Array(wTrTool.option.input);

  wTrTool.binarys = a;

})();

debugPrint = (function(){
  WScript.Echo( JSON.stringify(wTrTool.pattern) );
  WScript.Echo( "========================================================================" );
  WScript.Echo( JSON.stringify(wTrTool.binarys) );
  WScript.Echo( "========================================================================" );
  WScript.Echo( JSON.stringify(wTrTool.format) );
  WScript.Echo( "========================================================================" );
});
// debugPrint();

// output
(function(){
  var top = [];
  var binarys = wTrTool.binarys;

  (function make_header_str(header,format){
    // WScript.Echo( JSON.stringify( format ) );

    if("type" in format){
      if(format.type.search("DUMMY") === -1){
        header.push(format.label);
      }
    }else{
      for(var i = 0; i < format.length; i++){
        if("union" in format[i]){
          // WScript.Echo( "union" );
          make_header_str(header, format[i].union);
        }else if("type" in format[i]){
          make_header_str(header, format[i]);
        }else{
          for(var j = 0; j < format[i].length; j++){
            make_header_str(header, format[i][j]);
          }
        }
      }
    }
  })(top, wTrTool.format);

  WScript.Echo( JSON.stringify(top) );
  WScript.Echo( "------------------------------------------------------------------------" );

  while(binarys.length > 0){
    var data = [];

    binarys = (function make_convert_str(str, tbl, format){
      if(tbl.length !== 0){
        if("union" in format){
          //@TODO
          var union_tbl = JSON.parse( JSON.stringify( tbl ) );
          var min_tbl = JSON.parse( JSON.stringify( tbl ) );
          for(var j = 0; j < format.union.length; j++){
            var temp_tbl = JSON.parse( JSON.stringify( union_tbl ) );
            temp_tbl = make_convert_str(str, temp_tbl, format.union[j]);
            if(min_tbl.length > temp_tbl.length){
              min_tbl = JSON.parse( JSON.stringify( temp_tbl ) );
            }
          }
          tbl = JSON.parse( JSON.stringify( min_tbl ) );
        }else if("label" in format){
          var flg = true;
          for(var k = 0; k < FORMAT_TYPE.length; k++){
            if(FORMAT_TYPE[k].type === format.type){
              var bytes = [];
              flg = false;
              for(var l = 0; l < FORMAT_TYPE[k].size; l++){
                if(tbl.length != 0){
                  bytes.push(tbl.shift());
                }
              }

              if(wTrTool.option.endian === false){
                bytes = bytes.reverse();
              }

              if(bytes.length === FORMAT_TYPE[k].size){
                var ret;
                ret = FORMAT_TYPE[k].func(bytes);
                if(ret !== null){
                  str.push(ret);
                }
              }
            }
          }
          if(flg){
            WScript.Echo("Error : invalid type");
            WScript.Quit(-1);
          }
        }else{
          for(var i = 0; i < format.length; i++){
            tbl = make_convert_str(str, tbl, format[i]);
          }
        }
      }

      return tbl;
    })(data, binarys, wTrTool.format);

    WScript.Echo( JSON.stringify(data) );
  }

})();

<commit_msg>BITx,OCTx　ruby版と出力合わせる<commit_after>var FORMAT_TYPE = (function(){
  (function f_uint8(data){
    var num;

    num = data.shift();

    return num;
  });

  (function f_uint16(data){
    var num;

    num = data.shift();
    num += Math.pow(2, 8) * data.shift();

    return num;
  });

  (function f_uint32(data){
    var num;

    num = data.shift();
    num += Math.pow(2, 8) * data.shift();
    num += Math.pow(2, 16) * data.shift();
    num += Math.pow(2, 24) * data.shift();

    return num;
  });

  (function f_sint8(data){
    var num;

    num = f_uint8(data);

    if(num > (Math.pow(2, 7) - 1)){
      num = num - Math.pow(2, 8);
    }

    return num;
  });

  (function f_sint16(data){
    var num;

    num = f_uint16(data);

    if(num > (Math.pow(2, 15) - 1)){
      num = num - Math.pow(2, 16);
    }

    return num;
  });

  (function f_sint32(data){
    var num;

    num = f_uint32(data);

    if(num > (Math.pow(2, 31) - 1)){
      num = num - Math.pow(2, 32);
    }

    return num;
  });

  (function f_hex8(data){
    var num;

    num = f_uint8(data);

    return "0x" + ("00"+ num.toString(16)).slice(-2);
  });

  (function f_hex16(data){
    var num;

    num = f_uint16(data);

    return "0x" + ("0000"+ num.toString(16)).slice(-4);
  });

  (function f_hex32(data){
    var num;

    num = f_uint32(data);

    return "0x" + ("00000000"+ num.toString(16)).slice(-8);
  });

  (function f_bit8(data){
    var num;

    num = f_uint8(data);

    return "0b" + ("00000000" + num.toString(2)).slice(-8);
  });

  (function f_bit16(data){
    var num;

    num = f_uint16(data);

    return "0b" + ("0000000000000000" + num.toString(2)).slice(-16);
  });

  (function f_bit32(data){
    var num;

    num = f_uint32(data);

    return "0b" + ("00000000000000000000000000000000" + num.toString(2)).slice(-32);
  });

  (function f_oct8(data){
    var num;

    num = f_uint8(data);

    return "0" + ("000" + num.toString(8)).slice(-3);
  });

  (function f_oct16(data){
    var num;

    num = f_uint16(data);

    return "0" + ("000000" + num.toString(8)).slice(-6);
  });

  (function f_oct32(data){
    var num;

    num = f_uint32(data);

    return "0" + ("00000000000" + num.toString(8)).slice(-11);
  });

  (function f_dummy8(data){
    f_uint8(data);

    return null;
  });

  (function f_dummy16(data){
    f_uint16(data);

    return null;
  });

  (function f_dummy32(data){
    f_uint32(data);

    return null;
  });

  return [
     { "type" : "UINT8"   , "size" : 1, "func" : f_uint8   }
    ,{ "type" : "UINT16"  , "size" : 2, "func" : f_uint16  }
    ,{ "type" : "UINT32"  , "size" : 4, "func" : f_uint32  }
    ,{ "type" : "SINT8"   , "size" : 1, "func" : f_sint8   }
    ,{ "type" : "SINT16"  , "size" : 2, "func" : f_sint16  }
    ,{ "type" : "SINT32"  , "size" : 4, "func" : f_sint32  }
    ,{ "type" : "HEX8"    , "size" : 1, "func" : f_hex8    }
    ,{ "type" : "HEX16"   , "size" : 2, "func" : f_hex16   }
    ,{ "type" : "HEX32"   , "size" : 4, "func" : f_hex32   }
    ,{ "type" : "BIT8"    , "size" : 1, "func" : f_bit8    }
    ,{ "type" : "BIT16"   , "size" : 2, "func" : f_bit16   }
    ,{ "type" : "BIT32"   , "size" : 4, "func" : f_bit32   }
    ,{ "type" : "OCT8"    , "size" : 1, "func" : f_oct8    }
    ,{ "type" : "OCT16"   , "size" : 2, "func" : f_oct16   }
    ,{ "type" : "OCT32"   , "size" : 4, "func" : f_oct32   }
    ,{ "type" : "DUMMY8"  , "size" : 1, "func" : f_dummy8  }
    ,{ "type" : "DUMMY16" , "size" : 2, "func" : f_dummy16 }
    ,{ "type" : "DUMMY32" , "size" : 4, "func" : f_dummy32 }
  ];
})();

var wTrTool = {};

// command line argument
(function(){
  var opt = {};

  var objArgs = WScript.Arguments;

  optGet = (function(objArgs, key , default_value){
    if(objArgs.Named.Exists(key) && (objArgs.Named.Item(key) !== undefined)){
      return objArgs.Named.Item(key);
    }else{
      return default_value;
    }
  });

  var options = [
                /* key,     default_value */
                ["input",   "input.dat"]
              , ["output",  "output.csv"]
              , ["format",  "format.json"]
              , ["pattern", "sample"]
              , ["endian",  true]
            ];

  for(var i = 0; i < options.length; i++){
    opt[options[i][0]] = optGet(objArgs, options[i][0], options[i][1]);
  }

//  WScript.Echo( "opt = " + JSON.stringify(opt) );

  wTrTool.option = opt;
})();

// pattern select
(function(){

  var objFS = new ActiveXObject("Scripting.FileSystemObject");

  var format_stream = objFS.OpenTextFile(wTrTool.option.format, 1, false, -2);
  var format_txt = format_stream.ReadAll();
  var formats = JSON.parse(format_txt);
  var pattern = null;

  for(var i = 0; i < formats.length; i++){
    if(formats[i].patternname === wTrTool.option.pattern){
      pattern = formats[i];
      break;
    }
  }

  if(pattern === null){
    WScript.Echo( "Error: pattern not found" );
    WScript.Quit(-1);
  }

  wTrTool.pattern = pattern;

})();

// format preproc
(function(){
  var format = [];
  var prefix = "";
  var suffix = "";

  (function format_convert(format, pattern, prefix, suffix){
    for(var i = 0; i < pattern.length; i++){
      if("union" in pattern[i]){
        // WScript.Echo( "union" );
        var union_obj = {};
        union_obj.label = pattern[i].label;
        union_obj.union = [];
        for(var k = 0; k < pattern[i].union.length; k++){
          var tbl = [];
          var union_prefix_top = "";
          var union_prefix_bottom = "";
          if(prefix === ""){
            union_prefix_top = "";
          }else{
            union_prefix_top = prefix + ".";
          }
          union_prefix_bottom = pattern[i].label + "." + pattern[i].union[k].label + ".";
          format_convert(tbl, pattern[i].union[k].format, union_prefix_top + union_prefix_bottom, suffix);
          union_obj.union.push( tbl );
        }
        format.push(union_obj);
      }else if("array" in pattern[i]){
        // WScript.Echo( "array" );
        for(var j = 0; j < pattern[i].array.num; j++){
          var array_suffix = "[" + j + "]";
          var array_prefix = "";
          if(prefix === ""){
            array_prefix = pattern[i].label;
          }else{
            array_prefix = prefix + suffix + "." + pattern[i].label;
          }
          format_convert(format, pattern[i].array.format, array_prefix, array_suffix);
        }
      }else{
        // WScript.Echo( "member" );
        var obj = {};
        obj.type = pattern[i].type;
        if(suffix === ""){
          obj.label = prefix + pattern[i].label;
        }else{
          if(pattern[i].label === ""){
            obj.label = prefix + suffix;
          }else{
            obj.label = prefix + suffix + "." + pattern[i].label;
          }
        }
        format.push(obj);
      }
    }
  })(format, wTrTool.pattern.format, prefix, suffix);

  wTrTool.format = format;
})();

// input file read
(function(){

  var a = WSH_BINARY.Readfile2Array(wTrTool.option.input);

  wTrTool.binarys = a;

})();

debugPrint = (function(){
  WScript.Echo( JSON.stringify(wTrTool.pattern) );
  WScript.Echo( "========================================================================" );
  WScript.Echo( JSON.stringify(wTrTool.binarys) );
  WScript.Echo( "========================================================================" );
  WScript.Echo( JSON.stringify(wTrTool.format) );
  WScript.Echo( "========================================================================" );
});
// debugPrint();

// output
(function(){
  var top = [];
  var binarys = wTrTool.binarys;

  (function make_header_str(header,format){
    // WScript.Echo( JSON.stringify( format ) );

    if("type" in format){
      if(format.type.search("DUMMY") === -1){
        header.push(format.label);
      }
    }else{
      for(var i = 0; i < format.length; i++){
        if("union" in format[i]){
          // WScript.Echo( "union" );
          make_header_str(header, format[i].union);
        }else if("type" in format[i]){
          make_header_str(header, format[i]);
        }else{
          for(var j = 0; j < format[i].length; j++){
            make_header_str(header, format[i][j]);
          }
        }
      }
    }
  })(top, wTrTool.format);

  WScript.Echo( JSON.stringify(top) );
  WScript.Echo( "------------------------------------------------------------------------" );

  while(binarys.length > 0){
    var data = [];

    binarys = (function make_convert_str(str, tbl, format){
      if(tbl.length !== 0){
        if("union" in format){
          //@TODO
          var union_tbl = JSON.parse( JSON.stringify( tbl ) );
          var min_tbl = JSON.parse( JSON.stringify( tbl ) );
          for(var j = 0; j < format.union.length; j++){
            var temp_tbl = JSON.parse( JSON.stringify( union_tbl ) );
            temp_tbl = make_convert_str(str, temp_tbl, format.union[j]);
            if(min_tbl.length > temp_tbl.length){
              min_tbl = JSON.parse( JSON.stringify( temp_tbl ) );
            }
          }
          tbl = JSON.parse( JSON.stringify( min_tbl ) );
        }else if("label" in format){
          var flg = true;
          for(var k = 0; k < FORMAT_TYPE.length; k++){
            if(FORMAT_TYPE[k].type === format.type){
              var bytes = [];
              flg = false;
              for(var l = 0; l < FORMAT_TYPE[k].size; l++){
                if(tbl.length != 0){
                  bytes.push(tbl.shift());
                }
              }

              if(wTrTool.option.endian === false){
                bytes = bytes.reverse();
              }

              if(bytes.length === FORMAT_TYPE[k].size){
                var ret;
                ret = FORMAT_TYPE[k].func(bytes);
                if(ret !== null){
                  str.push(ret);
                }
              }
            }
          }
          if(flg){
            WScript.Echo("Error : invalid type");
            WScript.Quit(-1);
          }
        }else{
          for(var i = 0; i < format.length; i++){
            tbl = make_convert_str(str, tbl, format[i]);
          }
        }
      }

      return tbl;
    })(data, binarys, wTrTool.format);

    WScript.Echo( JSON.stringify(data) );
  }

})();

<|endoftext|>


<commit_before>import React from 'react';
import { useTable, usePagination, useSortBy } from 'react-table';
import Table from 'react-bootstrap/Table';
import Pagination from 'react-bootstrap/Pagination';

function paginationItems(count, active, gotoPage) {
  let items = [];
  for (let number = 1; number <= count; number++) {
    items.push(
      <Pagination.Item key={number} active={number === active} onClick={() => gotoPage(number-1)}>
        {number}
      </Pagination.Item>,
    );
  }
  return items;
}

export default function MyTable({ columns, data }) {
  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    state: { pageIndex },
  } = useTable({
    columns,
    data,
    initialState: { pageSize: 15 },
  },
    useSortBy,
    usePagination,
  )

  const paginationUI = pageOptions.length > 1 &&
    <Pagination size="sm" variant="dark">
      <Pagination.First onClick={() => gotoPage(0)} disabled={!canPreviousPage} />
      <Pagination.Prev onClick={() => previousPage()} disabled={!canPreviousPage} />
      {paginationItems(pageOptions.length, pageIndex+1, gotoPage)}
      <Pagination.Next onClick={() => nextPage()} disabled={!canNextPage} />
      <Pagination.Last onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage} />
    </Pagination>;

  return (
    <>

          {headerGroups.map(headerGroup => (

              {headerGroup.headers.map(column => (
                {column.render('Header')}
                 {column.isSorted ? (column.isSortedDesc ? '🔽' : '🔼') : ''}

              ))}

          ))}

          {page.map(
            (row, i) => {
              prepareRow(row);
              return (

                  {row.cells.map(cell => {
                    return {cell.render('Cell')}
                  })}

              )
            }
          )}

      { paginationUI }
    </>
  )
}
<commit_msg>htmlui: added elipsis in pagination bar for super long tables<commit_after>import React from 'react';
import { useTable, usePagination, useSortBy } from 'react-table';
import Table from 'react-bootstrap/Table';
import Pagination from 'react-bootstrap/Pagination';

function paginationItems(count, active, gotoPage) {
  let items = [];

  function pageWithNumber(number) {
    return <Pagination.Item key={number} active={number === active} onClick={() => gotoPage(number-1)}>
      {number}
    </Pagination.Item>;
  }

  function dotDotDot() {
    return <Pagination.Ellipsis />;
  }

  let minPageNumber = active - 10;
  if (minPageNumber < 1) {
    minPageNumber = 1;
  }

  let maxPageNumber = active + 9;
  if (minPageNumber + 19 >= maxPageNumber) {
    maxPageNumber = minPageNumber + 19;
  }
  if (maxPageNumber > count) {
    maxPageNumber = count;
  }

  if (minPageNumber > 1) {
    items.push(dotDotDot());
  }

  for (let number = minPageNumber; number <= maxPageNumber; number++) {
    items.push(pageWithNumber(number));
  }

  if (maxPageNumber < count) {
    items.push(dotDotDot());
  }

  return items;
}

export default function MyTable({ columns, data }) {
  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    state: { pageIndex },
  } = useTable({
    columns,
    data,
    initialState: { pageSize: 15 },
  },
    useSortBy,
    usePagination,
  )

  const paginationUI = pageOptions.length > 1 &&
  <>
    <Pagination size="sm" variant="dark">
      <Pagination.First onClick={() => gotoPage(0)} disabled={!canPreviousPage} />
      <Pagination.Prev onClick={() => previousPage()} disabled={!canPreviousPage} />
      <Pagination.Next onClick={() => nextPage()} disabled={!canNextPage} />
      <Pagination.Last onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage} />
    </Pagination>

    <Pagination size="sm" variant="dark">
      {paginationItems(pageOptions.length, pageIndex+1, gotoPage)}
    </Pagination>
    </>;

  return (
    <>

          {headerGroups.map(headerGroup => (

              {headerGroup.headers.map(column => (
                {column.render('Header')}
                 {column.isSorted ? (column.isSortedDesc ? '🔽' : '🔼') : ''}

              ))}

          ))}

          {page.map(
            (row, i) => {
              prepareRow(row);
              return (

                  {row.cells.map(cell => {
                    return {cell.render('Cell')}
                  })}

              )
            }
          )}

      { paginationUI }
    </>
  )
}
<|endoftext|>


<commit_before>// == units & 10's pows map ==
var exps2 = [
  ['n', 1e-9 ], // n/nΩ --> NanoOhm  ==> 10exp-9 ==> 0,000.000.001
  ['µ', 1e-6 ], // µ/µΩ --> MicroOhm ==> 10exp-6 ==> 0,000.001
  ['m', 1e-3 ], // m/mΩ --> MilliOhm ==> 10exp-3 ==> 0,001
  ['k',  1e3 ], // k/kΩ --> KiloOhm  ==> 10exp3 ==> 1.000
  ['M',  1e6 ], // M/MΩ --> MegaOhm  ==> 10exp6 ==> 1.000.000
  ['G',  1e9 ], // G/GΩ --> GigaOhm  ==> 10exp9 ==> 1.000.000.000
  ['T', 1e12 ], // T/TΩ --> TeraOhm  ==> 10exp12 ==> 1.000.000.000.000
];

// == general coloring scheme ==
var resColorsMap = {
  silver: '#C0C0C0',
  gold:   '#B8860B',
  black:  '#000000',
  brown:  '#A0522D',
  red:    '#FF0000',
  orange: '#FF8C00',
  yellow: '#FFD700',
  green:  '#008000',
  blue:   '#0000CD',
  purple: '#800080',
  gray:   '#808080',
  white:  '#F8F8FF',
};

// == values coloring scheme ==
var resValColorsMap = [
  resColorsMap.black,   // black   ->  0
  resColorsMap.brown,   // brown   ->  1
  resColorsMap.red,     // red     ->  2
  resColorsMap.orange,  // orange  ->  3
  resColorsMap.yellow,  // yellow  ->  4
  resColorsMap.green,   // green   ->  5
  resColorsMap.blue,    // blue    ->  6
  resColorsMap.purple,  // purple  ->  7
  resColorsMap.gray,    // gray    ->  8
  resColorsMap.white,   // white   ->  9
];

// == multiplier coloring scheme == */
var resMultColorsMap = {
         0.01: resColorsMap.silver, // silver  ->  0
         0.1:  resColorsMap.gold,   // gold    ->  1
         1:    resColorsMap.black,  // black   ->  2
        10:    resColorsMap.brown,  // brown   ->  3
       100:    resColorsMap.red,    // red     ->  4
      1000:    resColorsMap.orange, // orange  ->  5
     10000:    resColorsMap.yellow, // yellow  ->  6
    100000:    resColorsMap.green,  // green   ->  7
   1000000:    resColorsMap.blue,   // blue    ->  8
  10000000:    resColorsMap.purple, // purple  ->  9
};

// == tolerance coloring scheme == */
var resTol4bandsColorsMap = {
   0.05: resColorsMap.gray,   // gray   ->  0
   0.1:  resColorsMap.purple, // purple ->  1
   0.25: resColorsMap.blue,   // blue   ->  2
   0.5:  resColorsMap.green,  // green  ->  3
   1:    resColorsMap.brown,  // brown  ->  4
   2:    resColorsMap.red,    // red    ->  5
   5:    resColorsMap.gold,   // gold   ->  6
  10:    resColorsMap.silver, // silver ->  7
}

// helper - loop over the "units & 10's pows map" & see if we have a matching unit
var applyExp2 = function(theValue, theUnity){
  if( theUnity !== ''){
    for( var i=0; i<= exps2.length; i++){
      if (exps2[i][0] === theUnity) {
        return theValue * exps2[i][1];
        break;
      }
    }
  }
  return theValue;
}

// helper - get units & value from resistor values passed as trings ( may or not contain the ending "Ohm" symbol and/or n,µ,.. )
var getUnityIdx = function(valueStr){
  var valueStrArr = valueStr.split('');
  for( var i=0; i<= valueStrArr.length; i++){
    if (isNaN(parseInt(valueStrArr[i])) && valueStrArr[i] !== '.' ) { // to handle stuff like '2.3k'
      idx = i;
      return idx;
      break;
    }
  }
}

// helper - convert some value, not necesseraly a Resistor, to stuff ( including a Resistor )
var convert = function (resValOrStr, unit, type){
  // check whether we're passed a str or a value
  var value;
  if( ! isNaN(resValOrStr) ){
    if( typeof resValOrStr === "string" ) value = Number(resValOrStr);
    else value = resValOrStr;
  } else {
    var unity = resValOrStr.substr( getUnityIdx(resValOrStr) );
    if (unity.substr(-1) === "Ω" ) unity = unity.substr(0, unity.length-1);
    if( unity !== '') value = applyExp2( Number( resValOrStr.substr(0, getUnityIdx(resValOrStr) ) ), unity);
    else value = Number( resValOrStr.substr(0, getUnityIdx(resValOrStr) ) );
  }

  // clean & check what is the desired output unit, & convert value
  if (unit.substr(-1) === "Ω" ) unit = unit.substr(0, unit.length-1);
  var outVal = applyExp2( value, unit);

  // check what we have to return
  if( !typeof type === 'undefined' ){
    if( type === 'str') outVal += '';
    else if( type === 'unit') outVal += unit;
    else if( type === 'unity') outVal += unit + 'Ω';
    else if( type === 'resistor') outVal = Resistor(outVal);
  }

  return outVal;
}

// == Prototype of Resistor ==
function ResistorProto(resVal, resStr){
  this.resValue = resVal;
  this.resString = resStr;
}

// == Fcns shared by all the ResistorProto instances ==
// tests fcn
ResistorProto.prototype.sayHello = function(){ console.log('Hello there: ' + this.resValue) }

// generate fcns to display the value of a resistor with a different unit
exps2.forEach(function(mapItem){
  ResistorProto.prototype['_in' + mapItem[0]] = function(type){
    var outVal = applyExp2( this.resValue, mapItem[0]);

    // check what we have to return
    if( typeof type !== 'undefined' ){
      if( type === 'str') outVal += '';
      else if( type === 'unit') outVal += mapItem[0];
      else if( type === 'unity') outVal += mapItem[0] + 'Ω';
    }

    return outVal;
  };
})

// generate the bands for a Resistor ( 4 bands & 5bands )
ResistorProto.prototype.generateBands2 = function(bands){
  // TODO: handle values above 1 only for the moment ( aka no m,µ,n by now)
  if(this.value < 1){
    console.log('m,µ,n not handled by now ! ')
  } else {
    //console.log('res value is above 1 Ohm: ' + this.resValue)

    // ====
    var colorCodesArr = [];

    if( this.resValue < 10){ // if we only have one digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - one digit')
        colorCodesArr.push ( this.resValue ); // value in 1st, to apply to convention
        colorCodesArr.push ( 0 );             // added 0, same as above
        colorCodesArr.push ( 0.1 );           // adjusted multiplier to comply with the above(s) - 4 band version
        colorCodesArr.push ( '±' );           // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - one digit')
        colorCodesArr.push ( this.resValue ); // value in 1st, to apply to convention
        colorCodesArr.push ( 0 );             // added 0, same as above
        colorCodesArr.push ( 0 );             // added 0, same as above
        colorCodesArr.push ( 0.01 );           // adjusted multiplier to comply with the above(s) - 5 band version
        colorCodesArr.push ( '±' );           // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    else if( this.resValue < 100){ // if we have two digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - two digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( 1 );                     // adjusted multiplier - 4 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - two digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( 0 );                     // added 0, to apply to convention
        colorCodesArr.push ( 0.1 );                   // adjusted multiplier to comply with the above(s) - 5 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    else if( this.resValue < 1000){ // if we have three digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - three digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( 10 );                     // adjusted multiplier ( third digit is discarded ) - 4 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - three digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( Number( (''+this.resValue)[2] ) ); // 3rd digit
        colorCodesArr.push ( 1 );                     // adjusted multiplier - 5 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    else { // if we have more than three digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - more than three digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) );                                         // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) );                                         // 2nd digit
        colorCodesArr.push ( Number( '1' + Array( (''+this.resValue).substr(2).length+1 ).join('0') ) ) // adjusted multiplier - 4 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - more than digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( Number( (''+this.resValue)[2] ) ); // 3rd digit
        colorCodesArr.push ( Number( '1' + Array( (''+this.resValue).substr(3).length+1 ).join('0') ) ) // adjusted multiplier - 5 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    // ====
  }
}

// utility - display the array of bands as colored inline array whatever the number of items
function logBands(bands){
  var color_green = '\x1b[32m', color_yellow = '\x1b[33m', color_def = '\x1b[0m';
  var logStr = '[ ';
  for(var i=0; i < bands.length; i++){
    !isNaN(bands[i]) ? logStr += color_yellow + bands[i] : logStr += color_green + "'" + bands[i] + "'";
    logStr += color_def;
    i < bands.length-1 ? logStr += ', ' : '';
  }
  logStr += ' ]'
  console.log(logStr)
}

//  == Resistor class ( public ) ==
//function Resistor(resVal, resStr){ return new ResistorProto(resVal, resStr) }
function Resistor(resistorValue){
  if( ! isNaN(resistorValue) ){ // decimal
    if( typeof resistorValue === "string" ) this.resValue = Number(resistorValue); // if num passed as str
    else this.resValue = resistorValue;
    this.resStr = resistorValue + 'Ω';
  } else { // string
    // get string stuff until first char: if it's Ohm, strip it, else if maj/min supported char, deduce value
    var unity = resistorValue.substr( getUnityIdx(resistorValue) ); // get the unit part
    if (unity.substr(-1) === "Ω" ) unity = unity.substr(0, unity.length-1); // clean up
    // get actual value
    if( unity !== '') this.resValue = applyExp2( Number( resistorValue.substr(0, getUnityIdx(resistorValue) ) ), unity);
    else this.resValue = Number( resistorValue.substr(0, getUnityIdx(resistorValue) ) );
    this.resStr = resistorValue + 'Ω';
  }

  return new ResistorProto(this.resValue, this.resStr)
}

// == NodeJS module exports ==
module.exports = Resistor;

/*
// usage: instanciate a Resistor
var def = Resistor(400, '400')

// == NodeJS usage ==
var Resistor = require('./Resistor_nodeModule.js')
var def = Resistor(400, '400')
*/
<commit_msg>Update Resistor_nodeModule.js<commit_after>// == units & 10's pows map ==
var exps2 = [
  ['n', 1e-9 ], // n/nΩ --> NanoOhm  ==> 10exp-9 ==> 0,000.000.001
  ['µ', 1e-6 ], // µ/µΩ --> MicroOhm ==> 10exp-6 ==> 0,000.001
  ['m', 1e-3 ], // m/mΩ --> MilliOhm ==> 10exp-3 ==> 0,001
  ['k',  1e3 ], // k/kΩ --> KiloOhm  ==> 10exp3 ==> 1.000
  ['M',  1e6 ], // M/MΩ --> MegaOhm  ==> 10exp6 ==> 1.000.000
  ['G',  1e9 ], // G/GΩ --> GigaOhm  ==> 10exp9 ==> 1.000.000.000
  ['T', 1e12 ], // T/TΩ --> TeraOhm  ==> 10exp12 ==> 1.000.000.000.000
];

// == general coloring scheme ==
var resColorsMap = {
  silver: '#C0C0C0',
  gold:   '#B8860B',
  black:  '#000000',
  brown:  '#A0522D',
  red:    '#FF0000',
  orange: '#FF8C00',
  yellow: '#FFD700',
  green:  '#008000',
  blue:   '#0000CD',
  purple: '#800080',
  gray:   '#808080',
  white:  '#F8F8FF',
};

// == values coloring scheme ==
var resValColorsMap = [
  resColorsMap.black,   // black   ->  0
  resColorsMap.brown,   // brown   ->  1
  resColorsMap.red,     // red     ->  2
  resColorsMap.orange,  // orange  ->  3
  resColorsMap.yellow,  // yellow  ->  4
  resColorsMap.green,   // green   ->  5
  resColorsMap.blue,    // blue    ->  6
  resColorsMap.purple,  // purple  ->  7
  resColorsMap.gray,    // gray    ->  8
  resColorsMap.white,   // white   ->  9
];

// == multiplier coloring scheme == */
var resMultColorsMap = {
         0.01: resColorsMap.silver, // silver  ->  0
         0.1:  resColorsMap.gold,   // gold    ->  1
         1:    resColorsMap.black,  // black   ->  2
        10:    resColorsMap.brown,  // brown   ->  3
       100:    resColorsMap.red,    // red     ->  4
      1000:    resColorsMap.orange, // orange  ->  5
     10000:    resColorsMap.yellow, // yellow  ->  6
    100000:    resColorsMap.green,  // green   ->  7
   1000000:    resColorsMap.blue,   // blue    ->  8
  10000000:    resColorsMap.purple, // purple  ->  9
};

// == tolerance coloring scheme == */
var resTol4bandsColorsMap = {
   0.05: resColorsMap.gray,   // gray   ->  0
   0.1:  resColorsMap.purple, // purple ->  1
   0.25: resColorsMap.blue,   // blue   ->  2
   0.5:  resColorsMap.green,  // green  ->  3
   1:    resColorsMap.brown,  // brown  ->  4
   2:    resColorsMap.red,    // red    ->  5
   5:    resColorsMap.gold,   // gold   ->  6
  10:    resColorsMap.silver, // silver ->  7
}

// helper - loop over the "units & 10's pows map" & see if we have a matching unit
var applyExp2 = function(theValue, theUnity){
  if( theUnity !== ''){
    for( var i=0; i<= exps2.length; i++){
      if (exps2[i][0] === theUnity) {
        return theValue * exps2[i][1];
        break;
      }
    }
  }
  return theValue;
}

// helper - get units & value from resistor values passed as trings ( may or not contain the ending "Ohm" symbol and/or n,µ,.. )
var getUnityIdx = function(valueStr){
  var valueStrArr = valueStr.split('');
  for( var i=0; i<= valueStrArr.length; i++){
    if (isNaN(parseInt(valueStrArr[i])) && valueStrArr[i] !== '.' ) { // to handle stuff like '2.3k'
      idx = i;
      return idx;
      break;
    }
  }
}

// helper - convert some value, not necesseraly a Resistor, to stuff ( including a Resistor )
var convert = function (resValOrStr, unit, type){
  // check whether we're passed a str or a value
  var value;
  if( ! isNaN(resValOrStr) ){
    if( typeof resValOrStr === "string" ) value = Number(resValOrStr);
    else value = resValOrStr;
  } else {
    var unity = resValOrStr.substr( getUnityIdx(resValOrStr) );
    if (unity.substr(-1) === "Ω" ) unity = unity.substr(0, unity.length-1);
    if( unity !== '') value = applyExp2( Number( resValOrStr.substr(0, getUnityIdx(resValOrStr) ) ), unity);
    else value = Number( resValOrStr.substr(0, getUnityIdx(resValOrStr) ) );
  }

  // clean & check what is the desired output unit, & convert value
  if (unit.substr(-1) === "Ω" ) unit = unit.substr(0, unit.length-1);
  var outVal = applyExp2( value, unit);

  // check what we have to return
  if( !typeof type === 'undefined' ){
    if( type === 'str') outVal += '';
    else if( type === 'unit') outVal += unit;
    else if( type === 'unity') outVal += unit + 'Ω';
    else if( type === 'resistor') outVal = Resistor(outVal);
  }

  return outVal;
}

// == Prototype of Resistor ==
function ResistorProto(resVal, resStr){
  this.resValue = resVal;
  this.resString = resStr;
}

// == Fcns shared by all the ResistorProto instances ==
// tests fcn
ResistorProto.prototype.sayHello = function(){ console.log('Hello there: ' + this.resValue) }

// generate fcns to display the value of a resistor with a different unit
exps2.forEach(function(mapItem){
  ResistorProto.prototype['_in' + mapItem[0]] = function(type){
    var outVal = applyExp2( this.resValue, mapItem[0]);

    // check what we have to return
    if( typeof type !== 'undefined' ){
      if( type === 'str') outVal += '';
      else if( type === 'unit') outVal += mapItem[0];
      else if( type === 'unity') outVal += mapItem[0] + 'Ω';
    }

    return outVal;
  };
})

// generate the bands for a Resistor ( 4 bands & 5bands )
ResistorProto.prototype.generateBands = function(bands){
  // TODO: handle values above 1 only for the moment ( aka no m,µ,n by now)
  if(this.value < 1){
    console.log('m,µ,n not handled by now ! ')
  } else {
    //console.log('res value is above 1 Ohm: ' + this.resValue)

    // ====
    var colorCodesArr = [];

    if( this.resValue < 10){ // if we only have one digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - one digit')
        colorCodesArr.push ( this.resValue ); // value in 1st, to apply to convention
        colorCodesArr.push ( 0 );             // added 0, same as above
        colorCodesArr.push ( 0.1 );           // adjusted multiplier to comply with the above(s) - 4 band version
        colorCodesArr.push ( '±' );           // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - one digit')
        colorCodesArr.push ( this.resValue ); // value in 1st, to apply to convention
        colorCodesArr.push ( 0 );             // added 0, same as above
        colorCodesArr.push ( 0 );             // added 0, same as above
        colorCodesArr.push ( 0.01 );           // adjusted multiplier to comply with the above(s) - 5 band version
        colorCodesArr.push ( '±' );           // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    else if( this.resValue < 100){ // if we have two digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - two digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( 1 );                     // adjusted multiplier - 4 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - two digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( 0 );                     // added 0, to apply to convention
        colorCodesArr.push ( 0.1 );                   // adjusted multiplier to comply with the above(s) - 5 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    else if( this.resValue < 1000){ // if we have three digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - three digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( 10 );                     // adjusted multiplier ( third digit is discarded ) - 4 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - three digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( Number( (''+this.resValue)[2] ) ); // 3rd digit
        colorCodesArr.push ( 1 );                     // adjusted multiplier - 5 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    else { // if we have more than three digit
      // == 4 bands ==
      if( bands === 4 ){
        //console.log('4bands - more than three digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) );                                         // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) );                                         // 2nd digit
        colorCodesArr.push ( Number( '1' + Array( (''+this.resValue).substr(2).length+1 ).join('0') ) ) // adjusted multiplier - 4 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }
      // == 5 bands ==
      else {
        //console.log('5bands - more than digit')
        colorCodesArr.push ( Number( (''+this.resValue)[0] ) ); // 1st digit
        colorCodesArr.push ( Number( (''+this.resValue)[1] ) ); // 2nd digit
        colorCodesArr.push ( Number( (''+this.resValue)[2] ) ); // 3rd digit
        colorCodesArr.push ( Number( '1' + Array( (''+this.resValue).substr(3).length+1 ).join('0') ) ) // adjusted multiplier - 5 band version
        colorCodesArr.push ( '±' );                   // dummy placeholder for tolerance
        return colorCodesArr;
      }

    }

    // ====
  }
}

// utility - display the array of bands as colored inline array whatever the number of items
ResistorProto.prototype.logBands = function(bands){
  var bandsArr = this.generateBands(bands);
  var color_green = '\x1b[32m', color_yellow = '\x1b[33m', color_def = '\x1b[0m';
  var logStr = '[ ';
  for(var i=0; i < bandsArr.length; i++){
    !isNaN(bandsArr[i]) ? logStr += color_yellow + bandsArr[i] : logStr += color_green + "'" + bandsArr[i] + "'";
    logStr += color_def;
    i < bandsArr.length-1 ? logStr += ', ' : '';
  }
  logStr += ' ]'
  console.log(logStr)
}

//  == Resistor class ( public ) ==
//function Resistor(resVal, resStr){ return new ResistorProto(resVal, resStr) }
function Resistor(resistorValue){
  if( ! isNaN(resistorValue) ){ // decimal
    if( typeof resistorValue === "string" ) this.resValue = Number(resistorValue); // if num passed as str
    else this.resValue = resistorValue;
    this.resStr = resistorValue + 'Ω';
  } else { // string
    // get string stuff until first char: if it's Ohm, strip it, else if maj/min supported char, deduce value
    var unity = resistorValue.substr( getUnityIdx(resistorValue) ); // get the unit part
    if (unity.substr(-1) === "Ω" ) unity = unity.substr(0, unity.length-1); // clean up
    // get actual value
    if( unity !== '') this.resValue = applyExp2( Number( resistorValue.substr(0, getUnityIdx(resistorValue) ) ), unity);
    else this.resValue = Number( resistorValue.substr(0, getUnityIdx(resistorValue) ) );
    this.resStr = resistorValue + 'Ω';
  }

  return new ResistorProto(this.resValue, this.resStr)
}

// == NodeJS module exports ==
module.exports = Resistor;

/*
// usage: instanciate a Resistor
var def = Resistor(400, '400')

// == NodeJS usage ==
var Resistor = require('./Resistor_nodeModule.js')
var def = Resistor(400, '400')
*/
<|endoftext|>


<commit_before>// Not yet ported. Feel like it?
<commit_msg>Update preg_match_all.js<commit_after>function preg_match_all(pattern, s, flag, offset) {
  //  discuss at:
  //  original by: Camille Hodoul (http://webdev-snippets.net)
  //        note: The pattern must be a RegExp object.
  //        note: The function returns the matches array, instead of using a reference.
  //        note: Flag combination isn't supported yet.
  //        note: Dependency: strncmp.js
  //  example 1: var str = 'X-MyHeader: MyValue; X-AZE: adqdsdfff;USERAGENT: Chrome123123 é';
  //  example 1: var ptr = / *([a-zA-Z0-9\-]+) *: *([^;]*)/gm;
  //  example 1: jsPregMatchAll(ptr,str);
  //  returns 1: [
  //  returns 1:  ['X-MyHeader: MyValue',' X-AZE: adqdsdfff','USERAGENT: Chrome123123 é'],
  //  returns 1:  ['X-MyHeader','X-AZE','USERAGENT'],
  //  returns 1:  ['MyValue','adqdsdfff','Chrome123123 é']]

  // UNFINISHED this is a work in progress.
  // It's using Javascript's regex engine, which is different from PHP's PCRE.

  var order = flag || 'PREG_PATTERN_ORDER';
  // TODO support flag combination
  var matches = [];
  var nbP = find_parens_sub(pattern.source);

  if(typeof (offset) !== 'undefined' && offset > 0) {
    // try to reproduce the behavior of the offset parameter, but I'm not sure how to test it.
    // I have to rebuild a pattern.
    var ps = pattern.toString();
    var delimiter = ps.charAt(0);

    // FIXME : If the user has escaped his delimiter in the pattern, I should unescape it before passing it to the RegExp constructor.
    // but this should be done after the .join() ofc

    var t = ps.split(delimiter);
    t.shift();
    var flags = t.pop();
    t[0] = '.{' + offset + '}' + t[0];
    ps = t.join(delimiter);
    pattern = new RegExp(ps, flags); // Have to rebuild it at runtime so no literal...
  }

  //	 If the flag is 2 or 3, I should init the matches array with n+1 arrays
  //    Where n = nb of capturing parentheses

  if(order == 'PREG_PATTERN_ORDER' || order == 'PREG_OFFSET_CAPTURE') {
    for(var i = 0; i < 1 + nbP; i++) {
      matches[i] = [];
    }
  }

  s.replace(pattern, function () {
    var args = [].slice.call(arguments);
    // Remove unnecessary elements from the args array
    var fullMatch = args.pop();
    var offset = args.pop();
    var substr = args[0];
    // args now only contains the matches
    if(order === 'PREG_SET_ORDER') {
      matches.push(args);
    } else if(order === 'PREG_PATTERN_ORDER') {
      var l = args.length;
      matches[0].push(substr);
      for(var i = 1; i < l; i++) {
        if(!matches[(i)]) matches[(i)] = [];
        matches[(i)].push(args[i]);
      }
    } else if(order === 'PREG_OFFSET_CAPTURE') {
      if(!matches[0]) matches[0] = [];
      matches[0].push([args[0], offset]);
      var l = args.length;
      for(var i = 1; i < l; i++) {
        if(!matches[i]) matches[i] = [];
        matches[i].push([args[i], fullMatch.indexOf(args[i])]);
      }
    }
  });
  return matches;
}

//  I copied this function from http://www.opensource.apple.com/source/pcre/pcre-4.2/pcre/pcre_compile.c ,
//  but removed the parts I don't need, so it isn't an exact implementation. It should do the trick though.

function find_parens_sub(ptr, count) {
  var count = count || 0;
  var start_count = count;
  var hwm_count = start_count;
  var i = 0;
  var dup_parens = false;
  // If the first character is a parenthesis, check on the type of group we are
  // dealing with. The very first call may not start with a parenthesis.
  if(ptr[0] == '(') {
    if(ptr[1] == '?' && ptr[2] == '|') {
      i += 3;
      dup_parens = true;
    }

    // Handle a normal, unnamed capturing parenthesis
    else if(ptr[1] != '?' && ptr[1] != '*') {
      count += 1;
      i++;
    }
    // Handle a condition. If it is an assertion, just carry on so that it
	//	  is processed as normal. If not, skip to the closing parenthesis of the
	//	  condition (there can't be any nested parens. */
    else if(ptr[i + 2] == '(') {
      i += 2;
      if(ptr[i + 1] != '(') {
        while(!!ptr[i] && ptr[i] != ')') i++;
        if(ptr[i] != 0) i++;
      }
    }
    // We have either (? or (* and not a condition
    else {
      i += 2;
      if(ptr[i] == 'P') i++;

      // We have to disambiguate (?<! and (?<= from (?<name> for named groups
      if((ptr[i] == '<' && ptr[i + 1] != '!' && ptr[i + 1] != '=') || ptr[i] == '\'') {
        count++;
      }
    }
  }

  // Past any initial parenthesis handling, scan for parentheses or vertical
  //	bars.
  for(; !!ptr[i]; i++) {
    // Skip over backslashed characters and also entire \Q...\E
    if(ptr[i] == '\\') {
      if(!ptr[++i]) throw new Error('Weird backslash ?');
      if(ptr[i] == 'Q') {
        for(;;) {
          while(!!ptr[++i] && ptr[i] != '\\') {};
          if(!ptr[i]) throw new Error('No \\E ?');
          if(ptr[++i] == 'E') break;
        }
	  }
      continue;
    }
    //  Skip over character classes; this logic must be similar to the way they
	//  are handled for real. If the first character is '^', skip it. Also, if the
	//  first few characters (either before or after ^) are \Q\E or \E we skip them
	//  too.
    if(ptr[i] == '[') {
      var negate_class = false;
      for(;;) {
        var c = ptr[++i];
        if(c == '\\') {
          if(ptr[i] == 'E') i++;
          else if(!strncmp(ptr[i + 1]), 'Q\\E', 3) {
            i += 3;
          } else {
            break;
          }
        } else if(!negate_class && c == '^') {
          negate_class = true;
        } else break;
      }

      //  If the next character is ']', it is a data character that must be
	  //  skipped, except in JavaScript compatibility mode
      if(ptr[i] == ']' && false) {
        i++;
      }
      while(ptr[++i] != ']') {
        if(!ptr[i]) {
          return count;
        }
        if(ptr[i] == '\\') {
          if(!ptr[++i]) throw new Error('Weird backslash ?');
          if(ptr[i] == 'Q') {
            for(;;) {
              while(!!ptr[++i] && ptr[i] != '\\') {};
              if(!ptr[i]) throw new Error('No \\E ?');
              if(ptr[++i] == 'E') break;
            }
		  }
          continue;
        }
      }
      continue;
    }

    // Check for the special metacharacters
    if(ptr[i] == '(') {

      count = find_parens_sub(ptr.slice(i), count);
      return count;
    } else if(ptr[i] == ')') {
      if(dup_parens && count < hwm_count) count = hwm_count;
    } else if(ptr[i] == '|' && dup_parens) {
      if(count > hwm_count) hwm_count = count;
      count = start_count;
    }
  }
  return count;
}
<|endoftext|>


<commit_before>
gridWidth = grid[0].length;
gridHeight = grid.length;

canvasWidth = 1000; //window.innerWidth;
canvasHeight = 650; //(window.innerHeight / 100) * 80;

players = [];
velocity = [2,2];

startX = 0;
startY = 0;

$(document).ready(function() {

  // Super shiny header
  var interval;
  $("header").mouseover(function() {
    interval = setInterval(function() {
      $("h1").css({ color: getRandomColor() });
    }, 100);
  });
  $("header").mouseout(function() {
    clearInterval(interval);
    $("h1").css({ color: "rgb(80,80,80)" });
  });

  conn = new WebSocket('ws://109.109.137.94:8080');
  conn.onopen = function(e) {
    console.log("Connection established!");
  };

  conn.onmessage = function(e) {
    console.log(e.data);
    splitData = e.data.split(" ");
    if (splitData[0] === "move") {
      movePlayer(parseInt(splitData[1]), parseInt(splitData[2]), parseInt(splitData[3]));
    } else if (splitData[0] === "add") {
      addPlayer();
    }
  };

  conn.onclose = function(e) {
    console.log("Connection closed!");
  };

  stage = new Kinetic.Stage({
    container: "game-container",
    width: canvasWidth,
    height: canvasHeight
  });
  layer = new Kinetic.Layer();

  mazeBlockWidth = Math.round(canvasWidth / gridWidth);
  mazeBlockHeight = Math.round(canvasHeight / gridHeight);

  buildMaze();

  // Add the layer to the stage
  stage.add(layer);

  // Add test players
  addPlayer();

  // setTimeout(function() {
  //   whatIsWallWhatisNot();
  // }, 1000);

});

function buildMaze() {
  for (var i = 0; i < grid.length; i++) {
    for (var j = 0; j < grid[i].length; j++) {
      buildMazeBlock(i,j);
    };
  };
}

function buildMazeBlock(i,j) {
  var blockFill = ""
  if (grid[j][i] === " ") {
     return;
  } else if (grid[j][i] === "#") {
    blockFill = "rgb(100,100,100)";
  } else if (grid[j][i] === "s") {
    startX = i;
    startY = j;
    return;
  }

  var block = new Kinetic.Rect({
    x: i * mazeBlockWidth,
    y: j * mazeBlockHeight,
    width: mazeBlockWidth,
    height: mazeBlockHeight,
    fill: blockFill
  });

  if (grid[j][i] === "e") {
    console.log(j,i);
    setInterval(function() {
      block.setFill(getRandomColor());
      layer.draw();
    },100);
  }

  layer.add(block);
  layer.draw();
}

function addPlayer() {
  var newPlayer = new Kinetic.Rect({
    x: startX * mazeBlockWidth,
    y: startY * mazeBlockHeight,
    width: mazeBlockWidth,
    height: mazeBlockHeight,
    fill: getRandomColor()
  });

  players.push(newPlayer);

  stackPlayers(startX,startY);

  // add the shape to the layer
  layer.add(newPlayer);

  layer.draw();
}

function movePlayer(playerIndex, i, j) {
  console.log(players[playerIndex]);

  var tween = new Kinetic.Tween({
    node: players[playerIndex],
    duration: 1,
    x: i * mazeBlockWidth,
    y: j * mazeBlockHeight,
    opacity: 1,
    onFinish: function() {
      stackedPlayers(i,j);
    }
  });

  tween.play();
}

function stackPlayers(i,j) {
  var stackedPlayers = [];
  var positionX = i * mazeBlockWidth;
  var positionY = j * mazeBlockHeight;
  for (var i = 0; i < players.length; i++) {
    if (players[i].getPosition().x === positionX
    &&  players[i].getPosition().y === positionY) {
      stackedPlayers.push(players[i])
    }
  }

  var stackRows = Math.ceil(stackedPlayers.length / 2);
  for (var i = 0; i < stackedPlayers.length; i++) {
    var row = Math.floor(i / 2);
    var column = i % 2;
    // Adjust x and y

    // Adjust width and height

  }

}

function whatIsWallWhatisNot() {
  $(".kineticjs-content").css({ background: "rgb(100,100,100)" });
  setTimeout(function() {
    $(".kineticjs-content").css({ background: "rgb(220,220,220)" });
  },2000);
}

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
        color += letters[Math.round(Math.random() * 15)];
    }
    return color;
}<commit_msg>initial full stacked player algo<commit_after>
gridWidth = grid[0].length;
gridHeight = grid.length;

canvasWidth = 1000; //window.innerWidth;
canvasHeight = 650; //(window.innerHeight / 100) * 80;

players = [];
velocity = [2,2];

startX = 0;
startY = 0;

$(document).ready(function() {

  // Super shiny header
  var interval;
  $("header").mouseover(function() {
    interval = setInterval(function() {
      $("h1").css({ color: getRandomColor() });
    }, 100);
  });
  $("header").mouseout(function() {
    clearInterval(interval);
    $("h1").css({ color: "rgb(80,80,80)" });
  });

  conn = new WebSocket('ws://109.109.137.94:8080');
  grid = conn.send( {"operation":"GAME","type":"NEW","recipient":"server","message":"newgame","sender":"steph","id":388542958} );

  conn.onopen = function(e) {
    console.log("Connection established!");
  };

  conn.onclose = function(e) {
    console.log("Connection closed!");
  };

  conn.onmessage = function(e) {
    console.log(e.data);
    splitData = e.data.split(" ");
    if (splitData[0] === "move") {
      movePlayer(parseInt(splitData[1]), parseInt(splitData[2]), parseInt(splitData[3]));
    } else if (splitData[0] === "add") {
      addPlayer();
    } else if (false/* Get grid data */) {
      stage = new Kinetic.Stage({
        container: "game-container",
        width: canvasWidth,
        height: canvasHeight
      });
      layer = new Kinetic.Layer();

      mazeBlockWidth = Math.round(canvasWidth / gridWidth);
      mazeBlockHeight = Math.round(canvasHeight / gridHeight);

      buildMaze();

      // Add the layer to the stage
      stage.add(layer);

      // Add test players
      addPlayer();
      addPlayer();
      addPlayer();
      addPlayer();
      addPlayer();
    }
  };

});

function buildMaze() {
  for (var i = 0; i < grid.length; i++) {
    for (var j = 0; j < grid[i].length; j++) {
      buildMazeBlock(i,j);
    };
  };
}

function buildMazeBlock(i,j) {
  var blockFill = ""
  if (grid[j][i] === " ") {
     return;
  } else if (grid[j][i] === "#") {
    blockFill = "rgb(100,100,100)";
  } else if (grid[j][i] === "s") {
    startX = i;
    startY = j;
    return;
  }

  var block = new Kinetic.Rect({
    x: i * mazeBlockWidth,
    y: j * mazeBlockHeight,
    width: mazeBlockWidth,
    height: mazeBlockHeight,
    fill: blockFill
  });

  if (grid[j][i] === "e") {
    console.log(j,i);
    setInterval(function() {
      block.setFill(getRandomColor());
      layer.draw();
    },100);
  }

  layer.add(block);
  layer.draw();
}

function addPlayer() {
  var newPlayer = new Kinetic.Rect({
    x: startX * mazeBlockWidth,
    y: startY * mazeBlockHeight,
    width: mazeBlockWidth,
    height: mazeBlockHeight,
    fill: getRandomColor()
  });

  players.push(newPlayer);

  stackPlayers(startX,startY);

  // add the shape to the layer
  layer.add(newPlayer);

  layer.draw();
}

function movePlayer(playerIndex, i, j) {
  console.log(players[playerIndex]);

  var tween = new Kinetic.Tween({
    node: players[playerIndex],
    duration: 1,
    x: i * mazeBlockWidth,
    y: j * mazeBlockHeight,
    opacity: 1,
    onFinish: function() {
      stackedPlayers(i,j);
    }
  });

  tween.play();
}

function stackPlayers(i,j) {
  var stackedPlayers = [];
  var positionX = i * mazeBlockWidth;
  var positionY = j * mazeBlockHeight;
  for (var i = 0; i < players.length; i++) {
    if (players[i].getPosition().x === positionX
    &&  players[i].getPosition().y === positionY) {
      stackedPlayers.push(players[i])
    }
  }

  var stackRows = Math.ceil(players.length / 2);
  for (var i = 0; i < players.length; i++) {
    var row = Math.floor(i / 2);
    var column = i % 2;
    // Adjust x and y
    players[i].setPosition(
      players[i].getPosition().x + column * Math.round(mazeBlockWidth / 2),
      players[i].getPosition().y + row * Math.round(mazeBlockHeight / 2)
    );

    // Adjust width and height
    if (players[i].length % 2 == 0 || row != (stackRows - 1)) {
      players[i].setWidth(Math.round(mazeBlockWidth / 2));
    }
    player.setHeight(Math.round(mazeBlockHeight / stackRows));
  }

  layer.draw();

}

function whatIsWallWhatisNot() {
  $(".kineticjs-content").css({ background: "rgb(100,100,100)" });
  setTimeout(function() {
    $(".kineticjs-content").css({ background: "rgb(220,220,220)" });
  },2000);
}

function getRandomColor() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
        color += letters[Math.round(Math.random() * 15)];
    }
    return color;
}<|endoftext|>


<commit_before>const URL = require('url');
const ghGot = require('gh-got');
const delay = require('delay');
const parseLinkHeader = require('parse-link-header');
const hostRules = require('../../util/host-rules');
const { maskToken } = require('../../util/mask');

let cache = {};
let stats = {};

async function get(path, options, retries = 5) {
  const { host } = URL.parse(path);
  const opts = {
    ...hostRules.find({ platform: 'github', host }),
    ...options,
  };
  opts.baseUrl = opts.endpoint;
  delete opts.endpoint;
  const method = opts.method || 'get';
  const useCache = opts.useCache || true;
  if (method.toLowerCase() === 'post' && path === 'graphql') {
    // GitHub Enterprise uses unversioned graphql path
    opts.baseUrl = opts.baseUrl.replace(/\/v3\/?$/, '/');
  }
  if (method === 'get' && useCache && cache[path]) {
    logger.trace({ path }, 'Returning cached result');
    return cache[path];
  }
  logger.trace(`${method.toUpperCase()} ${path}`);
  stats.requests = (stats.requests || []).concat([
    method.toUpperCase() + ' ' + path,
  ]);
  try {
    if (global.appMode) {
      const appAccept = 'application/vnd.github.machine-man-preview+json';
      opts.headers = Object.assign(
        {},
        {
          accept: appAccept,
          'user-agent':
            process.env.RENOVATE_USER_AGENT ||
            'https://github.com/renovatebot/renovate',
        },
        opts.headers
      );
      if (opts.headers.accept !== appAccept) {
        opts.headers.accept = `${appAccept}, ${opts.headers.accept}`;
      }
    }
    const res = await ghGot(path, opts);
    if (res && res.headers) {
      stats.rateLimit = res.headers['x-ratelimit-limit'];
      stats.rateLimitRemaining = res.headers['x-ratelimit-remaining'];
    }
    if (opts.paginate) {
      // Check if result is paginated
      const pageLimit = opts.pageLimit || 10;
      const linkHeader = parseLinkHeader(res.headers.link);
      if (linkHeader && linkHeader.next && linkHeader.last) {
        let lastPage = +linkHeader.last.page;
        if (!process.env.RENOVATE_PAGINATE_ALL && opts.paginate !== 'all') {
          lastPage = Math.min(pageLimit, lastPage);
        }
        const pageNumbers = Array.from(
          new Array(lastPage),
          (x, i) => i + 1
        ).slice(1);
        const pages = await Promise.all(
          pageNumbers.map(page => {
            const url = URL.parse(linkHeader.next.url, true);
            delete url.search;
            url.query.page = page;
            return get(URL.format(url), { ...opts, paginate: false }, retries);
          })
        );
        res.body = res.body.concat(
          ...pages.filter(Boolean).map(page => page.body)
        );
      }
    }
    if (
      method === 'get' &&
      (path.startsWith('repos/') ||
        path.startsWith('https://api.github.com/repos/'))
    ) {
      cache[path] = res;
    }
    // istanbul ignore if
    if (method === 'POST' && path === 'graphql') {
      const goodResult = '{"data":{';
      if (res.body.startsWith(goodResult)) {
        if (retries === 0) {
          logger.info('Recovered graphql query');
        }
      } else if (retries > 0) {
        logger.info('Retrying graphql query');
        opts.body = opts.body.replace('first: 100', 'first: 25');
        return get(path, opts, 0);
      }
    }
    return res;
  } catch (err) {
    if (
      err.name === 'RequestError' &&
      (err.code === 'ENOTFOUND' || err.code === 'ETIMEDOUT')
    ) {
      throw new Error('platform-failure');
    }
    if (err.name === 'ParseError') {
      throw new Error('platform-failure');
    }
    if (err.statusCode >= 500 && err.statusCode < 600) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(5000 / retries);

        return get(path, opts, retries - 1);
      }
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('You have triggered an abuse detection mechanism')
    ) {
      if (retries > 0) {
        logger.info(
          {
            headers: err.headers,
            path,
            statusCode: err.statusCode,
            message: err.message,
          },
          `Retrying request`
        );

        await delay(180000 / (retries * retries));

        return get(path, opts, 0);
      }
      // istanbul ignore next
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('rate limit exceeded')
    ) {
      logger.info({ err, headers: err.headers }, 'Rate limit exceeded');
      throw new Error('rate-limit-exceeded');
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('blobs up to 1 MB in size')
    ) {
      throw err;
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('Resource not accessible by integration')
    ) {
      throw new Error('integration-unauthorized');
    } else if (err.statusCode === 403) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(60000 / (retries * retries));

        return get(path, opts, retries - 1);
      }
    } else if (
      err.statusCode === 401 &&
      err.message &&
      err.message.includes('Bad credentials')
    ) {
      const rateLimit = err.headers ? err.headers['x-ratelimit-limit'] : -1;
      logger.info(
        {
          token: maskToken(opts.token),
          err,
        },
        'Bad credentials'
      );
      if (rateLimit === '60') {
        throw new Error('platform-failure');
      }
      throw new Error('bad-credentials');
    }
    throw err;
  }
}

const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];

for (const x of helpers) {
  get[x] = (url, opts) =>
    get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}

get.setAppMode = function setAppMode() {
  // no-op
};

get.reset = function reset() {
  cache = null;
  cache = {};
  // istanbul ignore if
  if (stats.requests && stats.requests.length > 1) {
    logger.info(
      {
        rateLimit: parseInt(stats.rateLimit, 10),
        requestCount: stats.requests.length,
        rateLimitRemaining: parseInt(stats.rateLimitRemaining, 10),
      },
      'Request stats'
    );
    stats.requests.sort();
    logger.debug({ requests: stats.requests }, 'All requests');
    stats = {};
  }
};

module.exports = get;
<commit_msg>fix(github): throw if GitHub Pro limitation<commit_after>const URL = require('url');
const ghGot = require('gh-got');
const delay = require('delay');
const parseLinkHeader = require('parse-link-header');
const hostRules = require('../../util/host-rules');
const { maskToken } = require('../../util/mask');

let cache = {};
let stats = {};

async function get(path, options, retries = 5) {
  const { host } = URL.parse(path);
  const opts = {
    ...hostRules.find({ platform: 'github', host }),
    ...options,
  };
  opts.baseUrl = opts.endpoint;
  delete opts.endpoint;
  const method = opts.method || 'get';
  const useCache = opts.useCache || true;
  if (method.toLowerCase() === 'post' && path === 'graphql') {
    // GitHub Enterprise uses unversioned graphql path
    opts.baseUrl = opts.baseUrl.replace(/\/v3\/?$/, '/');
  }
  if (method === 'get' && useCache && cache[path]) {
    logger.trace({ path }, 'Returning cached result');
    return cache[path];
  }
  logger.trace(`${method.toUpperCase()} ${path}`);
  stats.requests = (stats.requests || []).concat([
    method.toUpperCase() + ' ' + path,
  ]);
  try {
    if (global.appMode) {
      const appAccept = 'application/vnd.github.machine-man-preview+json';
      opts.headers = Object.assign(
        {},
        {
          accept: appAccept,
          'user-agent':
            process.env.RENOVATE_USER_AGENT ||
            'https://github.com/renovatebot/renovate',
        },
        opts.headers
      );
      if (opts.headers.accept !== appAccept) {
        opts.headers.accept = `${appAccept}, ${opts.headers.accept}`;
      }
    }
    const res = await ghGot(path, opts);
    if (res && res.headers) {
      stats.rateLimit = res.headers['x-ratelimit-limit'];
      stats.rateLimitRemaining = res.headers['x-ratelimit-remaining'];
    }
    if (opts.paginate) {
      // Check if result is paginated
      const pageLimit = opts.pageLimit || 10;
      const linkHeader = parseLinkHeader(res.headers.link);
      if (linkHeader && linkHeader.next && linkHeader.last) {
        let lastPage = +linkHeader.last.page;
        if (!process.env.RENOVATE_PAGINATE_ALL && opts.paginate !== 'all') {
          lastPage = Math.min(pageLimit, lastPage);
        }
        const pageNumbers = Array.from(
          new Array(lastPage),
          (x, i) => i + 1
        ).slice(1);
        const pages = await Promise.all(
          pageNumbers.map(page => {
            const url = URL.parse(linkHeader.next.url, true);
            delete url.search;
            url.query.page = page;
            return get(URL.format(url), { ...opts, paginate: false }, retries);
          })
        );
        res.body = res.body.concat(
          ...pages.filter(Boolean).map(page => page.body)
        );
      }
    }
    if (
      method === 'get' &&
      (path.startsWith('repos/') ||
        path.startsWith('https://api.github.com/repos/'))
    ) {
      cache[path] = res;
    }
    // istanbul ignore if
    if (method === 'POST' && path === 'graphql') {
      const goodResult = '{"data":{';
      if (res.body.startsWith(goodResult)) {
        if (retries === 0) {
          logger.info('Recovered graphql query');
        }
      } else if (retries > 0) {
        logger.info('Retrying graphql query');
        opts.body = opts.body.replace('first: 100', 'first: 25');
        return get(path, opts, 0);
      }
    }
    return res;
  } catch (err) {
    if (
      err.name === 'RequestError' &&
      (err.code === 'ENOTFOUND' || err.code === 'ETIMEDOUT')
    ) {
      throw new Error('platform-failure');
    }
    if (err.name === 'ParseError') {
      throw new Error('platform-failure');
    }
    if (err.statusCode >= 500 && err.statusCode < 600) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(5000 / retries);

        return get(path, opts, retries - 1);
      }
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('You have triggered an abuse detection mechanism')
    ) {
      if (retries > 0) {
        logger.info(
          {
            headers: err.headers,
            path,
            statusCode: err.statusCode,
            message: err.message,
          },
          `Retrying request`
        );

        await delay(180000 / (retries * retries));

        return get(path, opts, 0);
      }
      // istanbul ignore next
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith(
        'Upgrade to GitHub Pro or make this repository public to enable this feature'
      )
    ) {
      // istanbul ignore next
      throw err;
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('rate limit exceeded')
    ) {
      logger.info({ err, headers: err.headers }, 'Rate limit exceeded');
      throw new Error('rate-limit-exceeded');
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('blobs up to 1 MB in size')
    ) {
      throw err;
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('Resource not accessible by integration')
    ) {
      throw new Error('integration-unauthorized');
    } else if (err.statusCode === 403) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(60000 / (retries * retries));

        return get(path, opts, retries - 1);
      }
    } else if (
      err.statusCode === 401 &&
      err.message &&
      err.message.includes('Bad credentials')
    ) {
      const rateLimit = err.headers ? err.headers['x-ratelimit-limit'] : -1;
      logger.info(
        {
          token: maskToken(opts.token),
          err,
        },
        'Bad credentials'
      );
      if (rateLimit === '60') {
        throw new Error('platform-failure');
      }
      throw new Error('bad-credentials');
    }
    throw err;
  }
}

const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];

for (const x of helpers) {
  get[x] = (url, opts) =>
    get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}

get.setAppMode = function setAppMode() {
  // no-op
};

get.reset = function reset() {
  cache = null;
  cache = {};
  // istanbul ignore if
  if (stats.requests && stats.requests.length > 1) {
    logger.info(
      {
        rateLimit: parseInt(stats.rateLimit, 10),
        requestCount: stats.requests.length,
        rateLimitRemaining: parseInt(stats.rateLimitRemaining, 10),
      },
      'Request stats'
    );
    stats.requests.sort();
    logger.debug({ requests: stats.requests }, 'All requests');
    stats = {};
  }
};

module.exports = get;
<|endoftext|>


<commit_before>describe('Preparation list controller', function() {
    'use strict';

    var createController, scope;
    var allPreparations = [
        {
            'id': 'ab136cbf0923a7f11bea713adb74ecf919e05cfa',
            'dataSetId': 'ddb74c89-6d23-4528-9f37-7a9860bb468e',
            'author': 'anonymousUser',
            'creationDate': 1427447300300,
            'steps': [
                '35890aabcf9115e4309d4ce93367bf5e4e77b82a',
                '4ff5d9a6ca2e75ebe3579740a4297fbdb9b7894f',
                '8a1c49d1b64270482e8db8232357c6815615b7cf',
                '599725f0e1331d5f8aae24f22cd1ec768b10348d'
            ],
            'actions': [
                {
                    'action': 'lowercase',
                    'parameters': {
                        'column_name': 'birth'
                    }
                },
                {
                    'action': 'uppercase',
                    'parameters': {
                        'column_name': 'country'
                    }
                },
                {
                    'action': 'cut',
                    'parameters': {
                        'pattern': '.',
                        'column_name': 'first_item'
                    }
                }
            ]
        },
        {
            'id': 'fbaa18e82e913e97e5f0e9d40f04413412be1126',
            'dataSetId': '4d0a2718-bec6-4614-ad6c-8b3b326ff6c7',
            'author': 'anonymousUser',
            'creationDate': 1427447330693,
            'steps': [
                '47e2444dd1301120b539804507fd307072294048',
                'ae1aebf4b3fa9b983c895486612c02c766305410',
                '24dcd68f2117b9f93662cb58cc31bf36d6e2867a',
                '599725f0e1331d5f8aae24f22cd1ec768b10348d'
            ],
            'actions': [
                {
                    'action': 'cut',
                    'parameters': {
                        'pattern': '-',
                        'column_name': 'birth'
                    }
                },
                {
                    'action': 'fillemptywithdefault',
                    'parameters': {
                        'default_value': 'N/A',
                        'column_name': 'state'
                    }
                },
                {
                    'action': 'uppercase',
                    'parameters': {
                        'column_name': 'lastname'
                    }
                }
            ]
        }
    ];

    beforeEach(module('data-prep.preparation-list'));

    beforeEach(inject(function($q, $rootScope, $controller, PreparationService, PlaygroundService, DatasetListService) {
        scope = $rootScope.$new();

        createController = function() {
            var ctrl =  $controller('PreparationListCtrl', {
                $scope: scope
            });
            return ctrl;
        };

        spyOn(DatasetListService, 'getDatasetsPromise').and.returnValue($q.when([]));
        spyOn(PreparationService, 'getPreparations').and.returnValue($q.when({data: allPreparations}));
        spyOn(PlaygroundService, 'load').and.returnValue($q.when(true));
        spyOn(PlaygroundService, 'show').and.callThrough();
    }));

    it('should init preparations', inject(function() {
        //given

        //when
        var ctrl = createController();
        scope.$digest();

        //then
        expect(ctrl.preparations).toBe(allPreparations);
    }));

    it('should load preparation and show playground', inject(function(PlaygroundService) {
        //given
        var ctrl = createController();
        var preparation = {
            id: 'de618c62ef97b3a95b5c171bc077ffe22e1d6f79',
            dataSetId: 'dacd45cf-5bd0-4768-a9b7-f6c199581efc',
            author: 'anonymousUser',
            creationDate: 1427460984585,
            steps: [
                '228c16230de53de5992eb44c7aba362ac714ab1c'
            ],
            actions: []
        };

        //when
        ctrl.load(preparation);
        scope.$digest();

        //then
        expect(PlaygroundService.load).toHaveBeenCalledWith(preparation);
        expect(PlaygroundService.show).toHaveBeenCalled();
    }));
});
<commit_msg>TDP-72 : add unit tests<commit_after>describe('Preparation list controller', function() {
    'use strict';

    var createController, scope;
    var allPreparations = [
        {
            'id': 'ab136cbf0923a7f11bea713adb74ecf919e05cfa',
            'dataSetId': 'ddb74c89-6d23-4528-9f37-7a9860bb468e',
            'author': 'anonymousUser',
            'creationDate': 1427447300300,
            'steps': [
                '35890aabcf9115e4309d4ce93367bf5e4e77b82a',
                '4ff5d9a6ca2e75ebe3579740a4297fbdb9b7894f',
                '8a1c49d1b64270482e8db8232357c6815615b7cf',
                '599725f0e1331d5f8aae24f22cd1ec768b10348d'
            ],
            'actions': [
                {
                    'action': 'lowercase',
                    'parameters': {
                        'column_name': 'birth'
                    }
                },
                {
                    'action': 'uppercase',
                    'parameters': {
                        'column_name': 'country'
                    }
                },
                {
                    'action': 'cut',
                    'parameters': {
                        'pattern': '.',
                        'column_name': 'first_item'
                    }
                }
            ]
        },
        {
            'id': 'fbaa18e82e913e97e5f0e9d40f04413412be1126',
            'dataSetId': '4d0a2718-bec6-4614-ad6c-8b3b326ff6c7',
            'author': 'anonymousUser',
            'creationDate': 1427447330693,
            'steps': [
                '47e2444dd1301120b539804507fd307072294048',
                'ae1aebf4b3fa9b983c895486612c02c766305410',
                '24dcd68f2117b9f93662cb58cc31bf36d6e2867a',
                '599725f0e1331d5f8aae24f22cd1ec768b10348d'
            ],
            'actions': [
                {
                    'action': 'cut',
                    'parameters': {
                        'pattern': '-',
                        'column_name': 'birth'
                    }
                },
                {
                    'action': 'fillemptywithdefault',
                    'parameters': {
                        'default_value': 'N/A',
                        'column_name': 'state'
                    }
                },
                {
                    'action': 'uppercase',
                    'parameters': {
                        'column_name': 'lastname'
                    }
                }
            ]
        }
    ];

    beforeEach(module('data-prep.preparation-list'));

    beforeEach(inject(function($q, $rootScope, $controller, PreparationService, PlaygroundService, DatasetListService) {
        scope = $rootScope.$new();

        createController = function() {
            var ctrl =  $controller('PreparationListCtrl', {
                $scope: scope
            });
            return ctrl;
        };

        spyOn(DatasetListService, 'getDatasetsPromise').and.returnValue($q.when([]));
        spyOn(PreparationService, 'getPreparations').and.returnValue($q.when({data: allPreparations}));
        spyOn(PlaygroundService, 'load').and.returnValue($q.when(true));
        spyOn(PlaygroundService, 'show').and.callThrough();
    }));

    afterEach(inject(function($stateParams) {
        $stateParams.prepid = null;
    }));

    it('should init preparations', inject(function() {
        //given

        //when
        var ctrl = createController();
        scope.$digest();

        //then
        expect(ctrl.preparations).toBe(allPreparations);
    }));

    it('should load preparation on creation if requested in url', inject(function($stateParams, PlaygroundService) {
        //given
        $stateParams.prepid = 'fbaa18e82e913e97e5f0e9d40f04413412be1126';

        //when
        createController();
        scope.$digest();

        //then
        expect(PlaygroundService.load).toHaveBeenCalledWith(allPreparations[1]);
        expect(PlaygroundService.show).toHaveBeenCalled();
    }));

    it('should not load preparation on creation if requested preparation is not in preparation list', inject(function($stateParams, PlaygroundService) {
        //given
        $stateParams.prepid = 'azerty';

        //when
        createController();
        scope.$digest();

        //then
        expect(PlaygroundService.load).not.toHaveBeenCalled();
        expect(PlaygroundService.show).not.toHaveBeenCalled();
    }));

    it('should load preparation and show playground', inject(function(PlaygroundService) {
        //given
        var ctrl = createController();
        var preparation = {
            id: 'de618c62ef97b3a95b5c171bc077ffe22e1d6f79',
            dataSetId: 'dacd45cf-5bd0-4768-a9b7-f6c199581efc',
            author: 'anonymousUser',
            creationDate: 1427460984585,
            steps: [
                '228c16230de53de5992eb44c7aba362ac714ab1c'
            ],
            actions: []
        };
        expect(PlaygroundService.load).not.toHaveBeenCalled();

        //when
        ctrl.load(preparation);
        scope.$digest();

        //then
        expect(PlaygroundService.load).toHaveBeenCalledWith(preparation);
        expect(PlaygroundService.show).toHaveBeenCalled();
    }));
});
<|endoftext|>