<commit_before>import React from 'react';
import Subheader from 'material-ui/Subheader';
import { GridList, GridTile } from 'material-ui/GridList';
import Paper from 'material-ui/Paper';
import ReactList from 'react-list';
import { browserHistory } from 'react-router';

import * as Colors from 'material-ui/styles/colors';
import * as Helper from '../../../util/helper';
import * as GiveawaysHelper from '../../../util/giveaways';
import * as AvatarHelper from '../../../util/avatar';
import * as IconsHelper from '../../../util/icons';

let giveaways = [];
let props = {};

const photoAvatar = (ga) => (

);

const iconAvatar = (ga) => (

    { GiveawaysHelper.getCategoryIcon(ga, { color: Colors.grey50 }) }

);

const listItemRow = (ga) => (
  <Paper key={ ga._id } style={{ marginBottom: 20 }} className="giveaway giveaway-timeline-item" onTouchTap={ (event) => browserHistory.push('/giveaway/' + ga._id) }>

          { ga.avatarId ? photoAvatar(ga) : iconAvatar(ga) }

{ ga.title }

{ GiveawaysHelper.categoryBreadcrumbs(ga) }

{ GiveawaysHelper.descriptionTruncate(ga) }

{ GiveawaysHelper.compactDateRange(ga) }

            { IconsHelper.icon("fa fa-thumbs-o-up", { fontSize: 14, color: "#9e9e9e", lineHeight: "20px" }) } { GiveawaysHelper.countUpvotes(ga) }

            { IconsHelper.icon("fa fa-thumbs-o-down", { fontSize: 14, color: "#9e9e9e", lineHeight: "20px" }) } { GiveawaysHelper.countDownvotes(ga) }

  </Paper>
);

const gridItemTile = (ga) => (
  <GridTile
    key={ ga._id }
    className="giveaway giveaway-timeline-item"
    title={ ga.title }
    titleBackground='rgba(0, 0, 0, 0.55)'
    subtitle={ GiveawaysHelper.descriptionFirstLine(ga) }>
    { ga.avatarId ? photoAvatar(ga) : iconAvatar(ga) }
  </GridTile>
);

const renderItem = (index, key) => {
  if (props.view == "list")
    return listItemRow(giveaways[index]);
  else
    return gridItemTile(giveaways[index]);
};

export class TimelineItems extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      gridListCols: 2,
      gridListCellHeight: 768
    };
  }

  componentDidMount() {
    $(window).resize(event => {
      this.setState({
        gridListCols: $(window).width() < 768 ? 2 : 4,
        gridListCellHeight: $(window).width() < 768 ? 180 : 250
      });
    }).resize();
  }

  render() {
    props = this.props.props;
    giveaways = this.props.giveaways;

    if (props.view == "list")
      return (

          <ReactList
            itemRenderer={ renderItem }
            length={ giveaways.length }
            type='variable'
          />

      );

    else
      return (

          <GridList cols={ this.state.gridListCols } cellHeight={ this.state.gridListCellHeight }>
            { giveaways.map(ga => gridItemTile(ga)) }
          </GridList>

      );
  }
}
<commit_msg>Fixed setState on unmounted component warning<commit_after>import React from 'react';
import Subheader from 'material-ui/Subheader';
import { GridList, GridTile } from 'material-ui/GridList';
import Paper from 'material-ui/Paper';
import ReactList from 'react-list';
import { browserHistory } from 'react-router';

import * as Colors from 'material-ui/styles/colors';
import * as Helper from '../../../util/helper';
import * as GiveawaysHelper from '../../../util/giveaways';
import * as AvatarHelper from '../../../util/avatar';
import * as IconsHelper from '../../../util/icons';

let giveaways = [];
let props = {};

const photoAvatar = (ga) => (

);

const iconAvatar = (ga) => (

    { GiveawaysHelper.getCategoryIcon(ga, { color: Colors.grey50 }) }

);

const listItemRow = (ga) => (
  <Paper key={ ga._id } style={{ marginBottom: 20 }} className="giveaway giveaway-timeline-item" onTouchTap={ (event) => browserHistory.push('/giveaway/' + ga._id) }>

          { ga.avatarId ? photoAvatar(ga) : iconAvatar(ga) }

{ ga.title }

{ GiveawaysHelper.categoryBreadcrumbs(ga) }

{ GiveawaysHelper.descriptionTruncate(ga) }

{ GiveawaysHelper.compactDateRange(ga) }

            { IconsHelper.icon("fa fa-thumbs-o-up", { fontSize: 14, color: "#9e9e9e", lineHeight: "20px" }) } { GiveawaysHelper.countUpvotes(ga) }

            { IconsHelper.icon("fa fa-thumbs-o-down", { fontSize: 14, color: "#9e9e9e", lineHeight: "20px" }) } { GiveawaysHelper.countDownvotes(ga) }

  </Paper>
);

const gridItemTile = (ga) => (
  <GridTile
    key={ ga._id }
    className="giveaway giveaway-timeline-item"
    title={ ga.title }
    titleBackground='rgba(0, 0, 0, 0.55)'
    subtitle={ GiveawaysHelper.descriptionFirstLine(ga) }>
    { ga.avatarId ? photoAvatar(ga) : iconAvatar(ga) }
  </GridTile>
);

const renderItem = (index, key) => {
  if (props.view == "list")
    return listItemRow(giveaways[index]);
  else
    return gridItemTile(giveaways[index]);
};

export class TimelineItems extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      gridListCols: 2,
      gridListCellHeight: 768
    };

    this.windowResizeHandler = (event) => {
      this.setState({
        gridListCols: $(window).width() < 768 ? 2 : 4,
        gridListCellHeight: $(window).width() < 768 ? 180 : 250
      });
    };
  }

  componentDidMount() {
    $(window).bind('resize', this.windowResizeHandler).resize();
  }

  componentWillUnmount() {
    $(window).unbind('resize', this.windowResizeHandler);
  }

  render() {
    props = this.props.props;
    giveaways = this.props.giveaways;

    if (props.view == "list")
      return (

          <ReactList
            itemRenderer={ renderItem }
            length={ giveaways.length }
            type='variable'
          />

      );

    else
      return (

          <GridList cols={ this.state.gridListCols } cellHeight={ this.state.gridListCellHeight }>
            { giveaways.map(ga => gridItemTile(ga)) }
          </GridList>

      );
  }
}
<|endoftext|>


<commit_before>(function() {

  function strain(parent) {
    function type() {
      return type._invoke_.apply(type, arguments);
    }

    parent = parent || function() {};
    inherit(type, parent);
    extend(type, strain);
    extend(type, parent);

    var props = type._props_ || {};
    type._props_ = {};

    for (var k in props) {
      type.prop(props[k]);
    }

    type._super_ = parent;
    type._currprop_ = null;
    type._strain_ = true;
    type._defaults_ = {};

    if (!parent._strain_) {
      extend(type.prototype, strain.prototype);
    } else {
      type._defaults_ = lazyExtend(type._defaults_, parent._defaults_);
    }

    return type;
  }

  strain.static = function(name, val) {
    if (typeof name == 'function') {
      val = name;
      name = val.name;
    }

    if (name === '') {
      throw new Error("no name provided for static value");
    }

    this[name] = typeof val == 'function'
      ? chained(val)
      : val;

    return this;
  };

  strain
    .static('_new_', function() {
      function instance() {
        return instance._invoke_.apply(instance, arguments);
      }

      extendAll(instance, this.prototype);
      instance._type_ = this;
      instance._props_ = {};

      var defaults = {};
      for (var k in this._props_) {
        defaults[k] = null;
      }

      defaults = extend(defaults, result(this._super_._defaults_, instance));
      extend(defaults, result(this._defaults_, instance));

      for (k in defaults) {
        instance[k](defaults[k]);
      }

      instance._init_.apply(instance, arguments);
      return instance;
    })

    .static('_invoke_', function() {
      return this._new_.apply(this, arguments);
    })

    .static('new', function() {
      return this._new_.apply(this, arguments);
    })

    .static('extend', function() {
      return strain(this);
    })

    .static('prop', function(propdef) {
      propdef = typeof propdef == 'string'
        ? {name: propdef}
        : propdef;

      this._currprop_ = this._props_[propdef.name];
      if (this._currprop_) { return; }

      propdef = this._currprop_ = this._props_[propdef.name] = extend({
        get: identity,
        set: identity
      }, propdef);

      this.prototype[propdef.name] = function() {
        if (!arguments.length) {
          return propdef.get.call(this, this._props_[propdef.name]);
        }

        var v = propdef.set.apply(this, arguments);
        this._props_[propdef.name] = typeof v == 'undefined'
          ? null
          : v;

        return this;
      };
    })

    .static('get', function(fn) {
      if (!this._currprop_) {
        throw new Error("can't use .get(), no property has been defined");
      }

      this._currprop_.get = fn;
    })

    .static('set', function(fn) {
      if (!this._currprop_) {
        throw new Error("can't use .set(), no property has been defined");
      }

      this._currprop_.set = fn;
    })

    .static('default', function(v) {
      var defaults = {};
      defaults[this._currprop_.name] = v;
      this._defaults_ = lazyExtend(this._defaults_, defaults);
    })

    .static('defaults', function(obj) {
      this._defaults_ = lazyExtend(this._defaults_, obj);
    })

    .static('meth', function(name, fn) {
      if (typeof name == 'function') {
        fn = name;
        name = fn.name;
      }

      if (name === '') {
        throw new Error("no name provided for method");
      }

      this.prototype[name] = chained(fn);
    })

    .static('instanceof', function(instance, type) {
      return ((instance || 0)._type_ || 0)._strain_
        ? instance.instanceof(type)
        : instance instanceof type;
    })

    .static('init', function(fn) {
      this.meth('_init_', fn);
    })

    .static('invoke', function(fn) {
      this.meth('_invoke_', fn);
    })

    .init(function() {})

    .invoke(function() {})

    .meth('instanceof', function(type) {
      return isa(this._type_, type);
    })

    .meth('prop', function(name) {
      if (!(name in this._props_)) {
        return null;
      }

      var args = Array.prototype.slice.call(arguments, 1);
      return this[name].apply(this, args);
    })

    .meth('props', function() {
      var result = {};

      for (var k in this._props_) {
        result[k] = this.prop(k);
      }

      return result;
    })

    .meth('toJSON', function() {
      return this.props();
    })

    .meth('invoke', function() {
      return this._invoke_.apply(this, arguments);
    });

  function extend(target, source) {
    for (var k in source) {
      if (source.hasOwnProperty(k)) {
        target[k] = source[k];
      }
    }

    return target;
  }

  function extendAll(target, source) {
    for (var k in source) {
      target[k] = source[k];
    }

    return target;
  }

  function lazyExtend(target, source, that) {
    that = that || this;

    return function() {
      return extend(result(target), result(source));
    };
  }

  function inherit(child, parent) {
    function surrogate() {}
    surrogate.prototype = parent.prototype;
    child.prototype = new surrogate();
    child.prototype.constructor = child;
    return child;
  }

  function isa(child, parent) {
    return child === parent
        || child.prototype instanceof parent;
  }

  function identity(v) {
    return v;
  }

  function chained(fn) {
    return function() {
      var result = fn.apply(this, arguments);

      return typeof result != 'undefined'
        ? result
        : this;
    };
  }

  function result(obj, that) {
    return typeof obj == 'function'
      ? obj.call(that || this)
      : obj;
  }

  if (typeof module != 'undefined') {
    module.exports = strain;
  }
  else if (typeof define == 'function' && define.amd) {
    define(function() {
      return strain;
    });
  }
  else {
    this.strain = strain;
  }
}).call(this);
<commit_msg>Update strain to 0.8.3<commit_after>(function() {
  function strain(parent) {
    function type() {
      return type._invoke_.apply(type, arguments);
    }

    parent = parent || function() {};
    inherit(type, parent);
    extend(type, strain);
    extend(type, parent);

    var propList = type._propList_ || [];
    type._props_ = {};
    type._propList_ = [];
    propList.forEach(type.prop, type);

    type._super_ = parent;
    type._currprop_ = null;
    type._strain_ = true;
    type._defaults_ = {};

    if (!parent._strain_) {
      extend(type.prototype, strain.prototype);
    } else {
      type._defaults_ = lazyExtend(type._defaults_, parent._defaults_);
    }

    return type;
  }

  strain.static = function(name, val) {
    if (typeof name == 'function') {
      val = name;
      name = val.name;
    }

    if (name === '') {
      throw new Error("no name provided for static value");
    }

    this[name] = typeof val == 'function'
      ? chained(val)
      : val;

    return this;
  };

  strain
    .static('_new_', function() {
      function instance() {
        return instance._invoke_.apply(instance, arguments);
      }

      extendAll(instance, this.prototype);
      instance._type_ = this;
      instance._props_ = {};

      var defaults = {};
      for (var k in this._props_) {
        defaults[k] = null;
      }

      defaults = extend(defaults, result(this._super_._defaults_, instance));
      extend(defaults, result(this._defaults_, instance));

      for (k in defaults) {
        instance[k](defaults[k]);
      }

      instance._init_.apply(instance, arguments);
      return instance;
    })

    .static('_invoke_', function() {
      return this._new_.apply(this, arguments);
    })

    .static('new', function() {
      return this._new_.apply(this, arguments);
    })

    .static('extend', function() {
      return strain(this);
    })

    .static('prop', function(propdef) {
      propdef = typeof propdef == 'string'
        ? {name: propdef}
        : propdef;

      this._currprop_ = this._props_[propdef.name];
      if (this._currprop_) { return; }

      propdef = extend({
        get: identity,
        set: identity
      }, propdef);

      this._currprop_ = propdef;
      this._props_[propdef.name] = propdef;
      this._propList_.push(propdef);

      this.prototype[propdef.name] = function() {
        if (!arguments.length) {
          return propdef.get.call(this, this._props_[propdef.name]);
        }

        var v = propdef.set.apply(this, arguments);
        this._props_[propdef.name] = typeof v == 'undefined'
          ? null
          : v;

        return this;
      };
    })

    .static('get', function(fn) {
      if (!this._currprop_) {
        throw new Error("can't use .get(), no property has been defined");
      }

      this._currprop_.get = fn;
    })

    .static('set', function(fn) {
      if (!this._currprop_) {
        throw new Error("can't use .set(), no property has been defined");
      }

      this._currprop_.set = fn;
    })

    .static('default', function(v) {
      var defaults = {};
      defaults[this._currprop_.name] = v;
      this._defaults_ = lazyExtend(this._defaults_, defaults);
    })

    .static('defaults', function(obj) {
      this._defaults_ = lazyExtend(this._defaults_, obj);
    })

    .static('meth', function(name, fn) {
      if (typeof name == 'function') {
        fn = name;
        name = fn.name;
      }

      if (name === '') {
        throw new Error("no name provided for method");
      }

      this.prototype[name] = chained(fn);
    })

    .static('instanceof', function(instance, type) {
      return ((instance || 0)._type_ || 0)._strain_
        ? instance.instanceof(type)
        : instance instanceof type;
    })

    .static('init', function(fn) {
      this.meth('_init_', fn);
    })

    .static('invoke', function(fn) {
      this.meth('_invoke_', fn);
    })

    .init(function() {})

    .invoke(function() {})

    .meth('instanceof', function(type) {
      return isa(this._type_, type);
    })

    .meth('prop', function(name) {
      if (!(name in this._props_)) {
        return null;
      }

      var args = Array.prototype.slice.call(arguments, 1);
      return this[name].apply(this, args);
    })

    .meth('props', function() {
      var result = {};

      for (var k in this._props_) {
        result[k] = this.prop(k);
      }

      return result;
    })

    .meth('toJSON', function() {
      return this.props();
    })

    .meth('invoke', function() {
      return this._invoke_.apply(this, arguments);
    });

  function extend(target, source) {
    for (var k in source) {
      if (source.hasOwnProperty(k)) {
        target[k] = source[k];
      }
    }

    return target;
  }

  function extendAll(target, source) {
    for (var k in source) {
      target[k] = source[k];
    }

    return target;
  }

  function lazyExtend(target, source, that) {
    return function() {
      return extend(
          result(target, that || this),
          result(source, that || this));
    };
  }

  function inherit(child, parent) {
    function surrogate() {}
    surrogate.prototype = parent.prototype;
    child.prototype = new surrogate();
    child.prototype.constructor = child;
    return child;
  }

  function isa(child, parent) {
    return child === parent
        || child.prototype instanceof parent;
  }

  function identity(v) {
    return v;
  }

  function chained(fn) {
    return function() {
      var result = fn.apply(this, arguments);

      return typeof result != 'undefined'
        ? result
        : this;
    };
  }

  function result(obj, that) {
    return typeof obj == 'function'
      ? obj.call(that || this)
      : obj;
  }

  if (typeof module != 'undefined') {
    module.exports = strain;
  }
  else if (typeof define == 'function' && define.amd) {
    define(function() {
      return strain;
    });
  }
  else {
    this.strain = strain;
  }
}).call(this);
<|endoftext|>


<commit_before>import React from "react";
import _ from "lodash";
// import {ReactSVGPanZoom} from 'react-svg-pan-zoom';
import * as globals from "./globals";
import graphUtil from "../util/graphUtil";

import Axes from "./graphAxes";
import Comments from "./graphComments";
import Participants from "./graphParticipants";
import Hulls from "./hull";
import BarChartForVotes from "./barChartsForGroupVotes";
import BarChart from "./barChart";

let ptptoiScaleFactor = 0.5;

class Graph extends React.Component {

  constructor(props) {
    super(props);
    this.Viewer = null;
    this.state = {
      selectedComment: null,
    };
  }

  componentWillMount() {
    console.log("graph mounted");
    document.getElementById("helpTextGroups").style.display = "none";
    document.getElementById("readReactView").style.display = "none";
    document.getElementById("visualization_div").style.display = "none";
    document.getElementById("carouselPane").style.display = "none";
    document.getElementsByClassName("groupSelectionView")[0].style.display = "none";
  }

  handleCommentHover(selectedComment) {
    return () => {
      this.setState({selectedComment});
    }
  }

  handleCommentClick(selectedComment) {
    return () => {
      this.setState({selectedComment});
    }
  }

  render() {

    if (!this.props.math) {
      return null;
    }

    let tidsToShowSet = _.keyBy(this.props.tidsToShow);

    let {
      xx,
      yy,
      commentsPoints,
      xCenter,
      yCenter,
      baseClustersScaled,
      commentScaleupFactorX,
      commentScaleupFactorY,
      hulls,
      groupCornerAssignments,
    } = graphUtil(this.props.comments, this.props.math, this.props.badTids);

    console.log(groupCornerAssignments);

    let should_only_show_voted_on_comments = false;

    commentsPoints = commentsPoints.filter((c) => {
      return !should_only_show_voted_on_comments || !_.isUndefined(tidsToShowSet[c.tid]);
    });
    let commentsToShow = this.props.comments.filter((c) => {
      return !should_only_show_voted_on_comments || !_.isUndefined(tidsToShowSet[c.tid]);
    });

    let heading = (
 Opinion Graph

        This graph shows all people and all comments.

        Comments, identified by their number, are positioned more closely to comments that were voted on similarly (blue, in the correlation matrix above). Comments are positioned further away from comments that tended to be voted on differently (red, in the correlation matrix above).

People are positioned closer to the comments on which they agreed, and further from the comments on which they disagreed. Groups of participants that tended to vote similarly across many comments (elaborated in the previous section) are identified by their similar color.

);

    return (

        {this.props.renderHeading ? heading : ""}
        <svg width="100%" height={globals.side}>

          {/* Comment https://bl.ocks.org/mbostock/7555321 */}
          <g transform={`translate(${globals.side / 2}, ${15})`}>
            <text
              style={{
                fontFamily: "Georgia",
                fontSize: 14,
                fontStyle: "italic"
              }}
              textAnchor="middle">

            </text>
          </g>
          <Axes xCenter={xCenter} yCenter={yCenter} report={this.props.report}/>
          <Hulls hulls={hulls} showOnlyGroup={this.props.showOnlyGroup} />
          <Participants points={baseClustersScaled} ptptois={this.props.ptptois} ptptoiScaleFactor={ptptoiScaleFactor}/>
          <Comments
            commentsPoints={commentsPoints}
            selectedComment={this.state.selectedComment}
            handleCommentHover={this.handleCommentHover.bind(this)}
            points={commentsPoints}
            repfulAgreeTidsByGroup={this.props.repfulAgreeTidsByGroup}
            repfulDisageeTidsByGroup={this.props.repfulDisageeTidsByGroup}
            showOnlyGroup={this.props.showOnlyGroup}
            xx={xx}
            yy={yy}
            xCenter={xCenter}
            yCenter={yCenter}
            xScaleup={commentScaleupFactorX}
            yScaleup={commentScaleupFactorY}
            formatTid={this.props.formatTid}/>
          <BarChartForVotes
            selectedComment={this.state.selectedComment}
            allComments={this.props.comments}
            groups={window.preload.firstMath["group-votes"]}
            groupCornerAssignments={groupCornerAssignments}
            />
        </svg>

            {this.state.selectedComment ? "#" + this.state.selectedComment.tid : null}

            {this.state.selectedComment ? this.state.selectedComment.txt : null}

TOTAL:

            <svg width={260} height={100}>
              <BarChart
                selectedComment={this.state.selectedComment}
                allComments={this.props.comments}
                groups={window.preload.firstMath["group-votes"]}
                />
            </svg>

 Comments:

              {commentsToShow.map((c) => { return (

                  {c.tid}

              )})}

    );
  }
}

export default Graph;

          // <defs>
          //   <marker
          //     className={'helpArrow'}
          //     id={'ArrowTip'}
          //     viewBox={'0 0 14 14'}
          //     refX={'1'
          //     refY={'5'}
          //     markerWidth={'5'}
          //     markerHeight={'5'}
          //     orient={'auto'}>
          //     // "<path d='M 0 0 L 10 5 L 0 10 z' />
          //     <circle cx = {'6'} cy = {'6'} r = {'5'} />
          //   </marker>
          //   <clipPath id={"clipCircleVis2"}>
          //     <circle r={ptptOiRadius * ptptoiScaleFactor} cx={0} cy={0}/>
          //   </clipPath>
          //   <filter id={'colorMeMatrix'}>
          //     <feColorMatrix
          //       in={'SourceGraphic'}
          //       type={'matrix'}
          //       values={'0.33 0.33 0.33 0 0
          //       0.33 0.33 0.33 0 0
          //       0.33 0.33 0.33 0 0
          //       0 0 0 1 0'} />
          //   </filter>

          //   <filter id={'colorMeMatrixRed'}
          //     <feColorMatrix
          //       in={'SourceGraphic'}
          //       type={'matrix'}
          //       values={'1.00 0.60 0.60 0 0.3
          //         0.10 0.20 0.10 0 0
          //         0.10 0.10 0.20 0 0
          //         0 0 0 1 0'} />
          //   </filter>

          //   <filter id={'colorMeMatrixGreen'}>
          //     <feColorMatrix
          //       in={'SourceGraphic'}
          //       type={'matrix'}
          //       values={'0.20 0.10 0.10 0 0
          //         0.60 1.00 0.60 0 0.3
          //         0.10 0.10 0.40 0 0
          //         0 0 0 1 0'} />
          //   </filter>
          // </defs>

// {/* this.props.math["group-clusters"].map((cluster, i) => {
//   return (<text x={300} y={300}> Renzi Supporters </text>)
// }) : null */}

// componentDidMount() {
//   this.Viewer.fitToViewer();
// }
//

//   <button onClick={event => this.Viewer.zoomOnViewerCenter(1.1)}>Zoom in</button>
//   <button onClick={event => this.Viewer.fitSelection(40, 40, 200, 200)}>Zoom area</button>
//   <button onClick={event => this.Viewer.fitToViewer()}>Fit</button>
//

// <ReactSVGPanZoom
//   style={{outline: "1px solid black", fill: "white"}}
//   width={500} height={500} ref={Viewer => this.Viewer = Viewer}
//   onClick={event => console.log('click', event.x, event.y, event.originalEvent)}
//   onMouseMove={event => console.log('move', event.x, event.y)} >
//
// </ReactSVGPanZoom>
<commit_msg>move markup out of graph, import back <commit_after>import React from "react";
import _ from "lodash";
// import {ReactSVGPanZoom} from 'react-svg-pan-zoom';
import * as globals from "./globals";
import graphUtil from "../util/graphUtil";

import Axes from "./graphAxes";
import Comments from "./graphComments";
import Participants from "./graphParticipants";
import Hulls from "./hull";
import BarChartsForGroupVotes from "./barChartsForGroupVotes";
import ExploreTid from "./exploreTid";
import TidCarousel from "./tidCarousel";
import Vote from "./voteView";

let ptptoiScaleFactor = 0.5;

class Graph extends React.Component {

  constructor(props) {
    super(props);
    this.Viewer = null;
    this.state = {
      selectedComment: null,
    };
  }

  componentWillMount() {
    console.log("graph mounted");
    document.getElementById("helpTextGroups").style.display = "none";
    document.getElementById("readReactView").style.display = "none";
    document.getElementById("visualization_div").style.display = "none";
    document.getElementById("carouselPane").style.display = "none";
    document.getElementsByClassName("groupSelectionView")[0].style.display = "none";
  }

  handleCommentHover(selectedComment) {
    return () => {
      this.setState({selectedComment});
    }
  }

  handleCommentClick(selectedComment) {
    return () => {
      this.setState({selectedComment});
    }
  }

  handleReturnToVoteClicked() {
    this.setState({selectedComment: null})
  }

  render() {

    if (!this.props.math) {
      return null;
    }

    let tidsToShowSet = _.keyBy(this.props.tidsToShow);

    let {
      xx,
      yy,
      commentsPoints,
      xCenter,
      yCenter,
      baseClustersScaled,
      commentScaleupFactorX,
      commentScaleupFactorY,
      hulls,
      groupCornerAssignments,
    } = graphUtil(this.props.comments, this.props.math, this.props.badTids);

    console.log(groupCornerAssignments);

    let should_only_show_voted_on_comments = false;

    commentsPoints = commentsPoints.filter((c) => {
      return !should_only_show_voted_on_comments || !_.isUndefined(tidsToShowSet[c.tid]);
    });
    let tidCarouselComments = this.props.comments.filter((c) => {
      return !should_only_show_voted_on_comments || !_.isUndefined(tidsToShowSet[c.tid]);
    });

    let heading = (
 Opinion Graph

        This graph shows all people and all comments.

        Comments, identified by their number, are positioned more closely to comments that were voted on similarly (blue, in the correlation matrix above). Comments are positioned further away from comments that tended to be voted on differently (red, in the correlation matrix above).

People are positioned closer to the comments on which they agreed, and further from the comments on which they disagreed. Groups of participants that tended to vote similarly across many comments (elaborated in the previous section) are identified by their similar color.

);

    return (

        {this.props.renderHeading ? heading : ""}
        {
          this.state.selectedComment ?
          <ExploreTid
            handleReturnToVoteClicked={this.handleReturnToVoteClicked.bind(this)}
            selectedComment={this.state.selectedComment}
            comments={this.props.comment}/> :
          <Vote
            />
        }
        <TidCarousel
          commentsToShow={tidCarouselComments}
          handleCommentClick={this.handleCommentClick.bind(this)}
          />
        <svg width="100%" height={globals.side}>

          {/* Comment https://bl.ocks.org/mbostock/7555321 */}
          <g transform={`translate(${globals.side / 2}, ${15})`}>
            <text
              style={{
                fontFamily: "Georgia",
                fontSize: 14,
                fontStyle: "italic"
              }}
              textAnchor="middle">

            </text>
          </g>
          <Axes xCenter={xCenter} yCenter={yCenter} report={this.props.report}/>
          <Hulls hulls={hulls} showOnlyGroup={this.props.showOnlyGroup} />
          <Participants points={baseClustersScaled} ptptois={this.props.ptptois} ptptoiScaleFactor={ptptoiScaleFactor}/>
          <Comments
            commentsPoints={commentsPoints}
            selectedComment={this.state.selectedComment}
            handleCommentHover={this.handleCommentHover.bind(this)}
            points={commentsPoints}
            repfulAgreeTidsByGroup={this.props.repfulAgreeTidsByGroup}
            repfulDisageeTidsByGroup={this.props.repfulDisageeTidsByGroup}
            showOnlyGroup={this.props.showOnlyGroup}
            xx={xx}
            yy={yy}
            xCenter={xCenter}
            yCenter={yCenter}
            xScaleup={commentScaleupFactorX}
            yScaleup={commentScaleupFactorY}
            formatTid={this.props.formatTid}/>
          <BarChartsForGroupVotes
            selectedComment={this.state.selectedComment}
            allComments={this.props.comments}
            groups={window.preload.firstMath["group-votes"]}
            groupCornerAssignments={groupCornerAssignments}
            />
        </svg>

    );
  }
}

export default Graph;

          // <defs>
          //   <marker
          //     className={'helpArrow'}
          //     id={'ArrowTip'}
          //     viewBox={'0 0 14 14'}
          //     refX={'1'
          //     refY={'5'}
          //     markerWidth={'5'}
          //     markerHeight={'5'}
          //     orient={'auto'}>
          //     // "<path d='M 0 0 L 10 5 L 0 10 z' />
          //     <circle cx = {'6'} cy = {'6'} r = {'5'} />
          //   </marker>
          //   <clipPath id={"clipCircleVis2"}>
          //     <circle r={ptptOiRadius * ptptoiScaleFactor} cx={0} cy={0}/>
          //   </clipPath>
          //   <filter id={'colorMeMatrix'}>
          //     <feColorMatrix
          //       in={'SourceGraphic'}
          //       type={'matrix'}
          //       values={'0.33 0.33 0.33 0 0
          //       0.33 0.33 0.33 0 0
          //       0.33 0.33 0.33 0 0
          //       0 0 0 1 0'} />
          //   </filter>

          //   <filter id={'colorMeMatrixRed'}
          //     <feColorMatrix
          //       in={'SourceGraphic'}
          //       type={'matrix'}
          //       values={'1.00 0.60 0.60 0 0.3
          //         0.10 0.20 0.10 0 0
          //         0.10 0.10 0.20 0 0
          //         0 0 0 1 0'} />
          //   </filter>

          //   <filter id={'colorMeMatrixGreen'}>
          //     <feColorMatrix
          //       in={'SourceGraphic'}
          //       type={'matrix'}
          //       values={'0.20 0.10 0.10 0 0
          //         0.60 1.00 0.60 0 0.3
          //         0.10 0.10 0.40 0 0
          //         0 0 0 1 0'} />
          //   </filter>
          // </defs>

// {/* this.props.math["group-clusters"].map((cluster, i) => {
//   return (<text x={300} y={300}> Renzi Supporters </text>)
// }) : null */}

// componentDidMount() {
//   this.Viewer.fitToViewer();
// }
//

//   <button onClick={event => this.Viewer.zoomOnViewerCenter(1.1)}>Zoom in</button>
//   <button onClick={event => this.Viewer.fitSelection(40, 40, 200, 200)}>Zoom area</button>
//   <button onClick={event => this.Viewer.fitToViewer()}>Fit</button>
//

// <ReactSVGPanZoom
//   style={{outline: "1px solid black", fill: "white"}}
//   width={500} height={500} ref={Viewer => this.Viewer = Viewer}
//   onClick={event => console.log('click', event.x, event.y, event.originalEvent)}
//   onMouseMove={event => console.log('move', event.x, event.y)} >
//
// </ReactSVGPanZoom>
<|endoftext|>


<commit_before>test(
  'CustomDefinitionTest',

  [
    'ephox.agar.api.RawAssertions',
    'ephox.alloy.behaviour.CustomBehaviour',
    'ephox.alloy.construct.ComponentDom',
    'ephox.alloy.construct.CustomDefinition',
    'ephox.alloy.dom.DomDefinition',
    'ephox.alloy.dom.DomModification',
    'ephox.alloy.test.ResultAssertions',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.ValueSchema',
    'ephox.peanut.Fun',
    'ephox.perhaps.Result'
  ],

  function (RawAssertions, CustomBehaviour, ComponentDom, CustomDefinition, DomDefinition, DomModification, ResultAssertions, FieldSchema, ValueSchema, Fun, Result) {
    var checkErr = function (label, expectedPart, spec) {
      ResultAssertions.checkErrStr(
        label,
        expectedPart,
        function () {
          return CustomDefinition.toInfo(spec).fold(
            function (errInfo) {
              return Result.error(ValueSchema.formatError(errInfo));
            }, Result.value
          );
        }
      );
    };

    var checkDomVal = function (label, expected, spec) {
      ResultAssertions.checkVal(label, function () {
        var info = CustomDefinition.toInfo(spec);
        return info.bind(function (inf) {
          var behaviours = CustomDefinition.behaviours(inf);

          var definition = CustomDefinition.toDefinition(inf);

          return ComponentDom.combine(inf, behaviours, definition).map(function (mod) {
            return DomModification.merge(definition, mod);
          });
        });
      }, function (value) {
        RawAssertions.assertEq(label, expected, DomDefinition.defToRaw(value));
      });
    };

    checkErr('Empty object', '*strict* value for "dom"', {});

    checkErr('Missing dom.tag', '*strict* value for "tag"', {
      dom: {

      }
    });

    checkErr('Missing components', '*strict* value for "components"', {
      dom: {
        tag: 'span'
      }
    });

    checkDomVal('Basics supplied', {
      tag: 'span',
      classes: [ ],
      attributes: { },
      styles: { },
      value: '<none>',
      innerHtml: '<none>',
      defChildren: '<none>',
      domChildren: '0 children, but still specified'
    }, {
      dom: {
        tag: 'span'
      },
      components: [ ]
    });

    checkDomVal('Basics supplied with behaviour that adds classes but does not use it', {
      tag: 'span',
      classes: [ ],
      attributes: { },
      styles: { },
      value: '<none>',
      innerHtml: '<none>',
      defChildren: '<none>',
      domChildren: '0 children, but still specified'
    }, {
      dom: {
        tag: 'span'
      },
      components: [ ],
      behaviours: [
        CustomBehaviour('behaviourA', {
          exhibit: function (info, base) {
            return DomModification.nu({
              classes: [ 'added-class-a' ]
            });
          },

          schema: Fun.constant(
            ValueSchema.objOf([
              FieldSchema.strict('a')
            ])
          )
        })
      ]
    });

    checkErr('Basics supplied with behaviour that adds classes and does have it but does not follow schema',
      '*strict* value for "a"',
      {
        dom: {
          tag: 'span'
        },
        components: [ ],
        behaviours: [
          CustomBehaviour('behaviourA', {
            exhibit: function (info, base) {
              return DomModification.nu({
                classes: [ 'added-class-a' ]
              });
            },

            schema: Fun.constant(
              ValueSchema.objOf([
                FieldSchema.strict('a')
              ])
            )
          })
        ],
        behaviourA: {

        }
      }
    );

    checkDomVal(
      'Basics supplied with behaviour that adds classes and activates it with correct schema',
      {
        tag: 'span',
        classes: [
          'added-class-a'
        ],
        attributes: {
          'data-alloy-id': 'id-custom-button-1'
        },
        styles: { },
        value: '<none>',
        innerHtml: '<none>',
        defChildren: '<none>',
        domChildren: '0 children, but still specified'
      }, {
        dom: {
          tag: 'span'
        },
        uid: 'id-custom-button-1',
        components: [ ],
        behaviours: [
          CustomBehaviour('behaviourA', {
            exhibit: function (info, base) {
              return DomModification.nu({
                classes: [ 'added-class-a' ]
              });
            },

            schema: Fun.constant(
              ValueSchema.objOf([
                FieldSchema.strict('a')
              ])
            )
          })
        ],
        'behaviourA': {
          a: true
        }
      }
    );

    // Add more tests.

  }

);<commit_msg>VAN-44-wheel-hackery-apis-2: custom definition error checking<commit_after>test(
  'CustomDefinitionTest',

  [
    'ephox.agar.api.RawAssertions',
    'ephox.alloy.behaviour.CustomBehaviour',
    'ephox.alloy.construct.ComponentDom',
    'ephox.alloy.construct.CustomDefinition',
    'ephox.alloy.dom.DomDefinition',
    'ephox.alloy.dom.DomModification',
    'ephox.alloy.test.ResultAssertions',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.ValueSchema',
    'ephox.peanut.Fun',
    'ephox.perhaps.Result'
  ],

  function (RawAssertions, CustomBehaviour, ComponentDom, CustomDefinition, DomDefinition, DomModification, ResultAssertions, FieldSchema, ValueSchema, Fun, Result) {
    var checkErr = function (label, expectedPart, spec) {
      ResultAssertions.checkErrStr(
        label,
        expectedPart,
        function () {
          return CustomDefinition.toInfo(spec).fold(
            function (errInfo) {
              var formatted = ValueSchema.formatError(errInfo);
              console.log('formatted', formatted);
              return Result.error(formatted);
            }, Result.value
          );
        }
      );
    };

    var checkDomVal = function (label, expected, spec) {
      ResultAssertions.checkVal(label, function () {
        var info = CustomDefinition.toInfo(spec);
        return info.bind(function (inf) {
          var behaviours = CustomDefinition.behaviours(inf);

          var definition = CustomDefinition.toDefinition(inf);

          return ComponentDom.combine(inf, behaviours, definition).map(function (mod) {
            return DomModification.merge(definition, mod);
          });
        }).fold(function (errInfo) {
          var formatted = ValueSchema.formatError(errInfo);
          console.log('formatted', formatted);
          return Result.error(formatted);
        }, Result.value);
      }, function (value) {
        RawAssertions.assertEq(label, expected, DomDefinition.defToRaw(value));
      });
    };

    checkErr('Empty object', '*strict* value for "dom"', {});

    checkErr('Missing dom.tag', '*strict* value for "tag"', {
      dom: {

      }
    });

    checkErr('Missing components', '*strict* value for "components"', {
      dom: {
        tag: 'span'
      }
    });

    checkDomVal('Basics supplied', {
      tag: 'span',
      classes: [ ],
      attributes: { },
      styles: { },
      value: '<none>',
      innerHtml: '<none>',
      defChildren: '<none>',
      domChildren: '0 children, but still specified'
    }, {
      dom: {
        tag: 'span'
      },
      components: [ ]
    });

    checkDomVal('Basics supplied with behaviour that adds classes but does not use it', {
      tag: 'span',
      classes: [ ],
      attributes: { },
      styles: { },
      value: '<none>',
      innerHtml: '<none>',
      defChildren: '<none>',
      domChildren: '0 children, but still specified'
    }, {
      dom: {
        tag: 'span'
      },
      components: [ ],
      behaviours: [
        CustomBehaviour('behaviourA', {
          exhibit: function (info, base) {
            return DomModification.nu({
              classes: [ 'added-class-a' ]
            });
          },

          schema: Fun.constant(
            ValueSchema.objOf([
              FieldSchema.strict('a')
            ])
          )
        })
      ]
    });

    checkErr('Basics supplied with behaviour that adds classes and does have it but does not follow schema',
      '*strict* value for "a"',
      {
        dom: {
          tag: 'span'
        },
        components: [ ],
        behaviours: [
          CustomBehaviour('behaviourA', {
            exhibit: function (info, base) {
              return DomModification.nu({
                classes: [ 'added-class-a' ]
              });
            },

            schema: Fun.constant(
              ValueSchema.objOf([
                FieldSchema.strict('a')
              ])
            )
          })
        ],
        behaviourA: {

        }
      }
    );

    checkDomVal(
      'Basics supplied with behaviour that adds classes and activates it with correct schema',
      {
        tag: 'span',
        classes: [
          'added-class-a'
        ],
        attributes: {
          'data-alloy-id': 'id-custom-button-1'
        },
        styles: { },
        value: '<none>',
        innerHtml: '<none>',
        defChildren: '<none>',
        domChildren: '0 children, but still specified'
      }, {
        dom: {
          tag: 'span'
        },
        uid: 'id-custom-button-1',
        components: [ ],
        behaviours: [
          CustomBehaviour('behaviourA', {
            exhibit: function (info, base) {
              return DomModification.nu({
                classes: [ 'added-class-a' ]
              });
            },

            schema: Fun.constant(
              ValueSchema.objOf([
                FieldSchema.strict('a')
              ])
            )
          })
        ],
        'behaviourA': {
          a: true
        }
      }
    );

    // Add more tests.

  }

);<|endoftext|>


<commit_before>asynctest(
  'MenuKeyingTest',

  [
    'ephox.agar.api.FocusTools',
    'ephox.agar.api.GeneralSteps',
    'ephox.agar.api.Keyboard',
    'ephox.agar.api.Keys',
    'ephox.agar.api.Step',
    'ephox.alloy.api.GuiFactory',
    'ephox.alloy.test.GuiSetup',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option'
  ],

  function (FocusTools, GeneralSteps, Keyboard, Keys, Step, GuiFactory, GuiSetup, Fun, Option) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];

    GuiSetup.setup(function (store, doc, body) {
      var handle = function (f) {
        return Fun.compose(function () {
          return Option.some(true);
        }, f);
      };

      var makeItem = function (name) {
        return {
          uiType: 'custom',
          dom: {
            tag: 'div',
            classes: [ 'test-item', name ],
            innerHtml: name
          },
          focusing: true
        };
      };

      return GuiFactory.build({
        uiType: 'custom',
        dom: {
          tag: 'div',
          classes: [ 'menu-keying-test'],
          styles: {

          }
        },
        uid: 'custom-uid',
        keying: {
          mode: 'menu',
          selector: '.test-item',
          onEscape: handle(store.adder('detected.escape')),
          onRight: handle(store.adder('detected.right')),
          onLeft: handle(store.adder('detected.left')),
          moveOnTab: true
        },
        components: [
          makeItem('alpha'),
          makeItem('beta'),
          makeItem('gamma')
        ]
      });

    }, function (doc, body, gui, component, store) {
      var checkStore = function (label, steps, expected) {
        return GeneralSteps.sequence([
          store.sClear
        ].concat(steps).concat([
          store.sAssertEq(label, expected)
        ]));
      };

      return [
        Step.sync(function () {
          component.apis().focusIn();
        }),

        FocusTools.sTryOnSelector('Focus should start on alpha', doc, '.alpha'),

        store.sAssertEq('Initially empty', [ ]),
        checkStore('pressing Escape', [
          Keyboard.sKeydown(doc, Keys.escape(), { })
        ], [ 'detected.escape' ]),

        checkStore('pressing left', [
          Keyboard.sKeydown(doc, Keys.left(), { })
        ], [ 'detected.left' ]),

        FocusTools.sTryOnSelector('Focus should still be on alpha', doc, '.alpha'),

        checkStore('pressing right', [
          Keyboard.sKeydown(doc, Keys.right(), { })
        ], [ 'detected.right' ]),

        FocusTools.sTryOnSelector('Focus should still be on alpha', doc, '.alpha'),

        checkStore('pressing tab', [
          Keyboard.sKeydown(doc, Keys.tab(), { })
        ], [ ]),
        FocusTools.sTryOnSelector('Focus should now be on beta', doc, '.beta'),

        checkStore('pressing tab', [
          Keyboard.sKeydown(doc, Keys.tab(), { })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on gamma', doc, '.gamma'),

        checkStore('pressing tab', [
          Keyboard.sKeydown(doc, Keys.tab(), { shift: true })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on beta', doc, '.beta'),
        // Basic tests
        checkStore('pressing up', [
          Keyboard.sKeydown(doc, Keys.up(), { })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on alpha', doc, '.alpha'),

        checkStore('pressing down', [
          Keyboard.sKeydown(doc, Keys.down(), { })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on beta', doc, '.beta'),

        checkStore('pressing enter', [
          Keyboard.sKeydown(doc, Keys.enter(), { })
        ], [ ])
      ];
    }, function () { success(); }, failure);

  }
);<commit_msg>VAN-44: removing comment<commit_after>asynctest(
  'MenuKeyingTest',

  [
    'ephox.agar.api.FocusTools',
    'ephox.agar.api.GeneralSteps',
    'ephox.agar.api.Keyboard',
    'ephox.agar.api.Keys',
    'ephox.agar.api.Step',
    'ephox.alloy.api.GuiFactory',
    'ephox.alloy.test.GuiSetup',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option'
  ],

  function (FocusTools, GeneralSteps, Keyboard, Keys, Step, GuiFactory, GuiSetup, Fun, Option) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];

    GuiSetup.setup(function (store, doc, body) {
      var handle = function (f) {
        return Fun.compose(function () {
          return Option.some(true);
        }, f);
      };

      var makeItem = function (name) {
        return {
          uiType: 'custom',
          dom: {
            tag: 'div',
            classes: [ 'test-item', name ],
            innerHtml: name
          },
          focusing: true
        };
      };

      return GuiFactory.build({
        uiType: 'custom',
        dom: {
          tag: 'div',
          classes: [ 'menu-keying-test'],
          styles: {

          }
        },
        uid: 'custom-uid',
        keying: {
          mode: 'menu',
          selector: '.test-item',
          onEscape: handle(store.adder('detected.escape')),
          onRight: handle(store.adder('detected.right')),
          onLeft: handle(store.adder('detected.left')),
          moveOnTab: true
        },
        components: [
          makeItem('alpha'),
          makeItem('beta'),
          makeItem('gamma')
        ]
      });

    }, function (doc, body, gui, component, store) {
      var checkStore = function (label, steps, expected) {
        return GeneralSteps.sequence([
          store.sClear
        ].concat(steps).concat([
          store.sAssertEq(label, expected)
        ]));
      };

      return [
        Step.sync(function () {
          component.apis().focusIn();
        }),

        FocusTools.sTryOnSelector('Focus should start on alpha', doc, '.alpha'),

        store.sAssertEq('Initially empty', [ ]),
        checkStore('pressing Escape', [
          Keyboard.sKeydown(doc, Keys.escape(), { })
        ], [ 'detected.escape' ]),

        checkStore('pressing left', [
          Keyboard.sKeydown(doc, Keys.left(), { })
        ], [ 'detected.left' ]),

        FocusTools.sTryOnSelector('Focus should still be on alpha', doc, '.alpha'),

        checkStore('pressing right', [
          Keyboard.sKeydown(doc, Keys.right(), { })
        ], [ 'detected.right' ]),

        FocusTools.sTryOnSelector('Focus should still be on alpha', doc, '.alpha'),

        checkStore('pressing tab', [
          Keyboard.sKeydown(doc, Keys.tab(), { })
        ], [ ]),
        FocusTools.sTryOnSelector('Focus should now be on beta', doc, '.beta'),

        checkStore('pressing tab', [
          Keyboard.sKeydown(doc, Keys.tab(), { })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on gamma', doc, '.gamma'),

        checkStore('pressing tab', [
          Keyboard.sKeydown(doc, Keys.tab(), { shift: true })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on beta', doc, '.beta'),

        checkStore('pressing up', [
          Keyboard.sKeydown(doc, Keys.up(), { })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on alpha', doc, '.alpha'),

        checkStore('pressing down', [
          Keyboard.sKeydown(doc, Keys.down(), { })
        ], [ ]),

        FocusTools.sTryOnSelector('Focus should now be on beta', doc, '.beta'),

        checkStore('pressing enter', [
          Keyboard.sKeydown(doc, Keys.enter(), { })
        ], [ ])
      ];
    }, function () { success(); }, failure);

  }
);<|endoftext|>


<commit_before>async function generatorBlobVideo(url, type, dom, link) {
  const headers = {
    responseType: 'arraybuffer',
  };
//   if(!type.includes('json')) {
//     headers.responseType = 'arraybuffer';
//   }
  // const headers = new Headers({
  //   'Content-Type': 'text/plain',
  //   'X-Custom-Header': 'ProcessThisImmediately',
  // });
  // const headers = new Headers();
  // headers.append('Content-Type', 'text/plain');
  // headers.append('X-Custom-Header', 'ProcessThisImmediately');
  // headers.set('Content-Type', 'text/html');
  // headers.has('X-Custom-Header');
  // headers.get('X-Custom-Header');
  // headers.delete('X-Custom-Header');
  // promise.then(res => res.json()).catch(err => {}).finally(() => {});
  // promise.then(res => res.arrayBuffer()).catch(err => {}).finally(() => {});
  const promise = await fetch(url, {
    // method: 'GET', // *GET, POST, PUT, DELETE, etc.
    // mode: 'cors', // no-cors, *cors, same-origin
    // cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    // credentials: 'same-origin',
    // credentials: 'include',
    method: 'GET',
    // mode: 'no-cors',
    // ❌  A no-cors request makes the response type opaque. Opaque means your frontend JavaScript code can’t see the response body or headers.
    // responseType: 'arraybuffer',
    // responseType: 'blob',
    ...headers,
    headers: {
      // 'Accept': type,
      'Content-Type': type,
      // 'Content-Type': 'application/octet-stream',
      // 'Accept': 'video/mp4',
      // 'Accept': 'application/json',
      // 'Content-Type': 'application/json;charset=utf-8'
      // 'Content-Type': 'application/json',
      // 'Content-Type': 'application/x-www-form-urlencoded',
      // ...headers,
    },
  }).then(res => {
    console.log('res =', res);
//     if(type.includes('json')) {
//       const json = res.json();
//       console.log('json =', json);
//       return json;
//     } else {
//       const buffer = res.arrayBuffer();
//       console.log('buffer =', buffer);
//       return buffer;
//     }
      return res.arrayBuffer();
  }).then(data => {
    console.log('data =', data);
    const blob = new Blob(
      [data],
      {'type' : type},
    );
    const urlBlob = URL.createObjectURL(blob);
    dom.src = urlBlob;
    link.href = urlBlob;
    if(type.includes('json')) {
      // 还原 blob
     const text = await (new Response(blob)).text();
     console.log('text =', text);
     link.innerText = text;
     const json = await (new Response(blob)).json();
     console.log('json =', json);
    } else {
      link.innerText = urlBlob;
    }
  }).catch(err => {}).finally(() => {});
  // .then(res => {
  //   // console.log('fetch.response =', res);
  //   const json = res.json();
  //   console.log('json =', json);
  //   const buffer = res.arrayBuffer();
  //   console.log('buffer =', buffer);
  //   // const buffer = res.blob();
  //   const blob = new Blob(
  //     [buffer],
  //     {'type' : type},
  //   );
  //   // const file = new File(buffer, 'test');
  //   const urlBlob = URL.createObjectURL(blob);
  //   dom.src = urlBlob;
  //   link.href = urlBlob;
  //   link.innerText = urlBlob;
  // }).catch(err => {}).finally(() => {});
  // url !== file
  // const blob = new Blob(
  //   [url],
  //   {'type' : type},
  // );
  // // const file = new File(buffer, 'test');
  // const urlBlob = URL.createObjectURL(blob);
  // dom.src = urlBlob;
  // link.href = urlBlob;
  // link.innerText = urlBlob;
}
(async function() {
  var type = 'application/json';
  var url = 'https://cdn.xgqfrms.xyz/json/honor.json';
  var dom = document.querySelector('#json');
  var link = document.querySelector('#json-link');
  // console.log('img link =', link);
  await generatorBlobVideo(url, type, dom, link);
})();
(async function() {
  var type = 'image/png';
  var url = 'https://cdn.xgqfrms.xyz/logo/icon.png';
  var dom = document.querySelector('#img');
  var link = document.querySelector('#img-link');
  // console.log('img link =', link);
  await generatorBlobVideo(url, type, dom, link);
})();
(async function() {
  var type = 'video/mp4';
  var url = 'https://cdn.xgqfrms.xyz/HTML5/Blob/2022-04-07-sh.mp4';
  var dom = document.querySelector('#video');
  var link = document.querySelector('#video-link');
  // console.log('video link =', link);
  setTimeout(() => {
    // Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
    // await generatorBlobVideo(url, type, dom, link);
    generatorBlobVideo(url, type, dom, link);
  }, 3000);
})();

/*

https://cdn.xgqfrms.xyz/HTML5/Blob/index.html

https://codepen.io/xgqfrms/pen/XWVYQPb

*/
<commit_msg> auto click<commit_after>async function generatorBlobVideo(url, type, dom, link, pre) {
  const headers = {
    responseType: 'arraybuffer',
  };
//   if(!type.includes('json')) {
//     headers.responseType = 'arraybuffer';
//   }
  // const headers = new Headers({
  //   'Content-Type': 'text/plain',
  //   'X-Custom-Header': 'ProcessThisImmediately',
  // });
  // const headers = new Headers();
  // headers.append('Content-Type', 'text/plain');
  // headers.append('X-Custom-Header', 'ProcessThisImmediately');
  // headers.set('Content-Type', 'text/html');
  // headers.has('X-Custom-Header');
  // headers.get('X-Custom-Header');
  // headers.delete('X-Custom-Header');
  // promise.then(res => res.json()).catch(err => {}).finally(() => {});
  // promise.then(res => res.arrayBuffer()).catch(err => {}).finally(() => {});
  const promise = await fetch(url, {
    // method: 'GET', // *GET, POST, PUT, DELETE, etc.
    // mode: 'cors', // no-cors, *cors, same-origin
    // cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    // credentials: 'same-origin',
    // credentials: 'include',
    method: 'GET',
    // mode: 'no-cors',
    // ❌  A no-cors request makes the response type opaque. Opaque means your frontend JavaScript code can’t see the response body or headers.
    // responseType: 'arraybuffer',
    // responseType: 'blob',
    ...headers,
    headers: {
      // 'Accept': type,
      'Content-Type': type,
      // 'Content-Type': 'application/octet-stream',
      // 'Accept': 'video/mp4',
      // 'Accept': 'application/json',
      // 'Content-Type': 'application/json;charset=utf-8'
      // 'Content-Type': 'application/json',
      // 'Content-Type': 'application/x-www-form-urlencoded',
      // ...headers,
    },
  }).then(res => {
    console.log('res =', res);
    if(type.includes('json')) {
      const json = res.json();
      console.log('res.json =', json);
      pre.innerText = JSON.stringify(json, null, 4);
      // return json;
    } else {
      // const buffer = res.arrayBuffer();
      // console.log('buffer =', buffer);
      // return buffer;
    }
      return res.arrayBuffer();
  }).then(data => {
    console.log('data =', data);
    const blob = new Blob(
      [data],
      {'type' : type},
    );
    const urlBlob = URL.createObjectURL(blob);
    dom.src = urlBlob;
    link.href = urlBlob;
    if(type.includes('json')) {
      // 还原 blob
     const text = await (new Response(blob)).text();
     console.log('text =', text);
     link.innerText = text;
     // auto click
     link.click();
     URL.revokeObjectURL(link.href);
     //
     try {
        const json = await (new Response(blob)).json();
        console.log('json =', json);
     } catch(err) {
        console.log('err =', err);
     }
    } else {
      link.innerText = urlBlob;
    }
  }).catch(err => {}).finally(() => {});
  // .then(res => {
  //   // console.log('fetch.response =', res);
  //   const json = res.json();
  //   console.log('json =', json);
  //   const buffer = res.arrayBuffer();
  //   console.log('buffer =', buffer);
  //   // const buffer = res.blob();
  //   const blob = new Blob(
  //     [buffer],
  //     {'type' : type},
  //   );
  //   // const file = new File(buffer, 'test');
  //   const urlBlob = URL.createObjectURL(blob);
  //   dom.src = urlBlob;
  //   link.href = urlBlob;
  //   link.innerText = urlBlob;
  // }).catch(err => {}).finally(() => {});
  // url !== file
  // const blob = new Blob(
  //   [url],
  //   {'type' : type},
  // );
  // // const file = new File(buffer, 'test');
  // const urlBlob = URL.createObjectURL(blob);
  // dom.src = urlBlob;
  // link.href = urlBlob;
  // link.innerText = urlBlob;
}
(async function() {
  var type = 'application/json';
  var url = 'https://cdn.xgqfrms.xyz/json/honor.json';
  var dom = document.querySelector('#json');
  var link = document.querySelector('#json-link');
  var pre = document.querySelector('#json-pre');
  // console.log('img link =', link);
  await generatorBlobVideo(url, type, dom, link, pre);
})();
(async function() {
  var type = 'image/png';
  var url = 'https://cdn.xgqfrms.xyz/logo/icon.png';
  var dom = document.querySelector('#img');
  var link = document.querySelector('#img-link');
  // console.log('img link =', link);
  await generatorBlobVideo(url, type, dom, link);
})();
(async function() {
  var type = 'video/mp4';
  var url = 'https://cdn.xgqfrms.xyz/HTML5/Blob/2022-04-07-sh.mp4';
  var dom = document.querySelector('#video');
  var link = document.querySelector('#video-link');
  // console.log('video link =', link);
  setTimeout(() => {
    // Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
    // await generatorBlobVideo(url, type, dom, link);
    generatorBlobVideo(url, type, dom, link);
  }, 3000);
})();

/*

https://cdn.xgqfrms.xyz/HTML5/Blob/index.html

https://codepen.io/xgqfrms/pen/XWVYQPb

*/
<|endoftext|>


<commit_before>var should = require('should');
var moment = require('moment-timezone');

describe('Profile', function ( ) {

  var profile_empty = require('../lib/profilefunctions')();

  it('should say it does not have data before it has data', function() {
    var hasData = profile_empty.hasData();
    hasData.should.equal(false);
  });

 it('should return undefined if asking for keys before init', function() {
    var dia = profile_empty.getDIA(now);
    should.not.exist(dia);
  });

  it('should return undefined if asking for missing keys', function() {
    var sens = profile_empty.getSensitivity(now);
    should.not.exist(sens);
  });

  var profileData = {
    'dia': 3
    , 'carbs_hr': 30
    , 'carbratio': 7
    , 'sens': 35
    , 'target_low': 95
    , 'target_high': 120
  };

  var profile = require('../lib/profilefunctions')([profileData]);
//  console.log(profile);

  var now = Date.now();

  it('should know what the DIA is with old style profiles', function() {
    var dia = profile.getDIA(now);
    dia.should.equal(3);
  });

  it('should know what the DIA is with old style profiles, with missing date argument', function() {
    var dia = profile.getDIA();
    dia.should.equal(3);
  });

  it('should know what the carbs_hr is with old style profiles', function() {
    var carbs_hr = profile.getCarbAbsorptionRate(now);
    carbs_hr.should.equal(30);
  });

  it('should know what the carbratio is with old style profiles', function() {
    var carbRatio = profile.getCarbRatio(now);
    carbRatio.should.equal(7);
  });

  it('should know what the sensitivity is with old style profiles', function() {
    var dia = profile.getSensitivity(now);
    dia.should.equal(35);
  });

  it('should know what the low target is with old style profiles', function() {
    var dia = profile.getLowBGTarget(now);
    dia.should.equal(95);
  });

  it('should know what the high target is with old style profiles', function() {
    var dia = profile.getHighBGTarget(now);
    dia.should.equal(120);
  });

  it('should know how to reload data and still know what the low target is with old style profiles', function() {

  var profileData2 = {
    'dia': 3,
    'carbs_hr': 30,
    'carbratio': 7,
    'sens': 35,
    'target_low': 50,
    'target_high': 120
  };

    profile.loadData([profileData2]);
    var dia = profile.getLowBGTarget(now);
    dia.should.equal(50);
  });

  var complexProfileData =
  {
    'timezone': moment.tz().zoneName(),  //Assume these are in the localtime zone so tests pass when not on UTC time
    'sens': [
        {
            'time': '00:00',
            'value': 10
        },
        {
            'time': '02:00',
            'value': 10
        },
        {
            'time': '07:00',
            'value': 9
        }
    ],
    'dia': 3,
    'carbratio': [
        {
            'time': '00:00',
            'value': 16
        },
        {
            'time': '06:00',
            'value': 15
        },
        {
            'time': '14:00',
            'value': 16
        }
    ],
    'carbs_hr': 30,
    'startDate': '2015-06-21',
    'basal': [
        {
            'time': '00:00',
            'value': 0.175
        },
        {
            'time': '02:30',
            'value': 0.125
        },
        {
            'time': '05:00',
            'value': 0.075
        },
        {
            'time': '08:00',
            'value': 0.1
        },
        {
            'time': '14:00',
            'value': 0.125
        },
        {
            'time': '20:00',
            'value': 0.3
        },
        {
            'time': '22:00',
            'value': 0.225
        }
    ],
    'target_low': 4.5,
    'target_high': 8,
    'units': 'mmol'
};

  var complexProfile = require('../lib/profilefunctions')([complexProfileData]);

  var noon = new Date('2015-06-22 12:00:00').getTime();
  var threepm = new Date('2015-06-22 15:00:00').getTime();

  it('should return profile units when configured', function() {
    var value = complexProfile.getUnits();
    value.should.equal('mmol');
  });

  it('should know what the basal rate is at 12:00 with complex style profiles', function() {
    var value = complexProfile.getBasal(noon);
    value.should.equal(0.1);
  });

  it('should know what the basal rate is at 15:00 with complex style profiles', function() {
    var value = complexProfile.getBasal(threepm);
    value.should.equal(0.125);
  });

  it('should know what the carbratio is at 12:00 with complex style profiles', function() {
    var carbRatio = complexProfile.getCarbRatio(noon);
    carbRatio.should.equal(15);
  });

  it('should know what the sensitivity is at 12:00 with complex style profiles', function() {
    var dia = complexProfile.getSensitivity(noon);
    dia.should.equal(9);
  });

});<commit_msg>use a differnt profile object to start with an empty cache<commit_after>var should = require('should');
var moment = require('moment-timezone');

describe('Profile', function ( ) {

  var profile_empty = require('../lib/profilefunctions')();

  it('should say it does not have data before it has data', function() {
    var hasData = profile_empty.hasData();
    hasData.should.equal(false);
  });

 it('should return undefined if asking for keys before init', function() {
    var dia = profile_empty.getDIA(now);
    should.not.exist(dia);
  });

  it('should return undefined if asking for missing keys', function() {
    var sens = profile_empty.getSensitivity(now);
    should.not.exist(sens);
  });

  var profileData = {
    'dia': 3
    , 'carbs_hr': 30
    , 'carbratio': 7
    , 'sens': 35
    , 'target_low': 95
    , 'target_high': 120
  };

  var profile = require('../lib/profilefunctions')([profileData]);
//  console.log(profile);

  var now = Date.now();

  it('should know what the DIA is with old style profiles', function() {
    var dia = profile.getDIA(now);
    dia.should.equal(3);
  });

  it('should know what the DIA is with old style profiles, with missing date argument', function() {
    var dia = profile.getDIA();
    dia.should.equal(3);
  });

  it('should know what the carbs_hr is with old style profiles', function() {
    var carbs_hr = profile.getCarbAbsorptionRate(now);
    carbs_hr.should.equal(30);
  });

  it('should know what the carbratio is with old style profiles', function() {
    var carbRatio = profile.getCarbRatio(now);
    carbRatio.should.equal(7);
  });

  it('should know what the sensitivity is with old style profiles', function() {
    var dia = profile.getSensitivity(now);
    dia.should.equal(35);
  });

  it('should know what the low target is with old style profiles', function() {
    var dia = profile.getLowBGTarget(now);
    dia.should.equal(95);
  });

  it('should know what the high target is with old style profiles', function() {
    var dia = profile.getHighBGTarget(now);
    dia.should.equal(120);
  });

  it('should know how to reload data and still know what the low target is with old style profiles', function() {

    var profile2 = require('../lib/profilefunctions')([profileData]);
    var profileData2 = {
      'dia': 3,
      'carbs_hr': 30,
      'carbratio': 7,
      'sens': 35,
      'target_low': 50,
      'target_high': 120
    };

    profile2.loadData([profileData2]);
    var dia = profile2.getLowBGTarget(now);
    dia.should.equal(50);
  });

  var complexProfileData =
  {
    'timezone': moment.tz().zoneName(),  //Assume these are in the localtime zone so tests pass when not on UTC time
    'sens': [
        {
            'time': '00:00',
            'value': 10
        },
        {
            'time': '02:00',
            'value': 10
        },
        {
            'time': '07:00',
            'value': 9
        }
    ],
    'dia': 3,
    'carbratio': [
        {
            'time': '00:00',
            'value': 16
        },
        {
            'time': '06:00',
            'value': 15
        },
        {
            'time': '14:00',
            'value': 16
        }
    ],
    'carbs_hr': 30,
    'startDate': '2015-06-21',
    'basal': [
        {
            'time': '00:00',
            'value': 0.175
        },
        {
            'time': '02:30',
            'value': 0.125
        },
        {
            'time': '05:00',
            'value': 0.075
        },
        {
            'time': '08:00',
            'value': 0.1
        },
        {
            'time': '14:00',
            'value': 0.125
        },
        {
            'time': '20:00',
            'value': 0.3
        },
        {
            'time': '22:00',
            'value': 0.225
        }
    ],
    'target_low': 4.5,
    'target_high': 8,
    'units': 'mmol'
};

  var complexProfile = require('../lib/profilefunctions')([complexProfileData]);

  var noon = new Date('2015-06-22 12:00:00').getTime();
  var threepm = new Date('2015-06-22 15:00:00').getTime();

  it('should return profile units when configured', function() {
    var value = complexProfile.getUnits();
    value.should.equal('mmol');
  });

  it('should know what the basal rate is at 12:00 with complex style profiles', function() {
    var value = complexProfile.getBasal(noon);
    value.should.equal(0.1);
  });

  it('should know what the basal rate is at 15:00 with complex style profiles', function() {
    var value = complexProfile.getBasal(threepm);
    value.should.equal(0.125);
  });

  it('should know what the carbratio is at 12:00 with complex style profiles', function() {
    var carbRatio = complexProfile.getCarbRatio(noon);
    carbRatio.should.equal(15);
  });

  it('should know what the sensitivity is at 12:00 with complex style profiles', function() {
    var dia = complexProfile.getSensitivity(noon);
    dia.should.equal(9);
  });

});<|endoftext|>


<commit_before>"use strict";
var util = exports;

// used to return a Promise where callback is omitted
util.asPromise = require("@protobufjs/aspromise");

// converts to / from base64 encoded strings
util.base64 = require("@protobufjs/base64");

// base class of rpc.Service
util.EventEmitter = require("@protobufjs/eventemitter");

// float handling accross browsers
util.float = require("@protobufjs/float");

// requires modules optionally and hides the call from bundlers
util.inquire = require("@protobufjs/inquire");

// converts to / from utf8 encoded strings
util.utf8 = require("@protobufjs/utf8");

// provides a node-like buffer pool in the browser
util.pool = require("@protobufjs/pool");

// utility to work with the low and high bits of a 64 bit value
util.LongBits = require("./longbits");

// global object reference
util.global = typeof window !== "undefined" && window
           || typeof global !== "undefined" && global
           || typeof self   !== "undefined" && self
           || this; // eslint-disable-line no-invalid-this

/**
 * An immuable empty array.
 * @memberof util
 * @type {Array.<*>}
 * @const
 */
util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes

/**
 * An immutable empty object.
 * @type {Object}
 * @const
 */
util.emptyObject = Object.freeze ? Object.freeze({}) : /* istanbul ignore next */ {}; // used on prototypes

/**
 * Whether running within node or not.
 * @memberof util
 * @type {boolean}
 * @const
 */
util.isNode = Boolean(process && process.versions && process.versions.node);

/**
 * Tests if the specified value is an integer.
 * @function
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is an integer
 */
util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) {
    return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};

/**
 * Tests if the specified value is a string.
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is a string
 */
util.isString = function isString(value) {
    return typeof value === "string" || value instanceof String;
};

/**
 * Tests if the specified value is a non-null object.
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is a non-null object
 */
util.isObject = function isObject(value) {
    return value && typeof value === "object";
};

/**
 * Checks if a property on a message is considered to be present.
 * This is an alias of {@link util.isSet}.
 * @function
 * @param {Object} obj Plain object or message instance
 * @param {string} prop Property name
 * @returns {boolean} `true` if considered to be present, otherwise `false`
 */
util.isset =

/**
 * Checks if a property on a message is considered to be present.
 * @param {Object} obj Plain object or message instance
 * @param {string} prop Property name
 * @returns {boolean} `true` if considered to be present, otherwise `false`
 */
util.isSet = function isSet(obj, prop) {
    var value = obj[prop];
    if (value != null && obj.hasOwnProperty(prop)) // eslint-disable-line eqeqeq, no-prototype-builtins
        return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
    return false;
};

/**
 * Any compatible Buffer instance.
 * This is a minimal stand-alone definition of a Buffer instance. The actual type is that exported by node's typings.
 * @interface Buffer
 * @extends Uint8Array
 */

/**
 * Node's Buffer class if available.
 * @type {Constructor<Buffer>}
 */
util.Buffer = (function() {
    try {
        var Buffer = util.inquire("buffer").Buffer;
        // refuse to use non-node buffers if not explicitly assigned (perf reasons):
        return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null;
    } catch (e) {
        /* istanbul ignore next */
        return null;
    }
})();

// Internal alias of or polyfull for Buffer.from.
util._Buffer_from = null;

// Internal alias of or polyfill for Buffer.allocUnsafe.
util._Buffer_allocUnsafe = null;

/**
 * Creates a new buffer of whatever type supported by the environment.
 * @param {number|number[]} [sizeOrArray=0] Buffer size or number array
 * @returns {Uint8Array|Buffer} Buffer
 */
util.newBuffer = function newBuffer(sizeOrArray) {
    /* istanbul ignore next */
    return typeof sizeOrArray === "number"
        ? util.Buffer
            ? util._Buffer_allocUnsafe(sizeOrArray)
            : new util.Array(sizeOrArray)
        : util.Buffer
            ? util._Buffer_from(sizeOrArray)
            : typeof Uint8Array === "undefined"
                ? sizeOrArray
                : new Uint8Array(sizeOrArray);
};

/**
 * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`.
 * @type {Constructor<Uint8Array>}
 */
util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array;

/**
 * Any compatible Long instance.
 * This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
 * @interface Long
 * @property {number} low Low bits
 * @property {number} high High bits
 * @property {boolean} unsigned Whether unsigned or not
 */

/**
 * Long.js's Long class if available.
 * @type {Constructor<Long>}
 */
util.Long = /* istanbul ignore next */ util.global.dcodeIO && /* istanbul ignore next */ util.global.dcodeIO.Long
         || /* istanbul ignore next */ util.global.Long
         || util.inquire("long");

/**
 * Regular expression used to verify 2 bit (`bool`) map keys.
 * @type {RegExp}
 * @const
 */
util.key2Re = /^true|false|0|1$/;

/**
 * Regular expression used to verify 32 bit (`int32` etc.) map keys.
 * @type {RegExp}
 * @const
 */
util.key32Re = /^-?(?:0|[1-9][0-9]*)$/;

/**
 * Regular expression used to verify 64 bit (`int64` etc.) map keys.
 * @type {RegExp}
 * @const
 */
util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;

/**
 * Converts a number or long to an 8 characters long hash string.
 * @param {Long|number} value Value to convert
 * @returns {string} Hash
 */
util.longToHash = function longToHash(value) {
    return value
        ? util.LongBits.from(value).toHash()
        : util.LongBits.zeroHash;
};

/**
 * Converts an 8 characters long hash string to a long or number.
 * @param {string} hash Hash
 * @param {boolean} [unsigned=false] Whether unsigned or not
 * @returns {Long|number} Original value
 */
util.longFromHash = function longFromHash(hash, unsigned) {
    var bits = util.LongBits.fromHash(hash);
    if (util.Long)
        return util.Long.fromBits(bits.lo, bits.hi, unsigned);
    return bits.toNumber(Boolean(unsigned));
};

/**
 * Merges the properties of the source object into the destination object.
 * @memberof util
 * @param {Object.<string,*>} dst Destination object
 * @param {Object.<string,*>} src Source object
 * @param {boolean} [ifNotSet=false] Merges only if the key is not already set
 * @returns {Object.<string,*>} Destination object
 */
function merge(dst, src, ifNotSet) { // used by converters
    for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
        if (dst[keys[i]] === undefined || !ifNotSet)
            dst[keys[i]] = src[keys[i]];
    return dst;
}

util.merge = merge;

/**
 * Converts the first character of a string to lower case.
 * @param {string} str String to convert
 * @returns {string} Converted string
 */
util.lcFirst = function lcFirst(str) {
    return str.charAt(0).toLowerCase() + str.substring(1);
};

/**
 * Creates a custom error constructor.
 * @memberof util
 * @param {string} name Error name
 * @returns {Constructor<Error>} Custom error constructor
 */
function newError(name) {

    function CustomError(message, properties) {

        if (!(this instanceof CustomError))
            return new CustomError(message, properties);

        // Error.call(this, message);
        // ^ just returns a new error instance because the ctor can be called as a function

        Object.defineProperty(this, "message", { get: function() { return message; } });

        /* istanbul ignore next */
        if (Error.captureStackTrace) // node
            Error.captureStackTrace(this, CustomError);
        else
            Object.defineProperty(this, "stack", { value: new Error().stack || "" });

        if (properties)
            merge(this, properties);
    }

    (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError;

    Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } });

    CustomError.prototype.toString = function toString() {
        return this.name + ": " + this.message;
    };

    return CustomError;
}

util.newError = newError;

/**
 * Constructs a new protocol error.
 * @classdesc Error subclass indicating a protocol specifc error.
 * @memberof util
 * @extends Error
 * @template T extends Message<T>
 * @constructor
 * @param {string} message Error message
 * @param {Object.<string,*>} [properties] Additional properties
 * @example
 * try {
 *     MyMessage.decode(someBuffer); // throws if required fields are missing
 * } catch (e) {
 *     if (e instanceof ProtocolError && e.instance)
 *         console.log("decoded so far: " + JSON.stringify(e.instance));
 * }
 */
util.ProtocolError = newError("ProtocolError");

/**
 * So far decoded message instance.
 * @name util.ProtocolError#instance
 * @type {Message<T>}
 */

/**
 * A OneOf getter as returned by {@link util.oneOfGetter}.
 * @typedef OneOfGetter
 * @type {function}
 * @returns {string|undefined} Set field name, if any
 */

/**
 * Builds a getter for a oneof's present field name.
 * @param {string[]} fieldNames Field names
 * @returns {OneOfGetter} Unbound getter
 */
util.oneOfGetter = function getOneOf(fieldNames) {
    var fieldMap = {};
    for (var i = 0; i < fieldNames.length; ++i)
        fieldMap[fieldNames[i]] = 1;

    /**
     * @returns {string|undefined} Set field name, if any
     * @this Object
     * @ignore
     */
    return function() { // eslint-disable-line consistent-return
        for (var keys = Object.keys(this), i = keys.length - 1; i > -1; --i)
            if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null)
                return keys[i];
    };
};

/**
 * A OneOf setter as returned by {@link util.oneOfSetter}.
 * @typedef OneOfSetter
 * @type {function}
 * @param {string|undefined} value Field name
 * @returns {undefined}
 */

/**
 * Builds a setter for a oneof's present field name.
 * @param {string[]} fieldNames Field names
 * @returns {OneOfSetter} Unbound setter
 */
util.oneOfSetter = function setOneOf(fieldNames) {

    /**
     * @param {string} name Field name
     * @returns {undefined}
     * @this Object
     * @ignore
     */
    return function(name) {
        for (var i = 0; i < fieldNames.length; ++i)
            if (fieldNames[i] !== name)
                delete this[fieldNames[i]];
    };
};

/**
 * Default conversion options used for {@link Message#toJSON} implementations.
 *
 * These options are close to proto3's JSON mapping with the exception that internal types like Any are handled just like messages. More precisely:
 *
 * - Longs become strings
 * - Enums become string keys
 * - Bytes become base64 encoded strings
 * - (Sub-)Messages become plain objects
 * - Maps become plain objects with all string keys
 * - Repeated fields become arrays
 * - NaN and Infinity for float and double fields become strings
 *
 * @type {IConversionOptions}
 * @see https://developers.google.com/protocol-buffers/docs/proto3?hl=en#json
 */
util.toJSONOptions = {
    longs: String,
    enums: String,
    bytes: String,
    json: true
};

// Sets up buffer utility according to the environment (called in index-minimal)
util._configure = function() {
    var Buffer = util.Buffer;
    /* istanbul ignore if */
    if (!Buffer) {
        util._Buffer_from = util._Buffer_allocUnsafe = null;
        return;
    }
    // because node 4.x buffers are incompatible & immutable
    // see: https://github.com/dcodeIO/protobuf.js/pull/665
    util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from ||
        /* istanbul ignore next */
        function Buffer_from(value, encoding) {
            return new Buffer(value, encoding);
        };
    util._Buffer_allocUnsafe = Buffer.allocUnsafe ||
        /* istanbul ignore next */
        function Buffer_allocUnsafe(size) {
            return new Buffer(size);
        };
};
<commit_msg>fix: do not fail if no process (#1440)<commit_after>"use strict";
var util = exports;

// used to return a Promise where callback is omitted
util.asPromise = require("@protobufjs/aspromise");

// converts to / from base64 encoded strings
util.base64 = require("@protobufjs/base64");

// base class of rpc.Service
util.EventEmitter = require("@protobufjs/eventemitter");

// float handling accross browsers
util.float = require("@protobufjs/float");

// requires modules optionally and hides the call from bundlers
util.inquire = require("@protobufjs/inquire");

// converts to / from utf8 encoded strings
util.utf8 = require("@protobufjs/utf8");

// provides a node-like buffer pool in the browser
util.pool = require("@protobufjs/pool");

// utility to work with the low and high bits of a 64 bit value
util.LongBits = require("./longbits");

// global object reference
util.global = typeof window !== "undefined" && window
           || typeof global !== "undefined" && global
           || typeof self   !== "undefined" && self
           || this; // eslint-disable-line no-invalid-this

/**
 * An immuable empty array.
 * @memberof util
 * @type {Array.<*>}
 * @const
 */
util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes

/**
 * An immutable empty object.
 * @type {Object}
 * @const
 */
util.emptyObject = Object.freeze ? Object.freeze({}) : /* istanbul ignore next */ {}; // used on prototypes

/**
 * Whether running within node or not.
 * @memberof util
 * @type {boolean}
 * @const
 */
util.isNode = Boolean(typeof process !== "undefined" && process &&
                      typeof process.versions !== "undefined" && process.versions &&
                      process.versions.node);

/**
 * Tests if the specified value is an integer.
 * @function
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is an integer
 */
util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) {
    return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};

/**
 * Tests if the specified value is a string.
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is a string
 */
util.isString = function isString(value) {
    return typeof value === "string" || value instanceof String;
};

/**
 * Tests if the specified value is a non-null object.
 * @param {*} value Value to test
 * @returns {boolean} `true` if the value is a non-null object
 */
util.isObject = function isObject(value) {
    return value && typeof value === "object";
};

/**
 * Checks if a property on a message is considered to be present.
 * This is an alias of {@link util.isSet}.
 * @function
 * @param {Object} obj Plain object or message instance
 * @param {string} prop Property name
 * @returns {boolean} `true` if considered to be present, otherwise `false`
 */
util.isset =

/**
 * Checks if a property on a message is considered to be present.
 * @param {Object} obj Plain object or message instance
 * @param {string} prop Property name
 * @returns {boolean} `true` if considered to be present, otherwise `false`
 */
util.isSet = function isSet(obj, prop) {
    var value = obj[prop];
    if (value != null && obj.hasOwnProperty(prop)) // eslint-disable-line eqeqeq, no-prototype-builtins
        return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
    return false;
};

/**
 * Any compatible Buffer instance.
 * This is a minimal stand-alone definition of a Buffer instance. The actual type is that exported by node's typings.
 * @interface Buffer
 * @extends Uint8Array
 */

/**
 * Node's Buffer class if available.
 * @type {Constructor<Buffer>}
 */
util.Buffer = (function() {
    try {
        var Buffer = util.inquire("buffer").Buffer;
        // refuse to use non-node buffers if not explicitly assigned (perf reasons):
        return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null;
    } catch (e) {
        /* istanbul ignore next */
        return null;
    }
})();

// Internal alias of or polyfull for Buffer.from.
util._Buffer_from = null;

// Internal alias of or polyfill for Buffer.allocUnsafe.
util._Buffer_allocUnsafe = null;

/**
 * Creates a new buffer of whatever type supported by the environment.
 * @param {number|number[]} [sizeOrArray=0] Buffer size or number array
 * @returns {Uint8Array|Buffer} Buffer
 */
util.newBuffer = function newBuffer(sizeOrArray) {
    /* istanbul ignore next */
    return typeof sizeOrArray === "number"
        ? util.Buffer
            ? util._Buffer_allocUnsafe(sizeOrArray)
            : new util.Array(sizeOrArray)
        : util.Buffer
            ? util._Buffer_from(sizeOrArray)
            : typeof Uint8Array === "undefined"
                ? sizeOrArray
                : new Uint8Array(sizeOrArray);
};

/**
 * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`.
 * @type {Constructor<Uint8Array>}
 */
util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array;

/**
 * Any compatible Long instance.
 * This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
 * @interface Long
 * @property {number} low Low bits
 * @property {number} high High bits
 * @property {boolean} unsigned Whether unsigned or not
 */

/**
 * Long.js's Long class if available.
 * @type {Constructor<Long>}
 */
util.Long = /* istanbul ignore next */ util.global.dcodeIO && /* istanbul ignore next */ util.global.dcodeIO.Long
         || /* istanbul ignore next */ util.global.Long
         || util.inquire("long");

/**
 * Regular expression used to verify 2 bit (`bool`) map keys.
 * @type {RegExp}
 * @const
 */
util.key2Re = /^true|false|0|1$/;

/**
 * Regular expression used to verify 32 bit (`int32` etc.) map keys.
 * @type {RegExp}
 * @const
 */
util.key32Re = /^-?(?:0|[1-9][0-9]*)$/;

/**
 * Regular expression used to verify 64 bit (`int64` etc.) map keys.
 * @type {RegExp}
 * @const
 */
util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;

/**
 * Converts a number or long to an 8 characters long hash string.
 * @param {Long|number} value Value to convert
 * @returns {string} Hash
 */
util.longToHash = function longToHash(value) {
    return value
        ? util.LongBits.from(value).toHash()
        : util.LongBits.zeroHash;
};

/**
 * Converts an 8 characters long hash string to a long or number.
 * @param {string} hash Hash
 * @param {boolean} [unsigned=false] Whether unsigned or not
 * @returns {Long|number} Original value
 */
util.longFromHash = function longFromHash(hash, unsigned) {
    var bits = util.LongBits.fromHash(hash);
    if (util.Long)
        return util.Long.fromBits(bits.lo, bits.hi, unsigned);
    return bits.toNumber(Boolean(unsigned));
};

/**
 * Merges the properties of the source object into the destination object.
 * @memberof util
 * @param {Object.<string,*>} dst Destination object
 * @param {Object.<string,*>} src Source object
 * @param {boolean} [ifNotSet=false] Merges only if the key is not already set
 * @returns {Object.<string,*>} Destination object
 */
function merge(dst, src, ifNotSet) { // used by converters
    for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
        if (dst[keys[i]] === undefined || !ifNotSet)
            dst[keys[i]] = src[keys[i]];
    return dst;
}

util.merge = merge;

/**
 * Converts the first character of a string to lower case.
 * @param {string} str String to convert
 * @returns {string} Converted string
 */
util.lcFirst = function lcFirst(str) {
    return str.charAt(0).toLowerCase() + str.substring(1);
};

/**
 * Creates a custom error constructor.
 * @memberof util
 * @param {string} name Error name
 * @returns {Constructor<Error>} Custom error constructor
 */
function newError(name) {

    function CustomError(message, properties) {

        if (!(this instanceof CustomError))
            return new CustomError(message, properties);

        // Error.call(this, message);
        // ^ just returns a new error instance because the ctor can be called as a function

        Object.defineProperty(this, "message", { get: function() { return message; } });

        /* istanbul ignore next */
        if (Error.captureStackTrace) // node
            Error.captureStackTrace(this, CustomError);
        else
            Object.defineProperty(this, "stack", { value: new Error().stack || "" });

        if (properties)
            merge(this, properties);
    }

    (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError;

    Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } });

    CustomError.prototype.toString = function toString() {
        return this.name + ": " + this.message;
    };

    return CustomError;
}

util.newError = newError;

/**
 * Constructs a new protocol error.
 * @classdesc Error subclass indicating a protocol specifc error.
 * @memberof util
 * @extends Error
 * @template T extends Message<T>
 * @constructor
 * @param {string} message Error message
 * @param {Object.<string,*>} [properties] Additional properties
 * @example
 * try {
 *     MyMessage.decode(someBuffer); // throws if required fields are missing
 * } catch (e) {
 *     if (e instanceof ProtocolError && e.instance)
 *         console.log("decoded so far: " + JSON.stringify(e.instance));
 * }
 */
util.ProtocolError = newError("ProtocolError");

/**
 * So far decoded message instance.
 * @name util.ProtocolError#instance
 * @type {Message<T>}
 */

/**
 * A OneOf getter as returned by {@link util.oneOfGetter}.
 * @typedef OneOfGetter
 * @type {function}
 * @returns {string|undefined} Set field name, if any
 */

/**
 * Builds a getter for a oneof's present field name.
 * @param {string[]} fieldNames Field names
 * @returns {OneOfGetter} Unbound getter
 */
util.oneOfGetter = function getOneOf(fieldNames) {
    var fieldMap = {};
    for (var i = 0; i < fieldNames.length; ++i)
        fieldMap[fieldNames[i]] = 1;

    /**
     * @returns {string|undefined} Set field name, if any
     * @this Object
     * @ignore
     */
    return function() { // eslint-disable-line consistent-return
        for (var keys = Object.keys(this), i = keys.length - 1; i > -1; --i)
            if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null)
                return keys[i];
    };
};

/**
 * A OneOf setter as returned by {@link util.oneOfSetter}.
 * @typedef OneOfSetter
 * @type {function}
 * @param {string|undefined} value Field name
 * @returns {undefined}
 */

/**
 * Builds a setter for a oneof's present field name.
 * @param {string[]} fieldNames Field names
 * @returns {OneOfSetter} Unbound setter
 */
util.oneOfSetter = function setOneOf(fieldNames) {

    /**
     * @param {string} name Field name
     * @returns {undefined}
     * @this Object
     * @ignore
     */
    return function(name) {
        for (var i = 0; i < fieldNames.length; ++i)
            if (fieldNames[i] !== name)
                delete this[fieldNames[i]];
    };
};

/**
 * Default conversion options used for {@link Message#toJSON} implementations.
 *
 * These options are close to proto3's JSON mapping with the exception that internal types like Any are handled just like messages. More precisely:
 *
 * - Longs become strings
 * - Enums become string keys
 * - Bytes become base64 encoded strings
 * - (Sub-)Messages become plain objects
 * - Maps become plain objects with all string keys
 * - Repeated fields become arrays
 * - NaN and Infinity for float and double fields become strings
 *
 * @type {IConversionOptions}
 * @see https://developers.google.com/protocol-buffers/docs/proto3?hl=en#json
 */
util.toJSONOptions = {
    longs: String,
    enums: String,
    bytes: String,
    json: true
};

// Sets up buffer utility according to the environment (called in index-minimal)
util._configure = function() {
    var Buffer = util.Buffer;
    /* istanbul ignore if */
    if (!Buffer) {
        util._Buffer_from = util._Buffer_allocUnsafe = null;
        return;
    }
    // because node 4.x buffers are incompatible & immutable
    // see: https://github.com/dcodeIO/protobuf.js/pull/665
    util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from ||
        /* istanbul ignore next */
        function Buffer_from(value, encoding) {
            return new Buffer(value, encoding);
        };
    util._Buffer_allocUnsafe = Buffer.allocUnsafe ||
        /* istanbul ignore next */
        function Buffer_allocUnsafe(size) {
            return new Buffer(size);
        };
};
<|endoftext|>