function addEventKeys(props, data) {
  const hasEventKeyAccessor = !!props.eventKey;
  const eventKeyAccessor = getEventKey(props.eventKey);
  return data.map((datum) => {
    if (datum.eventKey !== undefined) {
      return datum;
    } else if (hasEventKeyAccessor) {
      const eventKey = eventKeyAccessor(datum);
      return eventKey !== undefined ? assign({ eventKey }, datum) : datum;
    } else {
      return datum;
    }
  });
}

function addEventKeys ( props , data ) { const hasEventKeyAccessor = ! ! props . eventKey ; const eventKeyAccessor = getEventKey ( props . eventKey ) ; return data . map ( ( datum ) => { if ( datum . eventKey !== undefined ) { return datum ; } else if ( hasEventKeyAccessor ) { const eventKey = eventKeyAccessor ( datum ) ; return eventKey !== undefined ? assign ( { eventKey } , datum ) : datum ; } else { return datum ; } } ) ; }

Returns data with an eventKey prop added to each datum


function createStringMap(props, axis) {
  const stringsFromAxes = getStringsFromAxes(props, axis);
  const stringsFromCategories = getStringsFromCategories(props, axis);
  const stringsFromData = getStringsFromData(props, axis);

  const allStrings = uniq([...stringsFromAxes, ...stringsFromCategories, ...stringsFromData]);
  return allStrings.length === 0
    ? null
    : allStrings.reduce((memo, string, index) => {
        memo[string] = index + 1;
        return memo;
      }, {});
}

function createStringMap ( props , axis ) { const stringsFromAxes = getStringsFromAxes ( props , axis ) ; const stringsFromCategories = getStringsFromCategories ( props , axis ) ; const stringsFromData = getStringsFromData ( props , axis ) ; const allStrings = uniq ( [ ... stringsFromAxes , ... stringsFromCategories , ... stringsFromData ] ) ; return allStrings . length === 0 ? null : allStrings . reduce ( ( memo , string , index ) => { memo [ string ] = index + 1 ; return memo ; } , { } ) ; }

Exported Functions
Returns an object mapping string data to numeric data
@param {Object} props: the props object
@param {String} axis: the current axis
@returns {Object} an object mapping string data to numeric data


function downsample(data, maxPoints, startingIndex = 0) {
  // ensures that the downampling of data while zooming looks good.
  const dataLength = getLength(data);
  if (dataLength > maxPoints) {
    // limit k to powers of 2, e.g. 64, 128, 256
    // so that the same points will be chosen reliably, reducing flicker on zoom
    const k = Math.pow(2, Math.ceil(Math.log2(dataLength / maxPoints)));
    return data.filter(
      // ensure modulo is always calculated from same reference: i + startingIndex
      (d, i) => (i + startingIndex) % k === 0
    );
  }
  return data;
}

Reduces the size of a data array, such that it is <= maxPoints.
@param {Array} data: an array of data; must be sorted
@param {Number} maxPoints: maximum number of data points to return
@param {Number} startingIndex: the index of the data[0] *in the entire dataset*; this function
assumes `data` param is a subset of larger dataset that has been zoommed
@returns {Array} an array of data, a subset of data param

Reduces the size of a data array such that it is < = maxPoints .


function formatData(dataset, props, expectedKeys) {
  const isArrayOrIterable = Array.isArray(dataset) || Immutable.isIterable(dataset);
  if (!isArrayOrIterable || getLength(dataset) < 1) {
    return [];
  }

  const defaultKeys = ["x", "y", "y0"];
  expectedKeys = Array.isArray(expectedKeys) ? expectedKeys : defaultKeys;

  const stringMap = {
    x: expectedKeys.indexOf("x") !== -1 ? createStringMap(props, "x") : undefined,
    y: expectedKeys.indexOf("y") !== -1 ? createStringMap(props, "y") : undefined,
    y0: expectedKeys.indexOf("y0") !== -1 ? createStringMap(props, "y") : undefined
  };

  const createAccessor = (name) => {
    return Helpers.createAccessor(props[name] !== undefined ? props[name] : name);
  };

  const accessor = expectedKeys.reduce((memo, type) => {
    memo[type] = createAccessor(type);
    return memo;
  }, {});

  const preformattedData =
    isEqual(expectedKeys, defaultKeys) &&
    props.x === "_x" &&
    props.y === "_y" &&
    props.y0 === "_y0";

  const data = preformattedData
    ? dataset
    : dataset.reduce((dataArr, datum, index) => {
        // eslint-disable-line complexity
        datum = parseDatum(datum);
        const fallbackValues = { x: index, y: datum };
        const processedValues = expectedKeys.reduce((memo, type) => {
          const processedValue = accessor[type](datum);
          const value = processedValue !== undefined ? processedValue : fallbackValues[type];
          if (value !== undefined) {
            if (typeof value === "string" && stringMap[type]) {
              memo[`${type}Name`] = value;
              memo[`_${type}`] = stringMap[type][value];
            } else {
              memo[`_${type}`] = value;
            }
          }
          return memo;
        }, {});

        const formattedDatum = assign({}, processedValues, datum);
        if (!isEmpty(formattedDatum)) {
          dataArr.push(formattedDatum);
        }

        return dataArr;
      }, []);

  const sortedData = sortData(data, props.sortKey, props.sortOrder);
  const cleanedData = cleanData(sortedData, props);
  return addEventKeys(props, cleanedData);
}

function
formatData
(
dataset
,
props
,
expectedKeys
)
{
const
isArrayOrIterable
=
Array
.
isArray
(
dataset
)
||
Immutable
.
isIterable
(
dataset
)
;
if
(
!
isArrayOrIterable
||
getLength
(
dataset
)
<
1
)
{
return
[
]
;
}
const
defaultKeys
=
[
"x"
,
"y"
,
"y0"
]
;
expectedKeys
=
Array
.
isArray
(
expectedKeys
)
expectedKeys
:
defaultKeys
;
const
stringMap
=
{
x
:
expectedKeys
.
indexOf
(
"x"
)
!==
1
createStringMap
(
props
,
"x"
)
:
undefined
,
y
:
expectedKeys
.
indexOf
(
"y"
)
!==
1
createStringMap
(
props
,
"y"
)
:
undefined
,
y0
:
expectedKeys
.
indexOf
(
"y0"
)
!==
1
createStringMap
(
props
,
"y"
)
:
undefined
}
;
const
createAccessor
=
(
name
)
=>
{
return
Helpers
.
createAccessor
(
props
[
name
]
!==
undefined
props
[
name
]
:
name
)
;
}
;
const
accessor
=
expectedKeys
.
reduce
(
(
memo
,
type
)
=>
{
memo
[
type
]
=
createAccessor
(
type
)
;
return
memo
;
}
,
{
}
)
;
const
preformattedData
=
isEqual
(
expectedKeys
,
defaultKeys
)
&&
props
.
x
===
"_x"
&&
props
.
y
===
"_y"
&&
props
.
y0
===
"_y0"
;
const
data
=
preformattedData
dataset
:
dataset
.
reduce
(
(
dataArr
,
datum
,
index
)
=>
{
// eslint-disable-line complexity
datum
=
parseDatum
(
datum
)
;
const
fallbackValues
=
{
x
:
index
,
y
:
datum
}
;
const
processedValues
=
expectedKeys
.
reduce
(
(
memo
,
type
)
=>
{
const
processedValue
=
accessor
[
type
]
(
datum
)
;
const
value
=
processedValue
!==
undefined
processedValue
:
fallbackValues
[
type
]
;
if
(
value
!==
undefined
)
{
if
(
typeof
value
===
"string"
&&
stringMap
[
type
]
)
{
memo
[
`
${
type
}
`
]
=
value
;
memo
[
`
${
type
}
`
]
=
stringMap
[
type
]
[
value
]
;
}
else
{
memo
[
`
${
type
}
`
]
=
value
;
}
}
return
memo
;
}
,
{
}
)
;
const
formattedDatum
=
assign
(
{
}
,
processedValues
,
datum
)
;
if
(
!
isEmpty
(
formattedDatum
)
)
{
dataArr
.
push
(
formattedDatum
)
;
}
return
dataArr
;
}
,
[
]
)
;
const
sortedData
=
sortData
(
data
,
props
.
sortKey
,
props
.
sortOrder
)
;
const
cleanedData
=
cleanData
(
sortedData
,
props
)
;
return
addEventKeys
(
props
,
cleanedData
)
;
}

Returns formatted data. Data accessors are applied, and string values are replaced.
@param {Array} dataset: the original domain
@param {Object} props: the props object
@param {Array} expectedKeys: an array of expected data keys
@returns {Array} the formatted data

Returns formatted data . Data accessors are applied and string values are replaced .


function generateData(props) {
  const xValues = generateDataArray(props, "x");
  const yValues = generateDataArray(props, "y");
  const values = xValues.map((x, i) => {
    return { x, y: yValues[i] };
  });
  return values;
}

function generateData ( props ) { const xValues = generateDataArray ( props , "x" ) ; const yValues = generateDataArray ( props , "y" ) ; const values = xValues . map ( ( x , i ) => { return { x , y : yValues [ i ] } ; } ) ; return values ; }

Returns generated x and y data based on domain and sample from props
@param {Object} props: the props object
@returns {Array} an array of data


function getCategories(props, axis) {
  return props.categories && !Array.isArray(props.categories)
    ? props.categories[axis]
    : props.categories;
}

function getCategories ( props , axis ) { return props . categories && ! Array . isArray ( props . categories ) ? props . categories [ axis ] : props . categories ; }

Returns an array of categories for a given axis
@param {Object} props: the props object
@param {String} axis: the current axis
@returns {Array} an array of categories


function getData(props) {
  return props.data ? formatData(props.data, props) : formatData(generateData(props), props);
}

function getData ( props ) { return props . data ? formatData ( props . data , props ) : formatData ( generateData ( props ) , props ) ; }

Returns an array of formatted data
@param {Object} props: the props object
@returns {Array} an array of data


function getStringsFromAxes(props, axis) {
  const { tickValues, tickFormat } = props;
  let tickValueArray;
  if (!tickValues || (!Array.isArray(tickValues) && !tickValues[axis])) {
    tickValueArray = tickFormat && Array.isArray(tickFormat) ? tickFormat : [];
  } else {
    tickValueArray = tickValues[axis] || tickValues;
  }
  return tickValueArray.filter((val) => typeof val === "string");
}

function getStringsFromAxes ( props , axis ) { const { tickValues , tickFormat } = props ; let tickValueArray ; if ( ! tickValues || ( ! Array . isArray ( tickValues ) && ! tickValues [ axis ] ) ) { tickValueArray = tickFormat && Array . isArray ( tickFormat ) ? tickFormat : [ ] ; } else { tickValueArray = tickValues [ axis ] || tickValues ; } return tickValueArray . filter ( ( val ) => typeof val === "string" ) ; }

Returns an array of strings from axis tickValues for a given axis
@param {Object} props: the props object
@param {String} axis: the current axis
@returns {Array} an array of strings


function getStringsFromCategories(props, axis) {
  if (!props.categories) {
    return [];
  }
  const categories = getCategories(props, axis);
  const categoryStrings = categories && categories.filter((val) => typeof val === "string");
  return categoryStrings ? Collection.removeUndefined(categoryStrings) : [];
}

function getStringsFromCategories ( props , axis ) { if ( ! props . categories ) { return [ ] ; } const categories = getCategories ( props , axis ) ; const categoryStrings = categories && categories . filter ( ( val ) => typeof val === "string" ) ; return categoryStrings ? Collection . removeUndefined ( categoryStrings ) : [ ] ; }

Returns an array of strings from categories for a given axis
@param {Object} props: the props object
@param {String} axis: the current axis
@returns {Array} an array of strings


function getStringsFromData(props, axis) {
  const isArrayOrIterable = Array.isArray(props.data) || Immutable.isIterable(props.data);
  if (!isArrayOrIterable) {
    return [];
  }

  const key = props[axis] === undefined ? axis : props[axis];
  const accessor = Helpers.createAccessor(key);

  // support immutable data
  const data = props.data.reduce((memo, d) => {
    memo.push(parseDatum(d));
    return memo;
  }, []);

  const sortedData = sortData(data, props.sortKey, props.sortOrder);
  const dataStrings = sortedData
    .reduce((dataArr, datum) => {
      datum = parseDatum(datum);
      dataArr.push(accessor(datum));
      return dataArr;
    }, [])
    .filter((datum) => typeof datum === "string");

  // return a unique set of strings
  return dataStrings.reduce((prev, curr) => {
    if (curr !== undefined && curr !== null && prev.indexOf(curr) === -1) {
      prev.push(curr);
    }
    return prev;
  }, []);
}

function
getStringsFromData
(
props
,
axis
)
{
const
isArrayOrIterable
=
Array
.
isArray
(
props
.
data
)
||
Immutable
.
isIterable
(
props
.
data
)
;
if
(
!
isArrayOrIterable
)
{
return
[
]
;
}
const
key
=
props
[
axis
]
===
undefined
axis
:
props
[
axis
]
;
const
accessor
=
Helpers
.
createAccessor
(
key
)
;
// support immutable data
const
data
=
props
.
data
.
reduce
(
(
memo
,
d
)
=>
{
memo
.
push
(
parseDatum
(
d
)
)
;
return
memo
;
}
,
[
]
)
;
const
sortedData
=
sortData
(
data
,
props
.
sortKey
,
props
.
sortOrder
)
;
const
dataStrings
=
sortedData
.
reduce
(
(
dataArr
,
datum
)
=>
{
datum
=
parseDatum
(
datum
)
;
dataArr
.
push
(
accessor
(
datum
)
)
;
return
dataArr
;
}
,
[
]
)
.
filter
(
(
datum
)
=>
typeof
datum
===
"string"
)
;
// return a unique set of strings
return
dataStrings
.
reduce
(
(
prev
,
curr
)
=>
{
if
(
curr
!==
undefined
&&
curr
!==
&&
prev
.
indexOf
(
curr
)
===
1
)
{
prev
.
push
(
curr
)
;
}
return
prev
;
}
,
[
]
)
;
}

Returns an array of strings from data
@param {Object} props: the props object
@param {String} axis: the current axis
@returns {Array} an array of strings


function findAxisComponents(childComponents, predicate) {
  predicate = predicate || identity;
  const findAxes = (children) => {
    return children.reduce((memo, child) => {
      if (child.type && child.type.role === "axis" && predicate(child)) {
        return memo.concat(child);
      } else if (child.props && child.props.children) {
        return memo.concat(findAxes(React.Children.toArray(child.props.children)));
      }
      return memo;
    }, []);
  };

  return findAxes(childComponents);
}

function findAxisComponents ( childComponents , predicate ) { predicate = predicate || identity ; const findAxes = ( children ) => { return children . reduce ( ( memo , child ) => { if ( child . type && child . type . role === "axis" && predicate ( child ) ) { return memo . concat ( child ) ; } else if ( child . props && child . props . children ) { return memo . concat ( findAxes ( React . Children . toArray ( child . props . children ) ) ) ; } return memo ; } , [ ] ) ; } ; return findAxes ( childComponents ) ; }

Returns all axis components that pass a given predicate
@param {Array} childComponents: an array of children
@param {Function} predicate: a predicate function that will be called with each
@returns {Array} all axis components that pass the given predicate or []


function getDomainFromData(props, axis) {
  const { polar, startAngle = 0, endAngle = 360 } = props;
  const tickValues = getTickArray(props);
  if (!Array.isArray(tickValues)) {
    return undefined;
  }
  const minDomain = Domain.getMinFromProps(props, axis);
  const maxDomain = Domain.getMaxFromProps(props, axis);
  const tickStrings = stringTicks(props);
  const ticks = tickValues.map((value) => +value);
  const defaultMin = tickStrings ? 1 : Collection.getMinValue(ticks);
  const defaultMax = tickStrings ? tickValues.length : Collection.getMaxValue(ticks);
  const min = minDomain !== undefined ? minDomain : defaultMin;
  const max = maxDomain !== undefined ? maxDomain : defaultMax;
  const initialDomain = Domain.getDomainFromMinMax(min, max);
  const domain =
    polar && axis === "x" && Math.abs(startAngle - endAngle) === 360
      ? Domain.getSymmetricDomain(initialDomain, ticks)
      : initialDomain;
  if (isVertical(props) && !polar) {
    domain.reverse();
  }
  return domain;
}

function getDomainFromData ( props , axis ) { const { polar , startAngle = 0 , endAngle = 360 } = props ; const tickValues = getTickArray ( props ) ; if ( ! Array . isArray ( tickValues ) ) { return undefined ; } const minDomain = Domain . getMinFromProps ( props , axis ) ; const maxDomain = Domain . getMaxFromProps ( props , axis ) ; const tickStrings = stringTicks ( props ) ; const ticks = tickValues . map ( ( value ) => + value ) ; const defaultMin = tickStrings ? 1 : Collection . getMinValue ( ticks ) ; const defaultMax = tickStrings ? tickValues . length : Collection . getMaxValue ( ticks ) ; const min = minDomain !== undefined ? minDomain : defaultMin ; const max = maxDomain !== undefined ? maxDomain : defaultMax ; const initialDomain = Domain . getDomainFromMinMax ( min , max ) ; const domain = polar && axis === "x" && Math . abs ( startAngle - endAngle ) === 360 ? Domain . getSymmetricDomain ( initialDomain , ticks ) : initialDomain ; if ( isVertical ( props ) && ! polar ) { domain . reverse ( ) ; } return domain ; }

Returns a domain based tickValues
@param {Object} props: the props object
@param {String} axis: either x or y
@returns {Array} returns a domain from tickValues
 eslint-disable-next-line max-statements


function getDomain(props, axis) {
  const inherentAxis = getAxis(props);
  if (axis && axis !== inherentAxis) {
    return undefined;
  }
  return Domain.createDomainFunction(getDomainFromData)(props, inherentAxis);
}

function getDomain ( props , axis ) { const inherentAxis = getAxis ( props ) ; if ( axis && axis !== inherentAxis ) { return undefined ; } return Domain . createDomainFunction ( getDomainFromData ) ( props , inherentAxis ) ; }


function fillData(props, datasets) {
  const { fillInMissingData } = props;
  const xMap = datasets.reduce((prev, dataset) => {
    dataset.forEach((datum) => {
      prev[datum._x instanceof Date ? datum._x.getTime() : datum._x] = true;
    });
    return prev;
  }, {});
  const xKeys = keys(xMap).map((k) => +k);
  const xArr = orderBy(xKeys);

  return datasets.map((dataset) => {
    let indexOffset = 0;
    const isDate = dataset[0] && dataset[0]._x instanceof Date;
    const filledInData = xArr.map((x, index) => {
      x = +x;
      const datum = dataset[index - indexOffset];

      if (datum) {
        const x1 = isDate ? datum._x.getTime() : datum._x;
        if (x1 === x) {
          return datum;
        } else {
          indexOffset++;
          const y = fillInMissingData ? 0 : null;
          x = isDate ? new Date(x) : x;
          return { x, y, _x: x, _y: y };
        }
      } else {
        const y = fillInMissingData ? 0 : null;
        x = isDate ? new Date(x) : x;
        return { x, y, _x: x, _y: y };
      }
    });

    return filledInData;
  });
}

function fillData ( props , datasets ) { const { fillInMissingData } = props ; const xMap = datasets . reduce ( ( prev , dataset ) => { dataset . forEach ( ( datum ) => { prev [ datum . _x instanceof Date ? datum . _x . getTime ( ) : datum . _x ] = true ; } ) ; return prev ; } , { } ) ; const xKeys = keys ( xMap ) . map ( ( k ) => + k ) ; const xArr = orderBy ( xKeys ) ; return datasets . map ( ( dataset ) => { let indexOffset = 0 ; const isDate = dataset [ 0 ] && dataset [ 0 ] . _x instanceof Date ; const filledInData = xArr . map ( ( x , index ) => { x = + x ; const datum = dataset [ index - indexOffset ] ; if ( datum ) { const x1 = isDate ? datum . _x . getTime ( ) : datum . _x ; if ( x1 === x ) { return datum ; } else { indexOffset ++ ; const y = fillInMissingData ? 0 : null ; x = isDate ? new Date ( x ) : x ; return { x , y , _x : x , _y : y } ; } } else { const y = fillInMissingData ? 0 : null ; x = isDate ? new Date ( x ) : x ; return { x , y , _x : x , _y : y } ; } } ) ; return filledInData ; } ) ; }

Assumes data in `datasets` is sorted by `Data.getData`.

Assumes data in datasets is sorted by Data . getData .


function updateState() {
  history.replaceState(
    {
      left_top: split_left.scrollTop,
      right_top: split_right.scrollTop
    },
    document.title
  );
}

function updateState ( ) { history . replaceState ( { left_top : split_left . scrollTop , right_top : split_right . scrollTop } , document . title ) ; }

Chrome doesn't remember scroll position properly so do it ourselves. Also works on Firefox and Edge.

Chrome doesn t remember scroll position properly so do it ourselves . Also works on Firefox and Edge .


function _applyRemainingDefaultOptions(opts) {
      opts.icon = opts.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like  '#', '¶', '❡', or '§'.
      opts.visible = opts.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' & 'touch'
      opts.placement = opts.hasOwnProperty('placement')
        ? opts.placement
        : 'right'; // Also accepts 'left'
      opts.class = opts.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
      // Using Math.floor here will ensure the value is Number-cast and an integer.
      opts.truncate = opts.hasOwnProperty('truncate')
        ? Math.floor(opts.truncate)
        : 64; // Accepts any value that can be typecast to a number.
    }

Assigns options to the internal options object, and provides defaults.
@param {Object} opts - Options object

Assigns options to the internal options object and provides defaults .


function _addBaselineStyles() {
      // We don't want to add global baseline styles if they've been added before.
      if (document.head.querySelector('style.anchorjs') !== null) {
        return;
      }

      var style = document.createElement('style'),
        linkRule =
          ' .anchorjs-link {' +
          '   opacity: 0;' +
          '   text-decoration: none;' +
          '   -webkit-font-smoothing: antialiased;' +
          '   -moz-osx-font-smoothing: grayscale;' +
          ' }',
        hoverRule =
          ' *:hover > .anchorjs-link,' +
          ' .anchorjs-link:focus  {' +
          '   opacity: 1;' +
          ' }',
        anchorjsLinkFontFace =
          ' @font-face {' +
          '   font-family: "anchorjs-icons";' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
          '   src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype");' +
          ' }',
        pseudoElContent =
          ' [data-anchorjs-icon]::after {' +
          '   content: attr(data-anchorjs-icon);' +
          ' }',
        firstStyleEl;

      style.className = 'anchorjs';
      style.appendChild(document.createTextNode('')); // Necessary for Webkit.

      // We place it in the head with the other style tags, if possible, so as to
      // not look out of place. We insert before the others so these styles can be
      // overridden if necessary.
      firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
      if (firstStyleEl === undefined) {
        document.head.appendChild(style);
      } else {
        document.head.insertBefore(style, firstStyleEl);
      }

      style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
      style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
      style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
      style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
    }

'   -webkit-font-smoothing: antialiased;'

'   -moz-osx-font-smoothing: grayscale;'

_addBaselineStyles
Adds baseline styles to the page, used by all AnchorJS links irregardless of configuration.

_addBaselineStyles Adds baseline styles to the page used by all AnchorJS links irregardless of configuration .


function getClaimValue(entity, prop) {
    if (!entity.claims) return;
    if (!entity.claims[prop]) return;

    let value, c;
    for (let i = 0; i < entity.claims[prop].length; i++) {
        c = entity.claims[prop][i];
        if (c.rank === 'deprecated') continue;
        if (c.mainsnak.snaktype !== 'value') continue;

        value = c.mainsnak.datavalue.value;
        if (c.rank === 'preferred') return value;  // return immediately
    }
    return value;
}

function
getClaimValue
(
entity
,
prop
)
{
if
(
!
entity
.
claims
)
return
;
if
(
!
entity
.
claims
[
prop
]
)
return
;
let
value
,
c
;
for
(
let
i
=
0
;
i
<
entity
.
claims
[
prop
]
.
length
;
i
++
)
{
c
=
entity
.
claims
[
prop
]
[
i
]
;
if
(
c
.
rank
===
'deprecated'
)
continue
;
if
(
c
.
mainsnak
.
snaktype
!==
'value'
)
continue
;
value
=
c
.
mainsnak
.
datavalue
.
value
;
if
(
c
.
rank
===
'preferred'
)
return
value
;
// return immediately
}
return
value
;
}

Get the claim value, considering any claim rank.. - disregard any claims with "deprecated" rank - accept immediately any claim with "preferred" rank - return the latest claim with "normal" rank

Get the claim value considering any claim rank .. - disregard any claims with deprecated rank - accept immediately any claim with preferred rank - return the latest claim with normal rank


function checkWikipedia(brands) {
    Object.keys(brands).forEach(k => {
        ['brand:wikipedia', 'operator:wikipedia'].forEach(t => {
            let wp = brands[k].tags[t];
            if (wp && !/^[a-z_]{2,}:[^_]*$/.test(wp)) {
                _wrongFormat.push([k, wp, t]);
            }
        });
    });
}

function checkWikipedia ( brands ) { Object . keys ( brands ) . forEach ( k => { [ 'brand:wikipedia' , 'operator:wikipedia' ] . forEach ( t => { let wp = brands [ k ] . tags [ t ] ; if ( wp && ! / ^[a-z_]{2,}:[^_]*$ / . test ( wp ) ) { _wrongFormat . push ( [ k , wp , t ] ) ; } } ) ; } ) ; }

Additionally check for wrong formatted Wikipedia values


function buildReverseIndex(obj) {
    let warnCollisions = [];

    for (let k in obj) {
        checkAmbiguous(k);

        if (obj[k].match) {
            for (let i = obj[k].match.length - 1; i >= 0; i--) {
                let match = obj[k].match[i];
                checkAmbiguous(match);

                if (rIndex[match]) {
                    warnCollisions.push([rIndex[match], match]);
                    warnCollisions.push([k, match]);
                }
                rIndex[match] = k;
            }
        }
    }

    if (warnCollisions.length) {
        console.warn(colors.yellow('\nWarning - match name collisions'));
        console.warn('To resolve these, make sure multiple entries do not contain the same "match" property.');
        warnCollisions.forEach(w => console.warn(
            colors.yellow('  "' + w[0] + '"') + ' -> match? -> ' + colors.yellow('"' + w[1] + '"')
        ));
    }
}

Returns a reverse index to map match keys back to their original keys


function (KEY, exec) {
  var fn = (_core.Object || {})[KEY] || Object[KEY];
  var exp = {};
  exp[KEY] = exec(fn);
  _export(_export.S + _export.F * _fails(function () { fn(1); }), 'Object', exp);
}

function ( KEY , exec ) { var fn = ( _core . Object || { } ) [ KEY ] || Object [ KEY ] ; var exp = { } ; exp [ KEY ] = exec ( fn ) ; _export ( _export . S + _export . F * _fails ( function ( ) { fn ( 1 ) ; } ) , 'Object' , exp ) ; }

most Object methods by ES6 should accept primitives


function (it) {
  if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it);
  return it;
}

function ( it ) { if ( FREEZE && meta . NEED && isExtensible ( it ) && ! _has ( it , META ) ) setMeta ( it ) ; return it ; }

add metadata on freeze-family methods calling

add metadata on freeze - family methods calling


function isObject(obj) {
  // incase of arrow function and array
  return Object(obj) === obj && String(obj) === '[object Object]' && !isFunction(obj) && !isArray(obj);
}

function
isObject
(
obj
)
{
// incase of arrow function and array
return
Object
(
obj
)
===
obj
&&
String
(
obj
)
===
'[object Object]'
&&
!
isFunction
(
obj
)
&&
!
isArray
(
obj
)
;
}


function isNode$2(obj) {
  return !!((typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? obj instanceof Node : obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && typeof obj.nodeType === 'number' && typeof obj.nodeName === 'string');
}

function isNode$2 ( obj ) { return ! ! ( ( typeof Node === 'undefined' ? 'undefined' : _typeof ( Node ) ) === 'object' ? obj instanceof Node : obj && ( typeof obj === 'undefined' ? 'undefined' : _typeof ( obj ) ) === 'object' && typeof obj . nodeType === 'number' && typeof obj . nodeName === 'string' ) ; }


function isElement(obj) {
  return !!((typeof HTMLElement === 'undefined' ? 'undefined' : _typeof(HTMLElement)) === 'object' ? obj instanceof HTMLElement : obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === 'string');
}

function isElement ( obj ) { return ! ! ( ( typeof HTMLElement === 'undefined' ? 'undefined' : _typeof ( HTMLElement ) ) === 'object' ? obj instanceof HTMLElement : obj && ( typeof obj === 'undefined' ? 'undefined' : _typeof ( obj ) ) === 'object' && obj !== null && obj . nodeType === 1 && typeof obj . nodeName === 'string' ) ; }


function isPosterityNode(parent, child) {
  if (!isNode$2(parent) || !isNode$2(child)) {
    return false;
  }
  while (child.parentNode) {
    child = child.parentNode;
    if (child === parent) {
      return true;
    }
  }
  return false;
}

function isPosterityNode ( parent , child ) { if ( ! isNode$2 ( parent ) || ! isNode$2 ( child ) ) { return false ; } while ( child . parentNode ) { child = child . parentNode ; if ( child === parent ) { return true ; } } return false ; }

check if node B is node A's posterrity or not

check if node B is node A s posterrity or not


function genTraversalHandler(fn) {
  var setter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (target, key, value) {
    target[key] = value;
  };

  // use recursive to move what in source to the target
  // if you do not provide a target, we will create a new target
  function recursiveFn(source, target, key) {
    if (isArray(source) || isObject(source)) {
      target = isPrimitive(target) ? isObject(source) ? {} : [] : target;
      for (var _key in source) {
        // $FlowFixMe: support computed key here
        setter(target, _key, recursiveFn(source[_key], target[_key], _key));
        // target[key] = recursiveFn(source[key], target[key], key);
      }
      return target;
    }
    return fn(source, target, key);
  }
  return recursiveFn;
}

the handler to generate an deep traversal handler
@param  {Function} fn the function you wanna run when you reach in the deep property
@return {Function}    the handler


function recursiveFn(source, target, key) {
    if (isArray(source) || isObject(source)) {
      target = isPrimitive(target) ? isObject(source) ? {} : [] : target;
      for (var _key in source) {
        // $FlowFixMe: support computed key here
        setter(target, _key, recursiveFn(source[_key], target[_key], _key));
        // target[key] = recursiveFn(source[key], target[key], key);
      }
      return target;
    }
    return fn(source, target, key);
  }

use recursive to move what in source to the target if you do not provide a target, we will create a new target

use recursive to move what in source to the target if you do not provide a target we will create a new target


function deepAssign() {
  for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
    args[_key2] = arguments[_key2];
  }

  if (args.length < 2) {
    throw new Error('deepAssign accept two and more argument');
  }
  for (var i = args.length - 1; i > -1; i--) {
    if (isPrimitive(args[i])) {
      throw new TypeError('deepAssign only accept non primitive type');
    }
  }
  var target = args.shift();
  args.forEach(function (source) {
    return _deepAssign(source, target);
  });
  return target;
}

merge multiple objects
@param  {...Object} args [description]
@return {merge-object}         [description]


function getDeepProperty(obj, keys) {
  var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
      _ref$throwError = _ref.throwError,
      throwError = _ref$throwError === undefined ? false : _ref$throwError,
      backup = _ref.backup;

  if (isString(keys)) {
    keys = keys.split('.');
  }
  if (!isArray(keys)) {
    throw new TypeError('keys of getDeepProperty must be string or Array<string>');
  }
  var read = [];
  var target = obj;
  for (var i = 0, len = keys.length; i < len; i++) {
    var key = keys[i];
    if (isVoid(target)) {
      if (throwError) {
        throw new Error('obj' + (read.length > 0 ? '.' + read.join('.') : ' itself') + ' is ' + target);
      } else {
        return backup;
      }
    }
    target = target[key];
    read.push(key);
  }
  return target;
}


function transObjectAttrIntoArray(obj) {
  var fn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (a, b) {
    return +a - +b;
  };

  return _Object$keys(obj).sort(fn).reduce(function (order, key) {
    return order.concat(obj[key]);
  }, []);
}

function transObjectAttrIntoArray ( obj ) { var fn = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : function ( a , b ) { return + a - + b ; } ; return _Object$keys ( obj ) . sort ( fn ) . reduce ( function ( order , key ) { return order . concat ( obj [ key ] ) ; } , [ ] ) ; }

sort Object attributes by function
and transfer them into array
@param  {Object} obj Object form from numric
@param  {Function} fn sort function
@return {Array} the sorted attirbutes array


function runRejectableQueue(queue) {
  for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }

  return new _Promise(function (resolve, reject) {
    var step = function step(index) {
      if (index >= queue.length) {
        resolve();
        return;
      }
      var result = isFunction(queue[index]) ? queue[index].apply(queue, _toConsumableArray(args)) : queue[index];
      if (result === false) return reject('stop');
      return _Promise.resolve(result).then(function () {
        return step(index + 1);
      }).catch(function (err) {
        return reject(err || 'stop');
      });
    };
    step(0);
  });
}

function runRejectableQueue ( queue ) { for ( var _len = arguments . length , args = Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) { args [ _key - 1 ] = arguments [ _key ] ; } return new _Promise ( function ( resolve , reject ) { var step = function step ( index ) { if ( index >= queue . length ) { resolve ( ) ; return ; } var result = isFunction ( queue [ index ] ) ? queue [ index ] . apply ( queue , _toConsumableArray ( args ) ) : queue [ index ] ; if ( result === false ) return reject ( 'stop' ) ; return _Promise . resolve ( result ) . then ( function ( ) { return step ( index + 1 ) ; } ) . catch ( function ( err ) { return reject ( err || 'stop' ) ; } ) ; } ; step ( 0 ) ; } ) ; }

run a queue one by one.If include function reject or return false it will stop
@param  {Array} queue the queue which we want to run one by one
@return {Promise}    tell us whether a queue run finished

run a queue one by one . If include function reject or return false it will stop


function runStoppableQueue(queue) {
  for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
    args[_key2 - 1] = arguments[_key2];
  }

  var step = function step(index) {
    if (index >= queue.length) {
      return true;
    }
    var result = isFunction(queue[index]) ? queue[index].apply(queue, _toConsumableArray(args)) : queue[index];
    if (result === false) return false;
    return step(++index);
  };
  return step(0);
}

function runStoppableQueue ( queue ) { for ( var _len2 = arguments . length , args = Array ( _len2 > 1 ? _len2 - 1 : 0 ) , _key2 = 1 ; _key2 < _len2 ; _key2 ++ ) { args [ _key2 - 1 ] = arguments [ _key2 ] ; } var step = function step ( index ) { if ( index >= queue . length ) { return true ; } var result = isFunction ( queue [ index ] ) ? queue [ index ] . apply ( queue , _toConsumableArray ( args ) ) : queue [ index ] ; if ( result === false ) return false ; return step ( ++ index ) ; } ; return step ( 0 ) ; }

run a queue one by one.If include function return false it will stop
@param  {Array} queue the queue which we want to run one by one
@return {boolean} tell the user if the queue run finished

run a queue one by one . If include function return false it will stop


function getLegalBox(_ref) {
  var src = _ref.src,
      box = _ref.box;

  if (isString(box) && box) return box;
  src = src.toLowerCase();
  for (var key in boxSuffixMap) {
    var suffix = boxSuffixMap[key];
    if (src.indexOf(suffix) > -1) return key;
  }
  return 'native';
}

function getLegalBox ( _ref ) { var src = _ref . src , box = _ref . box ; if ( isString ( box ) && box ) return box ; src = src . toLowerCase ( ) ; for ( var key in boxSuffixMap ) { var suffix = boxSuffixMap [ key ] ; if ( src . indexOf ( suffix ) > - 1 ) return key ; } return 'native' ; }

return the config box or choose the right one according to the src


function bind$1(fn, context) {
  if (fn.bind) {
    return fn.bind(context);
  } else if (fn.apply) {
    return function __autobind__() {
      for (var _len2 = arguments.length, args = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) {
        args[_key3] = arguments[_key3];
      }

      return fn.apply(context, args);
    };
  } else {
    return function __autobind__() {
      for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) {
        args[_key4] = arguments[_key4];
      }

      return fn.call.apply(fn, [context].concat(_toConsumableArray(args)));
    };
  }
}

function bind$1 ( fn , context ) { if ( fn . bind ) { return fn . bind ( context ) ; } else if ( fn . apply ) { return function __autobind__ ( ) { for ( var _len2 = arguments . length , args = Array ( _len2 ) , _key3 = 0 ; _key3 < _len2 ; _key3 ++ ) { args [ _key3 ] = arguments [ _key3 ] ; } return fn . apply ( context , args ) ; } ; } else { return function __autobind__ ( ) { for ( var _len3 = arguments . length , args = Array ( _len3 ) , _key4 = 0 ; _key4 < _len3 ; _key4 ++ ) { args [ _key4 ] = arguments [ _key4 ] ; } return fn . call . apply ( fn , [ context ] . concat ( _toConsumableArray ( args ) ) ) ; } ; } }

bind the function with some context. we have some fallback strategy here
@param {function} fn the function which we need to bind the context on
@param {any} context the context object

bind the function with some context . we have some fallback strategy here


function isAccessorDescriptor(desc) {
  return !!desc && (isFunction(desc.get) || isFunction(desc.set)) && isBoolean(desc.configurable) && isBoolean(desc.enumerable) && desc.writable === undefined;
}

function isAccessorDescriptor ( desc ) { return ! ! desc && ( isFunction ( desc . get ) || isFunction ( desc . set ) ) && isBoolean ( desc . configurable ) && isBoolean ( desc . enumerable ) && desc . writable === undefined ; }

to check if the descirptor is an accessor descriptor
@param {descriptor} desc it should be a descriptor better


function isDataDescriptor(desc) {
  return !!desc && desc.hasOwnProperty('value') && isBoolean(desc.configurable) && isBoolean(desc.enumerable) && isBoolean(desc.writable);
}

function isDataDescriptor ( desc ) { return ! ! desc && desc . hasOwnProperty ( 'value' ) && isBoolean ( desc . configurable ) && isBoolean ( desc . enumerable ) && isBoolean ( desc . writable ) ; }

to check if the descirptor is an data descriptor
@param {descriptor} desc it should be a descriptor better


function isInitializerDescriptor(desc) {
  return !!desc && isFunction(desc.initializer) && isBoolean(desc.configurable) && isBoolean(desc.enumerable) && isBoolean(desc.writable);
}

function isInitializerDescriptor ( desc ) { return ! ! desc && isFunction ( desc . initializer ) && isBoolean ( desc . configurable ) && isBoolean ( desc . enumerable ) && isBoolean ( desc . writable ) ; }

to check if the descirptor is an initiallizer descriptor
@param {descriptor} desc it should be a descriptor better


function createDefaultSetter(key) {
  return function set(newValue) {
    _Object$defineProperty(this, key, {
      configurable: true,
      writable: true,
      // IS enumerable when reassigned by the outside word
      enumerable: true,
      value: newValue
    });
    return newValue;
  };
}

set one value on the object
@param {string} key


function compressOneArgFnArray(fns) {
  var errmsg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'You must pass me an array of function';

  if (!isArray(fns) || fns.length < 1) {
    throw new TypeError(errmsg);
  }
  if (fns.length === 1) {
    if (!isFunction(fns[0])) {
      throw new TypeError(errmsg);
    }
    return fns[0];
  }
  return fns.reduce(function (prev, curr) {
    if (!isFunction(curr) || !isFunction(prev)) throw new TypeError(errmsg);
    return function (value) {
      return bind$1(curr, this)(bind$1(prev, this)(value));
    };
  });
}

function
compressOneArgFnArray
(
fns
)
{
var
errmsg
=
arguments
.
length
>
1
&&
arguments
[
1
]
!==
undefined
arguments
[
1
]
:
'You must pass me an array of function'
;
if
(
!
isArray
(
fns
)
||
fns
.
length
<
1
)
{
throw
new
TypeError
(
errmsg
)
;
}
if
(
fns
.
length
===
1
)
{
if
(
!
isFunction
(
fns
[
0
]
)
)
{
throw
new
TypeError
(
errmsg
)
;
}
return
fns
[
0
]
;
}
return
fns
.
reduce
(
function
(
prev
,
curr
)
{
if
(
!
isFunction
(
curr
)
||
!
isFunction
(
prev
)
)
throw
new
TypeError
(
errmsg
)
;
return
function
(
value
)
{
return
bind$1
(
curr
,
this
)
(
bind$1
(
prev
,
this
)
(
value
)
)
;
}
;
}
)
;
}

Compress many function into one function, but this function only accept one arguments;
@param {Array<Function>} fns the array of function we need to compress into one function
@param {string} errmsg When we check that there is something is not function, we will throw an error, you can set your own error message

Compress many function into one function but this function only accept one arguments ;


function getBoundSuper(obj, fn) {
  if (typeof _WeakMap === 'undefined') {
    throw new Error('Using @autobind on ' + fn.name + '() requires WeakMap support due to its use of super.' + fn.name + '()');
  }

  if (!mapStore) {
    mapStore = new _WeakMap();
  }

  if (mapStore.has(obj) === false) {
    mapStore.set(obj, new _WeakMap());
  }

  var superStore = mapStore.get(obj);
  // $FlowFixMe: already insure superStore is not undefined
  if (superStore.has(fn) === false) {
    // $FlowFixMe: already insure superStore is not undefined
    superStore.set(fn, bind$1(fn, obj));
  }
  // $FlowFixMe: already insure superStore is not undefined
  return superStore.get(fn);
}


function autobind(obj, prop, descriptor) {
  if (arguments.length === 1) return autobindClass()(obj);

  var _ref = descriptor || {},
      fn = _ref.value,
      configurable = _ref.configurable;

  if (!isFunction(fn)) {
    throw new TypeError('@autobind can only be used on functions, not "' + fn + '" in ' + (typeof fn === 'undefined' ? 'undefined' : _typeof(fn)) + ' on property "' + prop + '"');
  }
  var constructor = obj.constructor;

  return {
    configurable: configurable,
    enumerable: false,
    get: function get() {
      var _this = this;

      var boundFn = function boundFn() {
        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        return fn.call.apply(fn, [_this].concat(_toConsumableArray(args)));
      };
      // Someone accesses the property directly on the prototype on which it is
      // actually defined on, i.e. Class.prototype.hasOwnProperty(key)
      if (this === obj) {
        return fn;
      }
      // Someone accesses the property directly on a prototype,
      // but it was found up the chain, not defined directly on it
      // i.e. Class.prototype.hasOwnProperty(key) == false && key in Class.prototype
      if (this.constructor !== constructor && _Object$getPrototypeOf(this).constructor === constructor) {
        return fn;
      }

      // Autobound method calling super.sameMethod() which is also autobound and so on.
      if (this.constructor !== constructor && prop in this.constructor.prototype) {
        return getBoundSuper(this, fn);
      }
      _Object$defineProperty(this, prop, {
        configurable: true,
        writable: true,
        // NOT enumerable when it's a bound method
        enumerable: false,
        value: boundFn
      });

      return boundFn;
    },

    set: createDefaultSetter(prop)
  };
}

auto bind the function on the class, just support function
@param {Object} obj Target Object
@param {string} prop prop strong
@param {Object} descriptor

auto bind the function on the class just support function


function set(value) {
          if (value === true) {
            while (waitingQueue.length > 0) {
              waitingQueue[0]();
              waitingQueue.shift();
            }
          }
          return value;
        }

function set ( value ) { if ( value === true ) { while ( waitingQueue . length > 0 ) { waitingQueue [ 0 ] ( ) ; waitingQueue . shift ( ) ; } } return value ; }

create a setter hook here
when it get ture, it will run all function in waiting queue immediately

create a setter hook here when it get ture it will run all function in waiting queue immediately


function attrAndStyleCheck() {
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }

  if (args.length > 2) {
    return ['set'].concat(args);
  }
  if (args.length === 2) {
    if (['video', 'container', 'wrapper', 'videoElement'].indexOf(args[0]) > -1) {
      return ['get'].concat(args);
    }
    return ['set', 'container'].concat(args);
  }
  return ['get', 'container'].concat(args);
}

function attrAndStyleCheck ( ) { for ( var _len = arguments . length , args = Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) { args [ _key ] = arguments [ _key ] ; } if ( args . length > 2 ) { return [ 'set' ] . concat ( args ) ; } if ( args . length === 2 ) { if ( [ 'video' , 'container' , 'wrapper' , 'videoElement' ] . indexOf ( args [ 0 ] ) > - 1 ) { return [ 'get' ] . concat ( args ) ; } return [ 'set' , 'container' ] . concat ( args ) ; } return [ 'get' , 'container' ] . concat ( args ) ; }


function Vessel(dispatcher, target, config) {
  var _this = this;

  _classCallCheck(this, Vessel);

  this.__dispatcher = dispatcher;
  this.__target = target;
  ['width', 'height', 'position', 'display'].forEach(function (key) {
    _Object$defineProperty(_this, key, {
      get: function get() {
        return this.__dispatcher.dom.getStyle(this.__target, key);
      },
      set: function set(value) {
        if (isNumber(value)) {
          value = value + 'px';
        }
        if (!isString(value)) {
          throw new Error('The value of ' + key + ' in ' + this.__target + 'Config must be string, but not ' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + '.');
        }
        this.__dispatcher.dom.setStyle(this.__target, key, value);
        // return value;
      },

      configurable: true,
      enumerable: true
    });
  });
  deepAssign(this, config);
}

function
Vessel
(
dispatcher
,
target
,
config
)
{
var
_this
=
this
;
_classCallCheck
(
this
,
Vessel
)
;
this
.
__dispatcher
=
dispatcher
;
this
.
__target
=
target
;
[
'width'
,
'height'
,
'position'
,
'display'
]
.
forEach
(
function
(
key
)
{
_Object$defineProperty
(
_this
,
key
,
{
get
:
function
get
(
)
{
return
this
.
__dispatcher
.
dom
.
getStyle
(
this
.
__target
,
key
)
;
}
,
set
:
function
set
(
value
)
{
if
(
isNumber
(
value
)
)
{
value
=
value
+
'px'
;
}
if
(
!
isString
(
value
)
)
{
throw
new
Error
(
'The value of '
+
key
+
' in '
+
this
.
__target
+
'Config must be string, but not '
+
(
typeof
value
===
'undefined'
'undefined'
:
_typeof
(
value
)
)
+
'.'
)
;
}
this
.
__dispatcher
.
dom
.
setStyle
(
this
.
__target
,
key
,
value
)
;
// return value;
}
,
configurable
:
true
,
enumerable
:
true
}
)
;
}
)
;
deepAssign
(
this
,
config
)
;
}

base css controller for container and wrapper


function destroy() {
      for (var _key in this.plugins) {
        this.unuse(_key);
      }
      this.binder.destroy();
      delete this.binder;
      this.dom.destroy();
      delete this.dom;
      this.kernel.destroy();
      delete this.kernel;
      delete this.vm;
      delete this.plugins;
      delete this.order;
    }

function destroy ( ) { for ( var _key in this . plugins ) { this . unuse ( _key ) ; } this . binder . destroy ( ) ; delete this . binder ; this . dom . destroy ( ) ; delete this . dom ; this . kernel . destroy ( ) ; delete this . kernel ; delete this . vm ; delete this . plugins ; delete this . order ; }

destroy function called when dispatcher destroyed


function eventBinderCheck(key, fn) {
  if (!chimeeHelper.isString(key)) throw new TypeError('key parameter must be String');
  if (!chimeeHelper.isFunction(fn)) throw new TypeError('fn parameter must be Function');
}

function
eventBinderCheck
(
key
,
fn
)
{
if
(
!
chimeeHelper
.
isString
(
key
)
)
throw
new
TypeError
(
'key parameter must be String'
)
;
if
(
!
chimeeHelper
.
isFunction
(
fn
)
)
throw
new
TypeError
(
'fn parameter must be Function'
)
;
}

checker for on, off, once function
@param {string} key
@param {Function} fn


function oldVideoTimeupdate() {
              var currentTime = _this2.kernel.currentTime;
              if (bias <= 0 && currentTime >= idealTime || bias > 0 && (Math.abs(idealTime - currentTime) <= bias && newVideoReady || currentTime - idealTime > bias)) {
                chimeeHelper.removeEvent(_this2.dom.videoElement, 'timeupdate', oldVideoTimeupdate);
                chimeeHelper.removeEvent(video, 'error', _videoError, true);
                if (!newVideoReady) {
                  chimeeHelper.removeEvent(video, 'canplay', videoCanplay, true);
                  chimeeHelper.removeEvent(video, 'loadedmetadata', videoLoadedmetadata, true);
                  kernel.destroy();
                  return resolve();
                }
                return reject({
                  error: false,
                  video: video,
                  kernel: kernel
                });
              }
            }

function oldVideoTimeupdate ( ) { var currentTime = _this2 . kernel . currentTime ; if ( bias <= 0 && currentTime >= idealTime || bias > 0 && ( Math . abs ( idealTime - currentTime ) <= bias && newVideoReady || currentTime - idealTime > bias ) ) { chimeeHelper . removeEvent ( _this2 . dom . videoElement , 'timeupdate' , oldVideoTimeupdate ) ; chimeeHelper . removeEvent ( video , 'error' , _videoError , true ) ; if ( ! newVideoReady ) { chimeeHelper . removeEvent ( video , 'canplay' , videoCanplay , true ) ; chimeeHelper . removeEvent ( video , 'loadedmetadata' , videoLoadedmetadata , true ) ; kernel . destroy ( ) ; return resolve ( ) ; } return reject ( { error : false , video : video , kernel : kernel } ) ; } }

bind time update on old video when we bump into the switch point and ready we switch


function registerEvents() {
      var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
          name = _ref.name,
          target = _ref.target;

      if (!name || !chimeeHelper.isString(name)) throw new Error('The event name must be a string, but not ' + (typeof name === 'undefined' ? 'undefined' : _typeof(name)));
      if (!target || !chimeeHelper.isString(target)) throw new Error('The event target must be a string, but not ' + (typeof target === 'undefined' ? 'undefined' : _typeof(target)));
      if (target === 'kernel') {
        kernelEvents.push(name);
      }
    }

In some situation, we may have custom events For example, we may have a custom kernel event We can register the event through this method

In some situation we may have custom events For example we may have a custom kernel event We can register the event through this method


function (runState) {
    const [a, b] = runState.stack.popN(2)
    const r = new BN(a.lt(b) ? 1 : 0)
    runState.stack.push(r)
  }

function ( runState ) { const [ a , b ] = runState . stack . popN ( 2 ) const r = new BN ( a . lt ( b ) ? 1 : 0 ) runState . stack . push ( r ) }


function (runState) {
    const [offset, length] = runState.stack.popN(2)
    subMemUsage(runState, offset, length)
    let data = Buffer.alloc(0)
    if (!length.isZero()) {
      data = runState.memory.read(offset.toNumber(), length.toNumber())
    }
    // copy fee
    subGas(runState, new BN(runState._common.param('gasPrices', 'sha3Word')).imul(length.divCeil(new BN(32))))
    const r = new BN(utils.keccak256(data))
    runState.stack.push(r)
  }

function
(
runState
)
{
const
[
offset
,
length
]
=
runState
.
stack
.
popN
(
2
)
subMemUsage
(
runState
,
offset
,
length
)
let
data
=
Buffer
.
alloc
(
0
)
if
(
!
length
.
isZero
(
)
)
{
data
=
runState
.
memory
.
read
(
offset
.
toNumber
(
)
,
length
.
toNumber
(
)
)
}
// copy fee
subGas
(
runState
,
new
BN
(
runState
.
_common
.
param
(
'gasPrices'
,
'sha3Word'
)
)
.
imul
(
length
.
divCeil
(
new
BN
(
32
)
)
)
)
const
r
=
new
BN
(
utils
.
keccak256
(
data
)
)
runState
.
stack
.
push
(
r
)
}


function (runState, cb) {
    const number = runState.stack.pop()
    var blockchain = runState.blockchain
    var diff = new BN(runState.block.header.number).sub(number)

    // block lookups must be within the past 256 blocks
    if (diff.gtn(256) || diff.lten(0)) {
      runState.stack.push(new BN(0))
      cb(null)
      return
    }

    blockchain.getBlock(number, function (err, block) {
      if (err) return cb(err)
      const blockHash = new BN(block.hash())
      runState.stack.push(blockHash)
      cb(null)
    })
  }


function (runState, done) {
    if (runState.static) {
      trap(ERROR.STATIC_STATE_CHANGE)
    }

    const [value, offset, length] = runState.stack.popN(3)

    subMemUsage(runState, offset, length)
    let data = Buffer.alloc(0)
    if (!length.isZero()) {
      data = runState.memory.read(offset.toNumber(), length.toNumber())
    }

    // set up config
    var options = {
      value: value,
      data: data
    }

    var localOpts = {
      inOffset: offset,
      inLength: length,
      outOffset: new BN(0),
      outLength: new BN(0)
    }

    checkCallMemCost(runState, options, localOpts)
    checkOutOfGas(runState, options)
    makeCall(runState, options, localOpts, done)
  }

function
(
runState
,
done
)
{
if
(
runState
.
static
)
{
trap
(
ERROR
.
STATIC_STATE_CHANGE
)
}
const
[
value
,
offset
,
length
]
=
runState
.
stack
.
popN
(
3
)
subMemUsage
(
runState
,
offset
,
length
)
let
data
=
Buffer
.
alloc
(
0
)
if
(
!
length
.
isZero
(
)
)
{
data
=
runState
.
memory
.
read
(
offset
.
toNumber
(
)
,
length
.
toNumber
(
)
)
}
// set up config
var
options
=
{
value
:
value
,
data
:
data
}
var
localOpts
=
{
inOffset
:
offset
,
inLength
:
length
,
outOffset
:
new
BN
(
0
)
,
outLength
:
new
BN
(
0
)
}
checkCallMemCost
(
runState
,
options
,
localOpts
)
checkOutOfGas
(
runState
,
options
)
makeCall
(
runState
,
options
,
localOpts
,
done
)
}


function (runState, cb) {
    let selfdestructToAddress = runState.stack.pop()
    if (runState.static) {
      trap(ERROR.STATIC_STATE_CHANGE)
    }
    var stateManager = runState.stateManager
    var contract = runState.contract
    var contractAddress = runState.address
    selfdestructToAddress = addressToBuffer(selfdestructToAddress)

    stateManager.getAccount(selfdestructToAddress, function (err, toAccount) {
      // update balances
      if (err) {
        cb(err)
        return
      }

      stateManager.accountIsEmpty(selfdestructToAddress, function (error, empty) {
        if (error) {
          cb(error)
          return
        }

        if ((new BN(contract.balance)).gtn(0)) {
          if (empty) {
            try {
              subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount')))
            } catch (e) {
              cb(e.error)
              return
            }
          }
        }

        // only add to refund if this is the first selfdestruct for the address
        if (!runState.selfdestruct[contractAddress.toString('hex')]) {
          runState.gasRefund = runState.gasRefund.addn(runState._common.param('gasPrices', 'selfdestructRefund'))
        }
        runState.selfdestruct[contractAddress.toString('hex')] = selfdestructToAddress
        runState.stopped = true

        var newBalance = new BN(contract.balance).add(new BN(toAccount.balance))
        async.waterfall([
          stateManager.getAccount.bind(stateManager, selfdestructToAddress),
          function (account, cb) {
            account.balance = newBalance
            stateManager.putAccount(selfdestructToAddress, account, cb)
          },
          stateManager.getAccount.bind(stateManager, contractAddress),
          function (account, cb) {
            account.balance = new BN(0)
            stateManager.putAccount(contractAddress, account, cb)
          }
        ], function (err) {
          // The reason for this is to avoid sending an array of results
          cb(err)
        })
      })
    })
  }


function getDataSlice (data, offset, length) {
  let len = new BN(data.length)
  if (offset.gt(len)) {
    offset = len
  }

  let end = offset.add(length)
  if (end.gt(len)) {
    end = len
  }

  data = data.slice(offset.toNumber(), end.toNumber())
  // Right-pad with zeros to fill dataLength bytes
  data = utils.setLengthRight(data, length.toNumber())

  return data
}

Returns an overflow-safe slice of an array. It right-pads
the data with zeros to `length`.
@param {BN} offset
@param {BN} length
@param {Buffer} data

Returns an overflow - safe slice of an array . It right - pads the data with zeros to length .


function checkCallMemCost (runState, callOptions, localOpts) {
  // calculates the gas need for saving the output in memory
  subMemUsage(runState, localOpts.outOffset, localOpts.outLength)

  if (!callOptions.gasLimit) {
    callOptions.gasLimit = new BN(runState.gasLeft)
  }
}

checks to see if we have enough gas left for the memory reads and writes required by the CALLs


function (next) {
    genesisBlock.header = new BlockHeader(
                            testData.genesisBlockHeader
                          )
    blockchain.putGenesis(genesisBlock, next)
  }

function ( next ) { genesisBlock . header = new BlockHeader ( testData . genesisBlockHeader ) blockchain . putGenesis ( genesisBlock , next ) }


function (next) {
    async.eachSeries(testData.blocks, eachBlock, next)

    function eachBlock (raw, cb) {
      try {
        var block = new Block(
            Buffer.from(raw.rlp.slice(2), 'hex'))

        // forces the block into thinking they are homestead
        block.header.isHomestead = function () {
          return true
        }
        block.uncleHeaders.forEach(function (uncle) {
          uncle.isHomestead = function () { return true }
        })

        blockchain.putBlock(block, function (err) {
          cb(err)
        })
      } catch (err) {
        cb()
      }
    }
  }


function getHead (next) {
    vm.blockchain.getHead(function (err, block) {
      // make sure the state is set before checking post conditions
      state.root = block.header.stateRoot
      next(err)
    })
  }


function runVm (err) {
    // Check that the programCounter is in range. Does not overwrite the previous err, if any.
    const pc = runState.programCounter
    if (!err && pc !== 0 && (pc < 0 || pc >= runState.code.length)) {
      err = new VmError(ERROR.INVALID_OPCODE)
    }

    if (err) {
      return parseVmResults(err)
    }
    async.whilst(vmIsActive, iterateVm, parseVmResults)
  }

iterate through the given ops until something breaks or we hit STOP


function loadContract (cb) {
    stateManager.getAccount(runState.address, function (err, account) {
      if (err) return cb(err)
      runState.contract = account
      cb()
    })
  }

function loadContract ( cb ) { stateManager . getAccount ( runState . address , function ( err , account ) { if ( err ) return cb ( err ) runState . contract = account cb ( ) } ) }

ensure contract is loaded; only used if runCode is called directly

ensure contract is loaded ; only used if runCode is called directly


function preprocessValidJumps (runState) {
  for (var i = 0; i < runState.code.length; i++) {
    var curOpCode = lookupOpInfo(runState.code[i]).name

    // no destinations into the middle of PUSH
    if (curOpCode === 'PUSH') {
      i += runState.code[i] - 0x5f
    }

    if (curOpCode === 'JUMPDEST') {
      runState.validJumps.push(i)
    }
  }
}

find all the valid jumps and puts them in the `validJumps` array

find all the valid jumps and puts them in the validJumps array


function getStartingState (cb) {
      // if we are just starting or if a chain re-org has happened
      if (!headBlock || reorg) {
        blockchain.getBlock(block.header.parentHash, function (err, parentBlock) {
          parentState = parentBlock.header.stateRoot
          // generate genesis state if we are at the genesis block
          // we don't have the genesis state
          if (!headBlock) {
            return self.stateManager.generateCanonicalGenesis(cb)
          } else {
            cb(err)
          }
        })
      } else {
        parentState = headBlock.header.stateRoot
        cb()
      }
    }


function runBlock (cb) {
      self.runBlock({
        block: block,
        root: parentState
      }, function (err, results) {
        if (err) {
          // remove invalid block
          blockchain.delBlock(block.header.hash(), function () {
            cb(err)
          })
        } else {
          // set as new head block
          headBlock = block
          cb()
        }
      })
    }

function
runBlock
(
cb
)
{
self
.
runBlock
(
{
block
:
block
,
root
:
parentState
}
,
function
(
err
,
results
)
{
if
(
err
)
{
// remove invalid block
blockchain
.
delBlock
(
block
.
header
.
hash
(
)
,
function
(
)
{
cb
(
err
)
}
)
}
else
{
// set as new head block
headBlock
=
block
cb
(
)
}
}
)
}


function payOmmersAndMiner (cb) {
    var ommers = block.uncleHeaders

    // pay each ommer
    async.series([
      rewardOmmers,
      rewardMiner
    ], cb)

    function rewardOmmers (done) {
      async.each(block.uncleHeaders, function (ommer, next) {
        // calculate reward
        var minerReward = new BN(self._common.param('pow', 'minerReward'))
        var heightDiff = new BN(block.header.number).sub(new BN(ommer.number))
        var reward = ((new BN(8)).sub(heightDiff)).mul(minerReward.divn(8))

        if (reward.ltn(0)) {
          reward = new BN(0)
        }

        rewardAccount(ommer.coinbase, reward, next)
      }, done)
    }

    function rewardMiner (done) {
      // calculate nibling reward
      var minerReward = new BN(self._common.param('pow', 'minerReward'))
      var niblingReward = minerReward.divn(32)
      var totalNiblingReward = niblingReward.muln(ommers.length)
      var reward = minerReward.add(totalNiblingReward)
      rewardAccount(block.header.coinbase, reward, done)
    }

    function rewardAccount (address, reward, done) {
      self.stateManager.getAccount(address, function (err, account) {
        if (err) return done(err)
        // give miner the block reward
        account.balance = new BN(account.balance).add(reward)
        self.stateManager.putAccount(address, account, done)
      })
    }
  }

function
payOmmersAndMiner
(
cb
)
{
var
ommers
=
block
.
uncleHeaders
// pay each ommer
async
.
series
(
[
rewardOmmers
,
rewardMiner
]
,
cb
)
function
rewardOmmers
(
done
)
{
async
.
each
(
block
.
uncleHeaders
,
function
(
ommer
,
next
)
{
// calculate reward
var
minerReward
=
new
BN
(
self
.
_common
.
param
(
'pow'
,
'minerReward'
)
)
var
heightDiff
=
new
BN
(
block
.
header
.
number
)
.
sub
(
new
BN
(
ommer
.
number
)
)
var
reward
=
(
(
new
BN
(
8
)
)
.
sub
(
heightDiff
)
)
.
mul
(
minerReward
.
divn
(
8
)
)
if
(
reward
.
ltn
(
0
)
)
{
reward
=
new
BN
(
0
)
}
rewardAccount
(
ommer
.
coinbase
,
reward
,
next
)
}
,
done
)
}
function
rewardMiner
(
done
)
{
// calculate nibling reward
var
minerReward
=
new
BN
(
self
.
_common
.
param
(
'pow'
,
'minerReward'
)
)
var
niblingReward
=
minerReward
.
divn
(
32
)
var
totalNiblingReward
=
niblingReward
.
muln
(
ommers
.
length
)
var
reward
=
minerReward
.
add
(
totalNiblingReward
)
rewardAccount
(
block
.
header
.
coinbase
,
reward
,
done
)
}
function
rewardAccount
(
address
,
reward
,
done
)
{
self
.
stateManager
.
getAccount
(
address
,
function
(
err
,
account
)
{
if
(
err
)
return
done
(
err
)
// give miner the block reward
account
.
balance
=
new
BN
(
account
.
balance
)
.
add
(
reward
)
self
.
stateManager
.
putAccount
(
address
,
account
,
done
)
}
)
}
}


function parseBlockResults (err) {
    if (err) {
      if (checkpointedState) {
        self.stateManager.revert(function () {
          cb(err)
        })
      } else {
        cb(err)
      }
      return
    }

    self.stateManager.commit(function (err) {
      if (err) return cb(err)

      self.stateManager.getStateRoot(function (err, stateRoot) {
        if (err) return cb(err)

        // credit all block rewards
        if (generateStateRoot) {
          block.header.stateRoot = stateRoot
        }

        if (validateStateRoot) {
          if (receiptTrie.root && receiptTrie.root.toString('hex') !== block.header.receiptTrie.toString('hex')) {
            err = new Error((err || '') + 'invalid receiptTrie ')
          }
          if (bloom.bitvector.toString('hex') !== block.header.bloom.toString('hex')) {
            err = new Error((err || '') + 'invalid bloom ')
          }
          if (ethUtil.bufferToInt(block.header.gasUsed) !== Number(gasUsed)) {
            err = new Error((err || '') + 'invalid gasUsed ')
          }
          if (stateRoot.toString('hex') !== block.header.stateRoot.toString('hex')) {
            err = new Error((err || '') + 'invalid block stateRoot ')
          }
        }

        result = {
          receipts: receipts,
          results: txResults,
          error: err
        }

        afterBlock(cb.bind(this, err, result))
      })
    })
  }

function
parseBlockResults
(
err
)
{
if
(
err
)
{
if
(
checkpointedState
)
{
self
.
stateManager
.
revert
(
function
(
)
{
cb
(
err
)
}
)
}
else
{
cb
(
err
)
}
return
}
self
.
stateManager
.
commit
(
function
(
err
)
{
if
(
err
)
return
cb
(
err
)
self
.
stateManager
.
getStateRoot
(
function
(
err
,
stateRoot
)
{
if
(
err
)
return
cb
(
err
)
// credit all block rewards
if
(
generateStateRoot
)
{
block
.
header
.
stateRoot
=
stateRoot
}
if
(
validateStateRoot
)
{
if
(
receiptTrie
.
root
&&
receiptTrie
.
root
.
toString
(
'hex'
)
!==
block
.
header
.
receiptTrie
.
toString
(
'hex'
)
)
{
err
=
new
Error
(
(
err
||
''
)
+
'invalid receiptTrie '
)
}
if
(
bloom
.
bitvector
.
toString
(
'hex'
)
!==
block
.
header
.
bloom
.
toString
(
'hex'
)
)
{
err
=
new
Error
(
(
err
||
''
)
+
'invalid bloom '
)
}
if
(
ethUtil
.
bufferToInt
(
block
.
header
.
gasUsed
)
!==
Number
(
gasUsed
)
)
{
err
=
new
Error
(
(
err
||
''
)
+
'invalid gasUsed '
)
}
if
(
stateRoot
.
toString
(
'hex'
)
!==
block
.
header
.
stateRoot
.
toString
(
'hex'
)
)
{
err
=
new
Error
(
(
err
||
''
)
+
'invalid block stateRoot '
)
}
}
result
=
{
receipts
:
receipts
,
results
:
txResults
,
error
:
err
}
afterBlock
(
cb
.
bind
(
this
,
err
,
result
)
)
}
)
}
)
}


function setup (cb) {
  // the address we are sending from
  var publicKeyBuf = Buffer.from(keyPair.publicKey, 'hex')
  var address = utils.pubToAddress(publicKeyBuf, true)

  // create a new account
  var account = new Account()

  // give the account some wei.
  //    Note: this needs to be a `Buffer` or a string. All
  //      strings need to be in hex.
  account.balance = '0xf00000000000000001'

  // store in the trie
  stateTrie.put(address, account.serialize(), cb)
}

sets up the initial state and runs the callback when complete


function runTx (raw, cb) {
  // create a new transaction out of the json
  var tx = new Transaction(raw)

  // tx.from
  tx.sign(Buffer.from(keyPair.secretKey, 'hex'))

  console.log('----running tx-------')
  // run the tx \o/
  vm.runTx({
    tx: tx
  }, function (err, results) {
    createdAddress = results.createdAddress
    // log some results
    console.log('gas used: ' + results.gasUsed.toString())
    console.log('returned: ' + results.vm.return.toString('hex'))
    if (createdAddress) {
      console.log('address created: ' +
          createdAddress.toString('hex'))
    }

    cb(err)
  })
}


function checkResults (cb) {
  // fetch the new account from the trie.
  stateTrie.get(createdAddress, function (err, val) {
    var account = new Account(val)

    storageRoot = account.stateRoot // used later! :)
    console.log('------results------')
    console.log('nonce: ' + account.nonce.toString('hex'))
    console.log('balance in wei: ' + account.balance.toString('hex'))
    console.log('stateRoot: ' + storageRoot.toString('hex'))
    console.log('codeHash:' + account.codeHash.toString('hex'))
    console.log('-------------------')
    cb(err)
  })
}

function
checkResults
(
cb
)
{
// fetch the new account from the trie.
stateTrie
.
get
(
createdAddress
,
function
(
err
,
val
)
{
var
account
=
new
Account
(
val
)
storageRoot
=
account
.
stateRoot
// used later! :)
console
.
log
(
'------results------'
)
console
.
log
(
'nonce: '
+
account
.
nonce
.
toString
(
'hex'
)
)
console
.
log
(
'balance in wei: '
+
account
.
balance
.
toString
(
'hex'
)
)
console
.
log
(
'stateRoot: '
+
storageRoot
.
toString
(
'hex'
)
)
console
.
log
(
'codeHash:'
+
account
.
codeHash
.
toString
(
'hex'
)
)
console
.
log
(
'-------------------'
)
cb
(
err
)
}
)
}

Now lets look at what we created. The transaction should have created a new account for the contranct in the trie.Lets test to see if it did.

Now lets look at what we created . The transaction should have created a new account for the contranct in the trie . Lets test to see if it did .


function readStorage (cb) {
  // we need to create a copy of the state root
  var storageTrie = stateTrie.copy()

  // Since we are using a copy we won't change the
  // root of `stateTrie`
  storageTrie.root = storageRoot

  var stream = storageTrie.createReadStream()

  console.log('------Storage------')

  // prints all of the keys and values in the storage trie
  stream.on('data', function (data) {
    // remove the 'hex' if you want to see the ascii values
    console.log('key: ' + data.key.toString('hex'))
    console.log('Value: ' + rlp.decode(data.value).toString())
  })

  stream.on('end', cb)
}

So if everything went right we should have "null_radix" stored at "0x9bdf9e2cc4dfa83de3c35da792cdf9b9e9fcfabd". To see this we need to print out the name register's storage trie. reads and prints the storage of a contract


function _handleKey(character, modifiers, e) {
        var self = this;

        if (!self.recording) {
            _origHandleKey.apply(self, arguments);
            return;
        }

        // remember this character if we're currently recording a sequence
        if (e.type == 'keydown') {
            if (character.length === 1 && _recordedCharacterKey) {
                _recordCurrentCombo();
            }

            for (i = 0; i < modifiers.length; ++i) {
                _recordKey(modifiers[i]);
            }
            _recordKey(character);

        // once a key is released, all keys that were held down at the time
        // count as a keypress
        } else if (e.type == 'keyup' && _currentRecordedKeys.length > 0) {
            _recordCurrentCombo();
        }
    }

handles a character key event

@param {string} character
@param {Array} modifiers
@param {Event} e
@returns void


function _recordKey(key) {
        var i;

        // one-off implementation of Array.indexOf, since IE6-9 don't support it
        for (i = 0; i < _currentRecordedKeys.length; ++i) {
            if (_currentRecordedKeys[i] === key) {
                return;
            }
        }

        _currentRecordedKeys.push(key);

        if (key.length === 1) {
            _recordedCharacterKey = true;
        }
    }

marks a character key as held down while recording a sequence

@param {string} key
@returns void


function _normalizeSequence(sequence) {
        var i;

        for (i = 0; i < sequence.length; ++i) {
            sequence[i].sort(function(x, y) {
                // modifier keys always come first, in alphabetical order
                if (x.length > 1 && y.length === 1) {
                    return -1;
                } else if (x.length === 1 && y.length > 1) {
                    return 1;
                }

                // character keys come next (list should contain no duplicates,
                // so no need for equality check)
                return x > y ? 1 : -1;
            });

            sequence[i] = sequence[i].join('+');
        }
    }

ensures each combo in a sequence is in a predictable order and formats
key combos to be '+'-delimited

modifies the sequence in-place

@param {Array} sequence
@returns void

ensures each combo in a sequence is in a predictable order and formats key combos to be + - delimited


function _finishRecording() {
        if (_recordedSequenceCallback) {
            _normalizeSequence(_recordedSequence);
            _recordedSequenceCallback(_recordedSequence);
        }

        // reset all recorded state
        _recordedSequence = [];
        _recordedSequenceCallback = null;
        _currentRecordedKeys = [];
    }

function
_finishRecording
(
)
{
if
(
_recordedSequenceCallback
)
{
_normalizeSequence
(
_recordedSequence
)
;
_recordedSequenceCallback
(
_recordedSequence
)
;
}
// reset all recorded state
_recordedSequence
=
[
]
;
_recordedSequenceCallback
=
;
_currentRecordedKeys
=
[
]
;
}

finishes the current recording, passes the recorded sequence to the stored
callback, and sets Mousetrap.handleKey back to its original function

@returns void

finishes the current recording passes the recorded sequence to the stored callback and sets Mousetrap . handleKey back to its original function


function CreateSetPolyfill() {
            return /** @class */ (function () {
                function Set() {
                    this._map = new _Map();
                }
                Object.defineProperty(Set.prototype, "size", {
                    get: function () { return this._map.size; },
                    enumerable: true,
                    configurable: true
                });
                Set.prototype.has = function (value) { return this._map.has(value); };
                Set.prototype.add = function (value) { return this._map.set(value, value), this; };
                Set.prototype.delete = function (value) { return this._map.delete(value); };
                Set.prototype.clear = function () { this._map.clear(); };
                Set.prototype.keys = function () { return this._map.keys(); };
                Set.prototype.values = function () { return this._map.values(); };
                Set.prototype.entries = function () { return this._map.entries(); };
                Set.prototype["@@iterator"] = function () { return this.keys(); };
                Set.prototype[iteratorSymbol] = function () { return this.keys(); };
                return Set;
            }());
        }

function
CreateSetPolyfill
(
)
{
return
/** @class */
(
function
(
)
{
function
Set
(
)
{
this
.
_map
=
new
_Map
(
)
;
}
Object
.
defineProperty
(
Set
.
prototype
,
"size"
,
{
get
:
function
(
)
{
return
this
.
_map
.
size
;
}
,
enumerable
:
true
,
configurable
:
true
}
)
;
Set
.
prototype
.
has
=
function
(
value
)
{
return
this
.
_map
.
has
(
value
)
;
}
;
Set
.
prototype
.
add
=
function
(
value
)
{
return
this
.
_map
.
set
(
value
,
value
)
,
this
;
}
;
Set
.
prototype
.
delete
=
function
(
value
)
{
return
this
.
_map
.
delete
(
value
)
;
}
;
Set
.
prototype
.
clear
=
function
(
)
{
this
.
_map
.
clear
(
)
;
}
;
Set
.
prototype
.
keys
=
function
(
)
{
return
this
.
_map
.
keys
(
)
;
}
;
Set
.
prototype
.
values
=
function
(
)
{
return
this
.
_map
.
values
(
)
;
}
;
Set
.
prototype
.
entries
=
function
(
)
{
return
this
.
_map
.
entries
(
)
;
}
;
Set
.
prototype
[
"@@iterator"
]
=
function
(
)
{
return
this
.
keys
(
)
;
}
;
Set
.
prototype
[
iteratorSymbol
]
=
function
(
)
{
return
this
.
keys
(
)
;
}
;
return
Set
;
}
(
)
)
;
}


function fuzzysearch (searchString, haystack, caseInsensitive) {
  var tlen = haystack.length;
  var qlen = searchString.length;
  var chunks = 1;
  var finding = false;
  var prefix = true;

  if (qlen > tlen) {
    return false;
  }

  if (qlen === tlen) {
    if (searchString === haystack) {
      return { caseMatch: true, chunks: 1, prefix: true };
    } else if (searchString.toLowerCase() === haystack.toLowerCase()) {
      return { caseMatch: false, chunks: 1, prefix: true };
    } else {
      return false;
    }
  }

  outer: for (var i = 0, j = 0; i < qlen; i++) {
    var nch = searchString[i];
    while (j < tlen) {
      var targetChar = haystack[j++];
      if (targetChar === nch) {
        finding = true;
        continue outer;
      }
      if (finding) {
        chunks++;
        finding = false;
      }
    }

    if (caseInsensitive) { return false }

    return fuzzysearch(searchString.toLowerCase(), haystack.toLowerCase(), true);
  }

  return { caseMatch: !caseInsensitive, chunks: chunks, prefix: j <= qlen };
}

function fuzzysearch ( searchString , haystack , caseInsensitive ) { var tlen = haystack . length ; var qlen = searchString . length ; var chunks = 1 ; var finding = false ; var prefix = true ; if ( qlen > tlen ) { return false ; } if ( qlen === tlen ) { if ( searchString === haystack ) { return { caseMatch : true , chunks : 1 , prefix : true } ; } else if ( searchString . toLowerCase ( ) === haystack . toLowerCase ( ) ) { return { caseMatch : false , chunks : 1 , prefix : true } ; } else { return false ; } } outer : for ( var i = 0 , j = 0 ; i < qlen ; i ++ ) { var nch = searchString [ i ] ; while ( j < tlen ) { var targetChar = haystack [ j ++ ] ; if ( targetChar === nch ) { finding = true ; continue outer ; } if ( finding ) { chunks ++ ; finding = false ; } } if ( caseInsensitive ) { return false } return fuzzysearch ( searchString . toLowerCase ( ) , haystack . toLowerCase ( ) , true ) ; } return { caseMatch : ! caseInsensitive , chunks : chunks , prefix : j <= qlen } ; }

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

THE SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .


function getExternals (api, pluginOptions) {
  const nodeModulesPath = pluginOptions.nodeModulesPath || './node_modules'
  let nodeModulesPaths = []
  if (Array.isArray(nodeModulesPath)) {
    // Set to user-defined array
    nodeModulesPaths = nodeModulesPath
  } else {
    // Add path to list
    nodeModulesPaths.push(nodeModulesPath)
  }
  const userExternals = pluginOptions.externals || []
  const userExternalsWhitelist = []
  userExternals.forEach((d, i) => {
    if (d.match(/^!/)) {
      userExternals.splice(i, 1)
      userExternalsWhitelist.push(d.replace(/^!/, ''))
    }
  })
  const { dependencies } = require(api.resolve('./package.json'))
  const externalsList = Object.keys(dependencies || {}).reduce(
    (depList, dep) => {
      // Return true if we want to add a dependency to externals
      try {
        let pgkString
        for (const path of nodeModulesPaths) {
          // Check if package.json exists
          if (fs.existsSync(api.resolve(`${path}/${dep}/package.json`))) {
            // If it does, read it and break
            pgkString = fs
              .readFileSync(api.resolve(`${path}/${dep}/package.json`))
              .toString()
            break
          }
        }
        if (!pgkString) {
          throw new Error(`Could not find a package.json for module ${dep}`)
        }
        const pkg = JSON.parse(pgkString)
        const name = userExternals.find(name =>
          new RegExp(`^${pkg.name}`).test(name)
        )
        const fields = ['main', 'module', 'jsnext:main', 'browser']
        if (
          // Not whitelisted
          userExternalsWhitelist.indexOf(dep) === -1 &&
          // Doesn't have main property
          (!fields.some(field => field in pkg) ||
            // Has binary property
            !!pkg.binary ||
            // Has gypfile property
            !!pkg.gypfile ||
            // Listed in user-defined externals list
            !!name)
        ) {
          // Use user-provided name if it exists, for subpaths
          depList.push(name || dep)
        }
      } catch (e) {
        console.log(e)
        depList.push(dep)
      }
      return depList
    },
    []
  )
  let externals = {}
  externalsList.forEach(d => {
    // Set external to be required during runtime
    externals[d] = `require("${d}")`
  })
  return externals
}

Find all the dependencies without a `main` property or with a `binary` property or set by user and add them as webpack externals

Find all the dependencies without a main property or with a binary property or set by user and add them as webpack externals


function(hashKey, dataObject, myContent, myClass, bootstrapSettings) {
      var exportButton = document.createElement("button");
      exportButton.setAttribute("type", "button");
      exportButton.setAttribute(this.storageKey, hashKey);
      exportButton.className = bootstrapSettings.bootstrapClass + bootstrapSettings.bootstrapTheme + myClass;
      exportButton.textContent = myContent;
      return exportButton;
    }

function ( hashKey , dataObject , myContent , myClass , bootstrapSettings ) { var exportButton = document . createElement ( "button" ) ; exportButton . setAttribute ( "type" , "button" ) ; exportButton . setAttribute ( this . storageKey , hashKey ) ; exportButton . className = bootstrapSettings . bootstrapClass + bootstrapSettings . bootstrapTheme + myClass ; exportButton . textContent = myContent ; return exportButton ; }

Creates file export buttons
@param hashKey {String}
@param dataObject {String}
@param myContent {String}
@param myClass {String}
@param bootstrapSettings {Object}
@returns Element


function(string) {
      var self = this;
      return String(string).replace(/[&<>'\/]/g, function(s) {
        return self.entityMap[s];
      });
    }

function ( string ) { var self = this ; return String ( string ) . replace ( / [&<>'\/] / g , function ( s ) { return self . entityMap [ s ] ; } ) ; }

Escapes special characters with HTML entities
@memberof TableExport.prototype
@param string {String}
@returns {String} escaped string


function(string) {
      var str = String(string);
      for (var key in this.entityMap) {
        str = str.replace(RegExp(this.entityMap[key], "g"), key);
      }
      return str;
    }

function ( string ) { var str = String ( string ) ; for ( var key in this . entityMap ) { str = str . replace ( RegExp ( this . entityMap [ key ] , "g" ) , key ) ; } return str ; }

Unescapes HTML entities to special characters
@memberof TableExport.prototype
@param string {String}
@returns {String} unescaped string


function(string) {
      if (!string) return "";
      var types = this.typeConfig;
      if (~string.indexOf(types.string.defaultClass)) {
        return _TYPE.STRING;
      } else if (~string.indexOf(types.number.defaultClass)) {
        return _TYPE.NUMBER;
      } else if (~string.indexOf(types.boolean.defaultClass)) {
        return _TYPE.BOOLEAN;
      } else if (~string.indexOf(types.date.defaultClass)) {
        return _TYPE.DATE;
      } else {
        return "";
      }
    }

function ( string ) { if ( ! string ) return "" ; var types = this . typeConfig ; if ( ~ string . indexOf ( types . string . defaultClass ) ) { return _TYPE . STRING ; } else if ( ~ string . indexOf ( types . number . defaultClass ) ) { return _TYPE . NUMBER ; } else if ( ~ string . indexOf ( types . boolean . defaultClass ) ) { return _TYPE . BOOLEAN ; } else if ( ~ string . indexOf ( types . date . defaultClass ) ) { return _TYPE . DATE ; } else { return "" ; } }

Get cell data-type
@param string {String}
@returns {String} data-type


function(v, date1904) {
      if (date1904) v += 1462;
      var epoch = Date.parse(v);
      var result = (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
      return Math.floor(result);
    }

function ( v , date1904 ) { if ( date1904 ) v += 1462 ; var epoch = Date . parse ( v ) ; var result = ( epoch - new Date ( Date . UTC ( 1899 , 11 , 30 ) ) ) / ( 24 * 60 * 60 * 1000 ) ; return Math . floor ( result ) ; }

Formats datetimes for compatibility with Excel
@memberof TableExport.prototype
@param v {Number}
@param date1904 {Date}
@returns {Number} epoch time


function(data, merges) {
      var ws = {};
      var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
      var types = this.typeConfig;
      for (var R = 0; R !== data.length; ++R) {
        for (var C = 0; C !== data[R].length; ++C) {
          if (range.s.r > R) range.s.r = R;
          if (range.s.c > C) range.s.c = C;
          if (range.e.r < R) range.e.r = R;
          if (range.e.c < C) range.e.c = C;
          var cell = data[R][C];
          if (!cell || !cell.v) continue;
          var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });

          if (!cell.t) {
            if (types.number.assert(cell.v)) cell.t = _TYPE.NUMBER;
            else if (types.boolean.assert(cell.v)) cell.t = _TYPE.BOOLEAN;
            else if (types.date.assert(cell.v)) cell.t = _TYPE.DATE;
            else cell.t = _TYPE.STRING;
          }
          if (cell.t === _TYPE.DATE) {
            cell.t = _TYPE.NUMBER;
            cell.z = XLSX.SSF._table[14];
            cell.v = this.dateNum(cell.v);
          }
          ws[cell_ref] = cell;
        }
      }
      ws["!merges"] = merges;
      if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
      return ws;
    }

function ( data , merges ) { var ws = { } ; var range = { s : { c : 10000000 , r : 10000000 } , e : { c : 0 , r : 0 } } ; var types = this . typeConfig ; for ( var R = 0 ; R !== data . length ; ++ R ) { for ( var C = 0 ; C !== data [ R ] . length ; ++ C ) { if ( range . s . r > R ) range . s . r = R ; if ( range . s . c > C ) range . s . c = C ; if ( range . e . r < R ) range . e . r = R ; if ( range . e . c < C ) range . e . c = C ; var cell = data [ R ] [ C ] ; if ( ! cell || ! cell . v ) continue ; var cell_ref = XLSX . utils . encode_cell ( { c : C , r : R } ) ; if ( ! cell . t ) { if ( types . number . assert ( cell . v ) ) cell . t = _TYPE . NUMBER ; else if ( types . boolean . assert ( cell . v ) ) cell . t = _TYPE . BOOLEAN ; else if ( types . date . assert ( cell . v ) ) cell . t = _TYPE . DATE ; else cell . t = _TYPE . STRING ; } if ( cell . t === _TYPE . DATE ) { cell . t = _TYPE . NUMBER ; cell . z = XLSX . SSF . _table [ 14 ] ; cell . v = this . dateNum ( cell . v ) ; } ws [ cell_ref ] = cell ; } } ws [ "!merges" ] = merges ; if ( range . s . c < 10000000 ) ws [ "!ref" ] = XLSX . utils . encode_range ( range ) ; return ws ; }

Creates an Excel spreadsheet from a data string
@memberof TableExport.prototype
@param data {String}
@param merges {Object[]}


function(event) {
      var target = event.target;
      var object = JSON.parse(Storage.getInstance().getItem(target.getAttribute(this.storageKey))),
        data = object.data,
        filename = object.filename,
        mimeType = object.mimeType,
        fileExtension = object.fileExtension,
        merges = object.merges,
        RTL = object.RTL,
        sheetname = object.sheetname;
      this.export2file(data, mimeType, filename, fileExtension, merges, RTL, sheetname);
    }

function ( event ) { var target = event . target ; var object = JSON . parse ( Storage . getInstance ( ) . getItem ( target . getAttribute ( this . storageKey ) ) ) , data = object . data , filename = object . filename , mimeType = object . mimeType , fileExtension = object . fileExtension , merges = object . merges , RTL = object . RTL , sheetname = object . sheetname ; this . export2file ( data , mimeType , filename , fileExtension , merges , RTL , sheetname ) ; }

Click handler for export button "download"
@memberof TableExport.prototype

Click handler for export button download


function(data, mime, name, extension, merges, RTL, sheetname) {
      var format = extension.slice(1);
      data = this.getRawData(data, extension, name, merges, RTL, sheetname);

      if (_isMobile && (format === _FORMAT.CSV || format === _FORMAT.TXT)) {
        var dataURI = "data:" + mime + ";" + this.charset + "," + data;
        this.downloadDataURI(dataURI, name, extension);
      } else {
        // TODO: error and fallback when `saveAs` not available
        saveAs(new Blob([data], { type: mime + ";" + this.charset }), name + extension, true);
      }
    }

Exports and downloads the file
@memberof TableExport.prototype
@param data {String}
@param mime {String} mime type
@param name {String} filename
@param extension {String} file extension
@param merges {Object[]}
@param RTL {Boolean}


function() {
    this._instance = null;

    this.store = sessionStorage;
    this.namespace = TableExport.prototype.defaultNamespace;
    this.getKey = function(key) {
      return this.namespace + key;
    };
    this.setItem = function(_key, value, overwrite) {
      var key = this.getKey(_key);
      if (this.exists(_key) && !overwrite) {
        return;
      }
      if (typeof value !== "string") return _handleError('"value" must be a string.');
      this.store.setItem(key, value);
      return _key;
    };
    this.getItem = function(_key) {
      var key = this.getKey(_key);
      return this.store.getItem(key);
    };
    this.exists = function(_key) {
      var key = this.getKey(_key);
      return this.store.getItem(key) !== null;
    };
    this.removeItem = function(_key) {
      var key = this.getKey(_key);
      return this.store.removeItem(key);
    };
  }

function
(
)
{
this
.
_instance
=
;
this
.
store
=
sessionStorage
;
this
.
namespace
=
TableExport
.
prototype
.
defaultNamespace
;
this
.
getKey
=
function
(
key
)
{
return
this
.
namespace
+
key
;
}
;
this
.
setItem
=
function
(
_key
,
value
,
overwrite
)
{
var
key
=
this
.
getKey
(
_key
)
;
if
(
this
.
exists
(
_key
)
&&
!
overwrite
)
{
return
;
}
if
(
typeof
value
!==
"string"
)
return
_handleError
(
'"value" must be a string.'
)
;
this
.
store
.
setItem
(
key
,
value
)
;
return
_key
;
}
;
this
.
getItem
=
function
(
_key
)
{
var
key
=
this
.
getKey
(
_key
)
;
return
this
.
store
.
getItem
(
key
)
;
}
;
this
.
exists
=
function
(
_key
)
{
var
key
=
this
.
getKey
(
_key
)
;
return
this
.
store
.
getItem
(
key
)
!==
;
}
;
this
.
removeItem
=
function
(
_key
)
{
var
key
=
this
.
getKey
(
_key
)
;
return
this
.
store
.
removeItem
(
key
)
;
}
;
}

Storage main interface constructor
@memberof TableExport.prototype
@constructor


function getPlatformLibtensorflowUri() {
  let targetUri = BASE_URI;
  if (platform === 'linux') {
    if (os.arch() === 'arm') {
      // TODO(kreeger): Update to TensorFlow 1.13:
      // https://github.com/tensorflow/tfjs/issues/1370
      targetUri =
          'https://storage.googleapis.com/tf-builds/libtensorflow_r1_12_linux_arm.tar.gz';
    } else {
      if (libType === 'gpu') {
        targetUri += GPU_LINUX;
      } else {
        targetUri += CPU_LINUX;
      }
    }
  } else if (platform === 'darwin') {
    targetUri += CPU_DARWIN;
  } else if (platform === 'win32') {
    // Use windows path
    path = path.win32;
    if (libType === 'gpu') {
      targetUri += GPU_WINDOWS;
    } else {
      targetUri += CPU_WINDOWS;
    }
  } else {
    throw new Error(`Unsupported platform: ${platform}`);
  }
  return targetUri;
}

Returns the libtensorflow hosted path of the current platform.

Returns the libtensorflow hosted path of the current platform .


async function cleanDeps() {
  if (await exists(depsPath)) {
    await rimrafPromise(depsPath);
  }
  await mkdir(depsPath);
}

async function cleanDeps ( ) { if ( await exists ( depsPath ) ) { await rimrafPromise ( depsPath ) ; } await mkdir ( depsPath ) ; }

Deletes the deps directory if it exists, and creates a fresh deps folder.

Deletes the deps directory if it exists and creates a fresh deps folder .


async function downloadLibtensorflow(callback) {
  // Ensure dependencies staged directory is available:
  await ensureDir(depsPath);

  console.warn('* Downloading libtensorflow');
  resources.downloadAndUnpackResource(
      getPlatformLibtensorflowUri(), depsPath, async () => {
        if (platform === 'win32') {
          // Some windows libtensorflow zip files are missing structure and the
          // eager headers. Check, restructure, and download resources as
          // needed.
          const depsIncludePath = path.join(depsPath, 'include');
          if (!await exists(depsLibTensorFlowPath)) {
            // Verify that tensorflow.dll exists
            const libtensorflowDll = path.join(depsPath, 'tensorflow.dll');
            if (!await exists(libtensorflowDll)) {
              throw new Error('Could not find libtensorflow.dll');
            }

            await ensureDir(depsLibPath);
            await rename(libtensorflowDll, depsLibTensorFlowPath);
          }

          // Next check the structure for the C-library headers. If they don't
          // exist, download and unzip them.
          if (!await exists(depsIncludePath)) {
            // Remove duplicated assets from the original libtensorflow package.
            // They will be replaced by the download below:
            await unlink(path.join(depsPath, 'c_api.h'));
            await unlink(path.join(depsPath, 'LICENSE'));

            // Download the C headers only and unpack:
            resources.downloadAndUnpackResource(
                TF_WIN_HEADERS_URI, depsPath, () => {
                  if (callback !== undefined) {
                    callback();
                  }
                });
          } else {
            if (callback !== undefined) {
              callback();
            }
          }
        } else {
          // No other work is required on other platforms.
          if (callback !== undefined) {
            callback();
          }
        }
      });
}

Downloads libtensorflow and notifies via a callback when unpacked.

Downloads libtensorflow and notifies via a callback when unpacked .


async function build() {
  console.error('* Building TensorFlow Node.js bindings');
  cp.exec('node-gyp rebuild', (err) => {
    if (err) {
      throw new Error('node-gyp rebuild failed with: ' + err);
    }
  });
}

Calls node-gyp for Node.js Tensorflow binding after lib is downloaded.

Calls node - gyp for Node . js Tensorflow binding after lib is downloaded .


async function run() {
  // First check if deps library exists:
  if (forceDownload !== 'download' && await exists(depsLibTensorFlowPath)) {
    // Library has already been downloaded, then compile and simlink:
    await build();
  } else {
    // Library has not been downloaded, download, then compile and symlink:
    await cleanDeps();
    await downloadLibtensorflow(build);
  }
}

Ensures libtensorflow requirements are met for building the binding.

Ensures libtensorflow requirements are met for building the binding .


async function symlinkDepsLib() {
  if (destLibPath === undefined) {
    throw new Error('Destination path not supplied!');
  }
  try {
    await symlink(depsLibTensorFlowPath, destLibPath);
    if (os.platform() !== 'win32') {
      await symlink(depsLibTensorFlowFrameworkPath, destFrameworkLibPath);
    }
  } catch (e) {
    console.error(
        `  * Symlink of ${destLibPath} failed, creating a copy on disk.`);
    await copy(depsLibTensorFlowPath, destLibPath);
    if (os.platform() !== 'win32') {
      await copy(depsLibTensorFlowFrameworkPath, destFrameworkLibPath);
    }
  }
}

async
function
symlinkDepsLib
(
)
{
if
(
destLibPath
===
undefined
)
{
throw
new
Error
(
'Destination path not supplied!'
)
;
}
try
{
await
symlink
(
depsLibTensorFlowPath
,
destLibPath
)
;
if
(
os
.
platform
(
)
!==
'win32'
)
{
await
symlink
(
depsLibTensorFlowFrameworkPath
,
destFrameworkLibPath
)
;
}
}
catch
(
e
)
{
console
.
error
(
`
${
destLibPath
}
`
)
;
await
copy
(
depsLibTensorFlowPath
,
destLibPath
)
;
if
(
os
.
platform
(
)
!==
'win32'
)
{
await
copy
(
depsLibTensorFlowFrameworkPath
,
destFrameworkLibPath
)
;
}
}
}

Symlinks the extracted libtensorflow library to the destination path. If the
symlink fails, a copy is made.

Symlinks the extracted libtensorflow library to the destination path . If the symlink fails a copy is made .


async function moveDepsLib() {
  await rename(depsLibTensorFlowPath, destLibPath);
  if (os.platform() !== 'win32') {
    await rename(depsLibTensorFlowFrameworkPath, destFrameworkLibPath);
  }
}

async function moveDepsLib ( ) { await rename ( depsLibTensorFlowPath , destLibPath ) ; if ( os . platform ( ) !== 'win32' ) { await rename ( depsLibTensorFlowFrameworkPath , destFrameworkLibPath ) ; } }

Moves the deps library path to the destination path.

Moves the deps library path to the destination path .


async function run(action) {
  if (action.endsWith('symlink')) {
    // Symlink will happen during `node-gyp rebuild`
    await symlinkDepsLib();
  } else if (action.endsWith('move')) {
    // Move action is used when installing this module as a package.
    await moveDepsLib();
  } else {
    throw new Error('Invalid action: ' + action);
  }
}

Symlink or move libtensorflow for building the binding.

Symlink or move libtensorflow for building the binding .