<commit_before>import { Mongo } from 'meteor/mongo';
import SimpleSchema from 'simpl-schema';
import { GraphQLSchema } from './graphql.js';
import { Utils } from './utils.js';
import { runCallbacks } from './callbacks.js';

export const Collections = [];

SimpleSchema.extendOptions([
  'viewableBy',
  'insertableBy',
  'editableBy',
  'resolveAs',
]);

/**
 * @summary replacement for Collection2's attachSchema
 * @class Mongo.Collection
 */
Mongo.Collection.prototype.attachSchema = function (schemaOrFields) {
  if (schemaOrFields instanceof SimpleSchema) {
    this.simpleSchema = () => schemaOrFields;
  } else {
    this.simpleSchema().extend(schemaOrFields)
  }
}

/**
 * @summary Add an additional field (or an array of fields) to a schema.
 * @param {Object|Object[]} field
 */
Mongo.Collection.prototype.addField = function (fieldOrFieldArray) {

  const collection = this;
  const schema = collection.simpleSchema()._schema;
  const fieldSchema = {};

  const fieldArray = Array.isArray(fieldOrFieldArray) ? fieldOrFieldArray : [fieldOrFieldArray];

  // loop over fields and add them to schema (or extend existing fields)
  fieldArray.forEach(function (field) {
    const newField = {...schema[field.fieldName], ...field.fieldSchema};
    fieldSchema[field.fieldName] = newField;
  });

  // add field schema to collection schema
  collection.attachSchema(fieldSchema);
};

/**
 * @summary Remove a field from a schema.
 * @param {String} fieldName
 */
Mongo.Collection.prototype.removeField = function (fieldName) {

  var collection = this;
  var schema = _.omit(collection.simpleSchema()._schema, fieldName);

  // add field schema to collection schema
  collection.attachSchema(schema, {replace: true});
};

/**
 * @summary Add a default view function.
 * @param {Function} view
 */
Mongo.Collection.prototype.addDefaultView = function (view) {
  this.defaultView = view;
};

/**
 * @summary Add a named view function.
 * @param {String} viewName
 * @param {Function} view
 */
Mongo.Collection.prototype.addView = function (viewName, view) {
  this.views[viewName] = view;
};

// see https://github.com/dburles/meteor-collection-helpers/blob/master/collection-helpers.js
Mongo.Collection.prototype.helpers = function(helpers) {
  var self = this;

  if (self._transform && ! self._helpers)
    throw new Meteor.Error("Can't apply helpers to '" +
      self._name + "' a transform function already exists!");

  if (! self._helpers) {
    self._helpers = function Document(doc) { return _.extend(this, doc); };
    self._transform = function(doc) {
      return new self._helpers(doc);
    };
  }

  _.each(helpers, function(helper, key) {
    self._helpers.prototype[key] = helper;
  });
};

export const createCollection = options => {

  const {collectionName, typeName, schema, resolvers, mutations, generateGraphQLSchema = true, dbCollectionName } = options;

  // initialize new Mongo collection
  const collection = collectionName === 'Users' ? Meteor.users : new Mongo.Collection(dbCollectionName ? dbCollectionName : collectionName.toLowerCase());

  // decorate collection with options
  collection.options = options;

  // add typeName
  collection.typeName = typeName;

  // add views
  collection.views = [];

  if (schema) {
    // attach schema to collection
    collection.attachSchema(new SimpleSchema(schema));
  }

  // add collection to resolver context
  const context = {};
  context[Utils.capitalize(collectionName)] = collection;
  GraphQLSchema.addToContext(context);

  if (generateGraphQLSchema){

    // add collection to list of dynamically generated GraphQL schemas
    GraphQLSchema.addCollection(collection);

    // ------------------------------------- Queries -------------------------------- //

    if (resolvers) {
      const queryResolvers = {};
      // list
      if (resolvers.list) { // e.g. ""
        GraphQLSchema.addQuery(`${resolvers.list.name}(terms: JSON, offset: Int, limit: Int): [${typeName}]`);
        queryResolvers[resolvers.list.name] = resolvers.list.resolver.bind(resolvers.list);
      }
      // single
      if (resolvers.single) {
        GraphQLSchema.addQuery(`${resolvers.single.name}(documentId: String, slug: String): ${typeName}`);
        queryResolvers[resolvers.single.name] = resolvers.single.resolver.bind(resolvers.single);
      }
      // total
      if (resolvers.total) {
        GraphQLSchema.addQuery(`${resolvers.total.name}(terms: JSON): Int`);
        queryResolvers[resolvers.total.name] = resolvers.total.resolver;
      }
      GraphQLSchema.addResolvers({ Query: { ...queryResolvers } });
    }

    // ------------------------------------- Mutations -------------------------------- //

    if (mutations) {
      const mutationResolvers = {};
      // new
      if (mutations.new) { // e.g. "moviesNew(document: moviesInput) : Movie"
        GraphQLSchema.addMutation(`${mutations.new.name}(document: ${collectionName}Input) : ${typeName}`);
        mutationResolvers[mutations.new.name] = mutations.new.mutation.bind(mutations.new);
      }
      // edit
      if (mutations.edit) { // e.g. "moviesEdit(documentId: String, set: moviesInput, unset: moviesUnset) : Movie"
        GraphQLSchema.addMutation(`${mutations.edit.name}(documentId: String, set: ${collectionName}Input, unset: ${collectionName}Unset) : ${typeName}`);
        mutationResolvers[mutations.edit.name] = mutations.edit.mutation.bind(mutations.edit);
      }
      // remove
      if (mutations.remove) { // e.g. "moviesRemove(documentId: String) : Movie"
        GraphQLSchema.addMutation(`${mutations.remove.name}(documentId: String) : ${typeName}`);
        mutationResolvers[mutations.remove.name] = mutations.remove.mutation.bind(mutations.remove);
      }
      GraphQLSchema.addResolvers({ Mutation: { ...mutationResolvers } });
    }
  }

  // ------------------------------------- Parameters -------------------------------- //

  collection.getParameters = (terms = {}, apolloClient, currentUser) => {

    // console.log(terms)

    let parameters = {
      selector: {},
      options: {}
    };

    if (collection.defaultView) {
      parameters = Utils.deepExtend(true, parameters, collection.defaultView(terms, apolloClient));
    }

    // handle view option
    if (terms.view && collection.views[terms.view]) {
      const view = collection.views[terms.view];
      parameters = Utils.deepExtend(true, parameters, view(terms, apolloClient));
    }

    // iterate over posts.parameters callbacks
    parameters = runCallbacks(`${collectionName.toLowerCase()}.parameters`, parameters, _.clone(terms), apolloClient);

    // extend sort to sort posts by _id to break ties
    // NOTE: always do this last to avoid overriding another sort
    parameters = Utils.deepExtend(true, parameters, {options: {sort: {_id: -1}}});

    // limit number of items to 200
    parameters.options.limit = (terms.limit < 1 || terms.limit > 200) ? 200 : terms.limit;

    // limit fields to viewable fields
    if (currentUser) {
      parameters.options.fields = currentUser.getViewableFields(collection);
    }

    // console.log(parameters);

    return parameters;
  }

  Collections.push(collection);

  return collection;
}<commit_msg>don’t capitalize collection name<commit_after>import { Mongo } from 'meteor/mongo';
import SimpleSchema from 'simpl-schema';
import { GraphQLSchema } from './graphql.js';
import { Utils } from './utils.js';
import { runCallbacks } from './callbacks.js';

export const Collections = [];

SimpleSchema.extendOptions([
  'viewableBy',
  'insertableBy',
  'editableBy',
  'resolveAs',
]);

/**
 * @summary replacement for Collection2's attachSchema
 * @class Mongo.Collection
 */
Mongo.Collection.prototype.attachSchema = function (schemaOrFields) {
  if (schemaOrFields instanceof SimpleSchema) {
    this.simpleSchema = () => schemaOrFields;
  } else {
    this.simpleSchema().extend(schemaOrFields)
  }
}

/**
 * @summary Add an additional field (or an array of fields) to a schema.
 * @param {Object|Object[]} field
 */
Mongo.Collection.prototype.addField = function (fieldOrFieldArray) {

  const collection = this;
  const schema = collection.simpleSchema()._schema;
  const fieldSchema = {};

  const fieldArray = Array.isArray(fieldOrFieldArray) ? fieldOrFieldArray : [fieldOrFieldArray];

  // loop over fields and add them to schema (or extend existing fields)
  fieldArray.forEach(function (field) {
    const newField = {...schema[field.fieldName], ...field.fieldSchema};
    fieldSchema[field.fieldName] = newField;
  });

  // add field schema to collection schema
  collection.attachSchema(fieldSchema);
};

/**
 * @summary Remove a field from a schema.
 * @param {String} fieldName
 */
Mongo.Collection.prototype.removeField = function (fieldName) {

  var collection = this;
  var schema = _.omit(collection.simpleSchema()._schema, fieldName);

  // add field schema to collection schema
  collection.attachSchema(schema, {replace: true});
};

/**
 * @summary Add a default view function.
 * @param {Function} view
 */
Mongo.Collection.prototype.addDefaultView = function (view) {
  this.defaultView = view;
};

/**
 * @summary Add a named view function.
 * @param {String} viewName
 * @param {Function} view
 */
Mongo.Collection.prototype.addView = function (viewName, view) {
  this.views[viewName] = view;
};

// see https://github.com/dburles/meteor-collection-helpers/blob/master/collection-helpers.js
Mongo.Collection.prototype.helpers = function(helpers) {
  var self = this;

  if (self._transform && ! self._helpers)
    throw new Meteor.Error("Can't apply helpers to '" +
      self._name + "' a transform function already exists!");

  if (! self._helpers) {
    self._helpers = function Document(doc) { return _.extend(this, doc); };
    self._transform = function(doc) {
      return new self._helpers(doc);
    };
  }

  _.each(helpers, function(helper, key) {
    self._helpers.prototype[key] = helper;
  });
};

export const createCollection = options => {

  const {collectionName, typeName, schema, resolvers, mutations, generateGraphQLSchema = true, dbCollectionName } = options;

  // initialize new Mongo collection
  const collection = collectionName === 'Users' ? Meteor.users : new Mongo.Collection(dbCollectionName ? dbCollectionName : collectionName.toLowerCase());

  // decorate collection with options
  collection.options = options;

  // add typeName
  collection.typeName = typeName;

  // add views
  collection.views = [];

  if (schema) {
    // attach schema to collection
    collection.attachSchema(new SimpleSchema(schema));
  }

  // add collection to resolver context
  const context = {};
  context[collectionName] = collection;
  GraphQLSchema.addToContext(context);

  if (generateGraphQLSchema){

    // add collection to list of dynamically generated GraphQL schemas
    GraphQLSchema.addCollection(collection);

    // ------------------------------------- Queries -------------------------------- //

    if (resolvers) {
      const queryResolvers = {};
      // list
      if (resolvers.list) { // e.g. ""
        GraphQLSchema.addQuery(`${resolvers.list.name}(terms: JSON, offset: Int, limit: Int): [${typeName}]`);
        queryResolvers[resolvers.list.name] = resolvers.list.resolver.bind(resolvers.list);
      }
      // single
      if (resolvers.single) {
        GraphQLSchema.addQuery(`${resolvers.single.name}(documentId: String, slug: String): ${typeName}`);
        queryResolvers[resolvers.single.name] = resolvers.single.resolver.bind(resolvers.single);
      }
      // total
      if (resolvers.total) {
        GraphQLSchema.addQuery(`${resolvers.total.name}(terms: JSON): Int`);
        queryResolvers[resolvers.total.name] = resolvers.total.resolver;
      }
      GraphQLSchema.addResolvers({ Query: { ...queryResolvers } });
    }

    // ------------------------------------- Mutations -------------------------------- //

    if (mutations) {
      const mutationResolvers = {};
      // new
      if (mutations.new) { // e.g. "moviesNew(document: moviesInput) : Movie"
        GraphQLSchema.addMutation(`${mutations.new.name}(document: ${collectionName}Input) : ${typeName}`);
        mutationResolvers[mutations.new.name] = mutations.new.mutation.bind(mutations.new);
      }
      // edit
      if (mutations.edit) { // e.g. "moviesEdit(documentId: String, set: moviesInput, unset: moviesUnset) : Movie"
        GraphQLSchema.addMutation(`${mutations.edit.name}(documentId: String, set: ${collectionName}Input, unset: ${collectionName}Unset) : ${typeName}`);
        mutationResolvers[mutations.edit.name] = mutations.edit.mutation.bind(mutations.edit);
      }
      // remove
      if (mutations.remove) { // e.g. "moviesRemove(documentId: String) : Movie"
        GraphQLSchema.addMutation(`${mutations.remove.name}(documentId: String) : ${typeName}`);
        mutationResolvers[mutations.remove.name] = mutations.remove.mutation.bind(mutations.remove);
      }
      GraphQLSchema.addResolvers({ Mutation: { ...mutationResolvers } });
    }
  }

  // ------------------------------------- Parameters -------------------------------- //

  collection.getParameters = (terms = {}, apolloClient, currentUser) => {

    // console.log(terms)

    let parameters = {
      selector: {},
      options: {}
    };

    if (collection.defaultView) {
      parameters = Utils.deepExtend(true, parameters, collection.defaultView(terms, apolloClient));
    }

    // handle view option
    if (terms.view && collection.views[terms.view]) {
      const view = collection.views[terms.view];
      parameters = Utils.deepExtend(true, parameters, view(terms, apolloClient));
    }

    // iterate over posts.parameters callbacks
    parameters = runCallbacks(`${collectionName.toLowerCase()}.parameters`, parameters, _.clone(terms), apolloClient);

    // extend sort to sort posts by _id to break ties
    // NOTE: always do this last to avoid overriding another sort
    parameters = Utils.deepExtend(true, parameters, {options: {sort: {_id: -1}}});

    // limit number of items to 200
    parameters.options.limit = (terms.limit < 1 || terms.limit > 200) ? 200 : terms.limit;

    // limit fields to viewable fields
    if (currentUser) {
      parameters.options.fields = currentUser.getViewableFields(collection);
    }

    // console.log(parameters);

    return parameters;
  }

  Collections.push(collection);

  return collection;
}<|endoftext|>


<commit_before>angular
  .module('mwl.calendar.docs')
  .controller('RecurringEventsCtrl', function($scope, moment, calendarConfig) {

    var vm = this;

    vm.events = [];
    vm.calendarView = 'month';
    vm.viewDate = moment().toDate();
    vm.isCellOpen = true;

    $scope.$watchGroup([
      'vm.calendarView',
      'vm.viewDate'
    ], function() {

      // Use the rrule library to generate recurring events: https://github.com/jkbrzt/rrule
      var rule = new RRule({
        freq: RRule.WEEKLY,
        interval: 1,
        byweekday: [RRule.MO],
        dtstart: moment(vm.viewDate).startOf(vm.calendarView).toDate(),
        until: moment(vm.viewDate).endOf(vm.calendarView).toDate()
      });

      vm.events = [{
        title: 'Recurs monthly',
        color: calendarConfig.colorTypes.warning,
        startsAt: moment().toDate(),
        recursOn: 'month'
      }, {
        title: 'Recurs yearly',
        tcolor: calendarConfig.colorTypes.info,
        startsAt: moment().toDate(),
        recursOn: 'year'
      }];

      rule.all().forEach(function(date) {
        vm.events.push({
          title: 'Recurs weekly on mondays',
          color: calendarConfig.colorTypes.success,
          startsAt: new Date(date)
        });
      });

    });

  });
<commit_msg>docs: fix recurring events color<commit_after>angular
  .module('mwl.calendar.docs')
  .controller('RecurringEventsCtrl', function($scope, moment, calendarConfig) {

    var vm = this;

    vm.events = [];
    vm.calendarView = 'month';
    vm.viewDate = moment().toDate();
    vm.isCellOpen = true;

    $scope.$watchGroup([
      'vm.calendarView',
      'vm.viewDate'
    ], function() {

      // Use the rrule library to generate recurring events: https://github.com/jkbrzt/rrule
      var rule = new RRule({
        freq: RRule.WEEKLY,
        interval: 1,
        byweekday: [RRule.MO],
        dtstart: moment(vm.viewDate).startOf(vm.calendarView).toDate(),
        until: moment(vm.viewDate).endOf(vm.calendarView).toDate()
      });

      vm.events = [{
        title: 'Recurs monthly',
        color: calendarConfig.colorTypes.warning,
        startsAt: moment().toDate(),
        recursOn: 'month'
      }, {
        title: 'Recurs yearly',
        color: calendarConfig.colorTypes.info,
        startsAt: moment().toDate(),
        recursOn: 'year'
      }];

      rule.all().forEach(function(date) {
        vm.events.push({
          title: 'Recurs weekly on mondays',
          color: calendarConfig.colorTypes.success,
          startsAt: new Date(date)
        });
      });

    });

  });
<|endoftext|>


<commit_before>import React, { Fragment, useState, useEffect, useCallback } from 'react';
import Container from '@material-ui/core/Container';
import { makeStyles } from '@material-ui/core/styles';
import Router from 'next/router';
import { pushToDataLayer } from 'lib/gtm';
import AppHeader from './AppHeader';
import AppSidebar from './AppSidebar';
import AppFooter from './AppFooter';
import gql from 'graphql-tag';
import { useLazyQuery } from '@apollo/react-hooks';
import LoginModal from './LoginModal';
import fetchAPI from 'lib/fetchAPI';

const USER_QUERY = gql`
  query UserLevelQuery {
    GetUser {
      id
      name
      avatarUrl
      level
      points {
        total
        currentLevel
        nextLevel
      }
    }
  }
`;
const useStyles = makeStyles({
  container: {
    flex: 1,
  },
});

const apiLogout = () => {
  return fetchAPI('/logout').then(resp => resp.json());
};

function AppLayout({ children }) {
  const [isRouteChanging, setRouteChanging] = useState(false);
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [loginModalOpen, setLoginModalOpen] = useState(false);

  const [loadUser, { data, refetch }] = useLazyQuery(USER_QUERY);

  const toggleSidebar = useCallback(() => setSidebarOpen(open => !open), []);

  const openLoginModal = useCallback(() => setLoginModalOpen(true), []);

  const logout = useCallback(() => apiLogout().then(refetch), [refetch]);

  const classes = useStyles();

  // load user when first loaded
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => loadUser(), []);

  useEffect(() => {
    const handleRouteChangeStart = () => {
      setRouteChanging(true);
      pushToDataLayer({ event: 'routeChangeStart' });
    };
    const handleRouteChangeComplete = () => {
      setRouteChanging(false);
      pushToDataLayer({ event: 'routeChangeComplete' });
    };

    Router.events.on('routeChangeStart', handleRouteChangeStart);
    Router.events.on('routeChangeComplete', handleRouteChangeComplete);

    return () => {
      Router.events.off('routeChangeStart', handleRouteChangeStart);
      Router.events.off('routeChangeComplete', handleRouteChangeComplete);
    };
  }, []);

  return (
    <Fragment>
      <AppHeader
        user={data?.GetUser}
        showProgress={isRouteChanging}
        onMenuButtonClick={toggleSidebar}
        onLoginModalOpen={openLoginModal}
        onLogout={logout}
      />
      <AppSidebar
        open={sidebarOpen}
        toggle={setSidebarOpen}
        user={data?.GetUser}
        onLoginModalOpen={openLoginModal}
      />
      <Container className={classes.container}>{children}</Container>
      <AppFooter />
      {loginModalOpen && (
        <LoginModal onClose={() => setLoginModalOpen(false)} />
      )}
    </Fragment>
  );
}

export default AppLayout;
<commit_msg>[AppLayout] support no container layout<commit_after>import React, { Fragment, useState, useEffect, useCallback } from 'react';
import Container from '@material-ui/core/Container';
import { makeStyles } from '@material-ui/core/styles';
import Router from 'next/router';
import { pushToDataLayer } from 'lib/gtm';
import AppHeader from './AppHeader';
import AppSidebar from './AppSidebar';
import AppFooter from './AppFooter';
import gql from 'graphql-tag';
import { useLazyQuery } from '@apollo/react-hooks';
import LoginModal from './LoginModal';
import fetchAPI from 'lib/fetchAPI';

const USER_QUERY = gql`
  query UserLevelQuery {
    GetUser {
      id
      name
      avatarUrl
      level
      points {
        total
        currentLevel
        nextLevel
      }
    }
  }
`;
const useStyles = makeStyles({
  container: {
    flex: 1,
  },
});

const apiLogout = () => {
  return fetchAPI('/logout').then(resp => resp.json());
};

/**
 * @param {boolean} props.container - whether we should use container around children
 */
function AppLayout({ children, container = true }) {
  const [isRouteChanging, setRouteChanging] = useState(false);
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [loginModalOpen, setLoginModalOpen] = useState(false);

  const [loadUser, { data, refetch }] = useLazyQuery(USER_QUERY);

  const toggleSidebar = useCallback(() => setSidebarOpen(open => !open), []);

  const openLoginModal = useCallback(() => setLoginModalOpen(true), []);

  const logout = useCallback(() => apiLogout().then(refetch), [refetch]);

  const classes = useStyles();

  // load user when first loaded
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => loadUser(), []);

  useEffect(() => {
    const handleRouteChangeStart = () => {
      setRouteChanging(true);
      pushToDataLayer({ event: 'routeChangeStart' });
    };
    const handleRouteChangeComplete = () => {
      setRouteChanging(false);
      pushToDataLayer({ event: 'routeChangeComplete' });
    };

    Router.events.on('routeChangeStart', handleRouteChangeStart);
    Router.events.on('routeChangeComplete', handleRouteChangeComplete);

    return () => {
      Router.events.off('routeChangeStart', handleRouteChangeStart);
      Router.events.off('routeChangeComplete', handleRouteChangeComplete);
    };
  }, []);

  return (
    <Fragment>
      <AppHeader
        user={data?.GetUser}
        showProgress={isRouteChanging}
        onMenuButtonClick={toggleSidebar}
        onLoginModalOpen={openLoginModal}
        onLogout={logout}
      />
      <AppSidebar
        open={sidebarOpen}
        toggle={setSidebarOpen}
        user={data?.GetUser}
        onLoginModalOpen={openLoginModal}
      />
      {container ? (
        <Container className={classes.container}>{children}</Container>
      ) : (
        children
      )}
      <AppFooter />
      {loginModalOpen && (
        <LoginModal onClose={() => setLoginModalOpen(false)} />
      )}
    </Fragment>
  );
}

export default AppLayout;
<|endoftext|>


<commit_before>import React, {Component, PropTypes, findDOMNode} from 'react';

import {ownerDocument, calcOverlayPosition} from './positionUtils';
import {mountable} from '../../lib/customPropTypes';
import Portal from '../Portal/Portal';
import s from './HoverCard.css';

export default class HoverCard extends Component {

  // TODO
  // - Detect if it's outside the viewport

  constructor(props, context) {
    super(props, context);

    this.state = {
      positionLeft: null,
      positionTop: null,
      arrowOffsetLeft: null,
      arrowOffsetTop: null
    };
  }

  componentWillMount() {
    this._needsFlush = true;
  }

  componentWillReceiveProps() {
    this._needsFlush = true;
  }

  componentDidMount() {
    this._maybeUpdatePosition();
  }
  componentDidUpdate() {
    this._maybeUpdatePosition();
  }

  _maybeUpdatePosition() {
    if (this._needsFlush) {
      this._needsFlush = false;
      this._updatePosition();
    }
  }

  _updatePosition() {
    if (this.props.anchor === null) {
      return;
    }

    let target = findDOMNode(this.props.anchor);
    let container = findDOMNode(this.props.container) || ownerDocument(this).body;

    // Store the val of calcOverlayPosition
    // Perform logic to make sure the HoverCard is contained within the window
    // If not, try alternative placements until it fits

    this.setState(
      calcOverlayPosition(
        this.props.placement,
        findDOMNode(this.refs.self),
        target,
        container,
        this.props.anchorPadding
      )
    );
  }

  render() {
    const {
      positionLeft,
      positionTop,
      arrowOffsetLeft,
      arrowOffsetTop
    } = this.state;

    const {
      variant,
      placement,
      caret,
    } = this.props;

    const css = [
      s.root,
      s[variant],
      s[placement]
    ].join(' ');

    const outerStyle = {
      left: positionLeft,
      top: positionTop
    };

    const caretStyle = {
      left: arrowOffsetLeft,
      top: arrowOffsetTop
    };

    return (
      <Portal container={this.props.container}>

          {caret ?

            : null
          }

            {this.props.children}

      </Portal>
    );
  }
}

HoverCard.propTypes = {

  // The Component the HoverCard will be offset from
  container: PropTypes.any,

  // React Component to position the HoverCard relative to
  anchor: mountable,

  // Distance from the anchor in pixels
  anchorPadding: PropTypes.number,

  // Where to be positioned relative to the anchor
  placement: PropTypes.oneOf(['top', 'left', 'bottom', 'right']),

  // Variant that maps to a CSS classname
  variant: PropTypes.oneOf(['tooltip', 'dropdown', 'datepicker']).isRequired,

  // Show a caret or not
  caret: PropTypes.bool,

  // Make the card change it's `placement` to fit inside the window
  // reposition: PropTypes.bool,

  children: PropTypes.any.isRequired
};

HoverCard.defaultProps = {
  anchorPadding: 10,
  caret: true
};
<commit_msg>HoverCard ideal placement to fit on page WIP<commit_after>import React, {Component, PropTypes, findDOMNode} from 'react';

import {ownerDocument, calcOverlayPosition} from './positionUtils';
import {mountable} from '../../lib/customPropTypes';
import Portal from '../Portal/Portal';
import s from './HoverCard.css';

export default class HoverCard extends Component {

  // TODO
  // - Detect if it's outside the viewport

  constructor(props, context) {
    super(props, context);

    this.state = {
      placement: this.props.placement,
      positionLeft: null,
      positionTop: null,
      arrowOffsetLeft: null,
      arrowOffsetTop: null
    };
  }

  componentWillMount() {
    this._needsFlush = true;
  }

  componentWillReceiveProps() {
    this._needsFlush = true;
  }

  componentDidMount() {
    this._maybeUpdatePosition();
  }
  componentDidUpdate() {
    this._maybeUpdatePosition();
  }

  _maybeUpdatePosition() {
    if (this._needsFlush) {
      this._needsFlush = false;
      this._updatePosition();
    }
  }

  _updatePosition() {
    if (this.props.anchor === null) {
      return;
    }

    const {placement} = this.props;
    let target = findDOMNode(this.props.anchor);
    let container = findDOMNode(this.props.container) || ownerDocument(this).body;

    // Starting with the props.placement, try out each placement to find one
    // where the
    let idealPosition;
    let idealPlacement;
    let placements = ['top', 'left', 'bottom', 'right']
      .sort(function(a, b) {
        if (b === placement) return 1;
        return 0;
      });

    for (let i = 0; i < placements.length; i++) {
      idealPlacement = placements[i];
      idealPosition = calcOverlayPosition(
          idealPlacement,
          findDOMNode(this.refs.self),
          target,
          container,
          this.props.anchorPadding
        );
      if (idealPosition.positionLeft > -1 && idealPosition.positionTop > -1) {
        break;
      }
    }

    this.setState({
      placement: idealPlacement,
      ...idealPosition
    });
  }

  render() {
    const {
      placement,
      positionLeft,
      positionTop,
      arrowOffsetLeft,
      arrowOffsetTop
    } = this.state;

    const {
      variant,
      caret
    } = this.props;

    const css = [
      s.root,
      s[variant],
      s[placement]
    ].join(' ');

    const outerStyle = {
      left: positionLeft,
      top: positionTop
    };

    const caretStyle = {
      left: arrowOffsetLeft,
      top: arrowOffsetTop
    };

    return (
      <Portal container={this.props.container}>

          {caret ?

            : null
          }

            {this.props.children}

      </Portal>
    );
  }
}

HoverCard.propTypes = {

  // The Component the HoverCard will be offset from
  container: PropTypes.any,

  // React Component to position the HoverCard relative to
  anchor: mountable,

  // Distance from the anchor in pixels
  anchorPadding: PropTypes.number,

  // Where to be positioned relative to the anchor
  placement: PropTypes.oneOf(['top', 'left', 'bottom', 'right']),

  // Variant that maps to a CSS classname
  variant: PropTypes.oneOf(['tooltip', 'dropdown', 'datepicker']).isRequired,

  // Show a caret or not
  caret: PropTypes.bool,

  // Make the card change it's `placement` to fit inside the window
  // reposition: PropTypes.bool,

  children: PropTypes.any.isRequired
};

HoverCard.defaultProps = {
  anchorPadding: 10,
  caret: true
};
<|endoftext|>


<commit_before>'use babel';

export default {
  lint: {
    doc: 'Use tern-lint for this project.',
    definition: {}
  },
  complete_strings: {
    doc: 'When enabled, this plugin will gather (short) strings in your code, and completing when inside a string will try to complete to previously seen strings. Takes a single option, maxLength, which controls the maximum length of string values to gather, and defaults to 15.',
    definition: {
      maxLength: {
        doc: '',
        type: 'number'
      }
    }
  },
  doc_comment: {
    doc: 'This plugin, which is enabled by default in the bin/tern server, parses comments before function declarations, variable declarations, and object properties. It will look for JSDoc-style type declarations, and try to parse them and add them to the inferred types, and it will treat the first sentence of comment text as the docstring for the defined variable or property.',
    definition: {
      fullDocs: {
        doc: 'Can be set to true to return the full comment text instead of the first sentence.',
        type: 'boolean'
      },
      strong: {
        doc: 'When enabled, types specified in comments take precedence over inferred types.',
        type: 'boolean'
      }
    }
  },
  node: {
    doc: 'The node.js plugin, called \"node\", provides variables that are part of the node environment, such as process and __dirname, and loads the commonjs and node_resolve plugins to allow node-style module loading. It defines types for the built-in modules that node.js provides (\"fs\", \"http\", etc).',
    definition: {
      dontLoad: {
        doc: 'Can be set to true to disable dynamic loading of required modules entirely, or to a regular expression to disable loading of files that match the expression.',
        type: 'string'
      },
      load: {
        doc: 'If dontLoad isn’t given, this setting is checked. If it is a regular expression, the plugin will only load files that match the expression.',
        type: 'string'
      },
      modules: {
        doc: 'Can be used to assign JSON type definitions to certain modules, so that those are loaded instead of the source code itself. If given, should be an object mapping module names to either JSON objects defining the types in the module, or a string referring to a file name (relative to the project directory) that contains the JSON data.',
        type: 'string'
      }
    }
  },
  node_resolve: {
    doc: 'This is a supporting plugin to act as a dependency for other module-loading and module-resolving plugins. It understands the following configuration parameters:',
    definition: {}
  },
  modules: {
    doc: 'This plugin defines the node.js module resolution strategy—things like defaulting to index.js when requiring a directory and searching node_modules directories. It depends on the modules plugin. Note that this plugin only does something meaningful when the Tern server is running on node.js itself.',
    definition: {
      dontLoad: {
        doc: 'Can be set to true to disable dynamic loading of required modules entirely, or to a regular expression to disable loading of files that match the expression.',
        type: 'string'
      },
      load: {
        doc: 'If dontLoad isn’t given, this setting is checked. If it is a regular expression, the plugin will only load files that match the expression.',
        type: 'string'
      },
      modules: {
        doc: 'Can be used to assign JSON type definitions to certain modules, so that those are loaded instead of the source code itself. If given, should be an object mapping module names to either JSON objects defining the types in the module, or a string referring to a file name (relative to the project directory) that contains the JSON data.',
        type: 'string'
      }
    }
  },
  es_modules: {
    doc: 'This plugin (es_modules) builds on top of the modules plugin to support ECMAScript 6’s import and export based module inclusion.',
    definition: {}
  },
  angular: {
    doc: 'Adds the angular object to the top-level environment, and tries to wire up some of the bizarre dependency management scheme from this library, so that dependency injections get the right types. Enabled with the name \"angular\".',
    definition: {}
  },
  requirejs: {
    doc: 'This plugin (\"requirejs\") teaches the server to understand RequireJS-style dependency management. It defines the global functions define and requirejs, and will do its best to resolve dependencies and give them their proper types.',
    defintions: {
      baseURL: {
        doc: 'The base path to prefix to dependency filenames.',
        type: 'string'
      },
      paths: {
        doc: 'An object mapping filename prefixes to specific paths. For example {\"acorn\": \"lib/acorn/\"}.',
        type: 'string'
      },
      override: {
        doc: 'An object that can be used to override some dependency names to refer to predetermined types. The value associated with a name can be a string starting with the character =, in which case the part after the = will be interpreted as a global variable (or dot-separated path) that contains the proper type. If it is a string not starting with =, it is interpreted as the path to the file that contains the code for the module. If it is an object, it is interpreted as JSON type definition.',
        type: 'string'
      }
    }
  },
  commonjs: {
    doc: 'This plugin implements CommonJS-style (require(\"foo\")) modules. It will wrap files in a file-local scope, and bind require, module, and exports in this scope. Does not implement a module resolution strategy (see for example the node_resolve plugin). Depends on the modules plugin.',
    definition: {}
  }
};
<commit_msg>fix docs (plugins) for node_resolve and modules<commit_after>'use babel';

export default {
  lint: {
    doc: 'Use tern-lint for this project.',
    definition: {}
  },
  complete_strings: {
    doc: 'When enabled, this plugin will gather (short) strings in your code, and completing when inside a string will try to complete to previously seen strings. Takes a single option, maxLength, which controls the maximum length of string values to gather, and defaults to 15.',
    definition: {
      maxLength: {
        doc: '',
        type: 'number'
      }
    }
  },
  doc_comment: {
    doc: 'This plugin, which is enabled by default in the bin/tern server, parses comments before function declarations, variable declarations, and object properties. It will look for JSDoc-style type declarations, and try to parse them and add them to the inferred types, and it will treat the first sentence of comment text as the docstring for the defined variable or property.',
    definition: {
      fullDocs: {
        doc: 'Can be set to true to return the full comment text instead of the first sentence.',
        type: 'boolean'
      },
      strong: {
        doc: 'When enabled, types specified in comments take precedence over inferred types.',
        type: 'boolean'
      }
    }
  },
  node: {
    doc: 'The node.js plugin, called \"node\", provides variables that are part of the node environment, such as process and __dirname, and loads the commonjs and node_resolve plugins to allow node-style module loading. It defines types for the built-in modules that node.js provides (\"fs\", \"http\", etc).',
    definition: {
      dontLoad: {
        doc: 'Can be set to true to disable dynamic loading of required modules entirely, or to a regular expression to disable loading of files that match the expression.',
        type: 'string'
      },
      load: {
        doc: 'If dontLoad isn’t given, this setting is checked. If it is a regular expression, the plugin will only load files that match the expression.',
        type: 'string'
      },
      modules: {
        doc: 'Can be used to assign JSON type definitions to certain modules, so that those are loaded instead of the source code itself. If given, should be an object mapping module names to either JSON objects defining the types in the module, or a string referring to a file name (relative to the project directory) that contains the JSON data.',
        type: 'string'
      }
    }
  },
  node_resolve: {
    doc: 'This plugin defines the node.js module resolution strategy—things like defaulting to index.js when requiring a directory and searching node_modules directories. It depends on the modules plugin. Note that this plugin only does something meaningful when the Tern server is running on node.js itself.',
    definition: {}
  },
  modules: {
    doc: 'This is a supporting plugin to act as a dependency for other module-loading and module-resolving plugins.',
    definition: {
      dontLoad: {
        doc: 'Can be set to true to disable dynamic loading of required modules entirely, or to a regular expression to disable loading of files that match the expression.',
        type: 'string'
      },
      load: {
        doc: 'If dontLoad isn’t given, this setting is checked. If it is a regular expression, the plugin will only load files that match the expression.',
        type: 'string'
      },
      modules: {
        doc: 'Can be used to assign JSON type definitions to certain modules, so that those are loaded instead of the source code itself. If given, should be an object mapping module names to either JSON objects defining the types in the module, or a string referring to a file name (relative to the project directory) that contains the JSON data.',
        type: 'string'
      }
    }
  },
  es_modules: {
    doc: 'This plugin (es_modules) builds on top of the modules plugin to support ECMAScript 6’s import and export based module inclusion.',
    definition: {}
  },
  angular: {
    doc: 'Adds the angular object to the top-level environment, and tries to wire up some of the bizarre dependency management scheme from this library, so that dependency injections get the right types. Enabled with the name \"angular\".',
    definition: {}
  },
  requirejs: {
    doc: 'This plugin (\"requirejs\") teaches the server to understand RequireJS-style dependency management. It defines the global functions define and requirejs, and will do its best to resolve dependencies and give them their proper types.',
    defintions: {
      baseURL: {
        doc: 'The base path to prefix to dependency filenames.',
        type: 'string'
      },
      paths: {
        doc: 'An object mapping filename prefixes to specific paths. For example {\"acorn\": \"lib/acorn/\"}.',
        type: 'string'
      },
      override: {
        doc: 'An object that can be used to override some dependency names to refer to predetermined types. The value associated with a name can be a string starting with the character =, in which case the part after the = will be interpreted as a global variable (or dot-separated path) that contains the proper type. If it is a string not starting with =, it is interpreted as the path to the file that contains the code for the module. If it is an object, it is interpreted as JSON type definition.',
        type: 'string'
      }
    }
  },
  commonjs: {
    doc: 'This plugin implements CommonJS-style (require(\"foo\")) modules. It will wrap files in a file-local scope, and bind require, module, and exports in this scope. Does not implement a module resolution strategy (see for example the node_resolve plugin). Depends on the modules plugin.',
    definition: {}
  }
};
<|endoftext|>


<commit_before>// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/* This file defines the module loader for the dart runtime.
*/
var dart_library;
if (!dart_library) {
dart_library =
  typeof module != "undefined" && module.exports || {};

(function (dart_library) {
  'use strict';

  /** Note that we cannot use dart_utils.throwInternalError from here. */
  function throwLibraryError(message) {
    throw Error(message);
  }

  const libraryImports = Symbol('libraryImports');
  dart_library.libraryImports = libraryImports;

  // Module support.  This is a simplified module system for Dart.
  // Longer term, we can easily migrate to an existing JS module system:
  // ES6, AMD, RequireJS, ....

  // Returns a proxy that delegates to the underlying loader.
  // This defers loading of a module until a library is actually used.
  const loadedModule = Symbol('loadedModule');
  dart_library.defer = function(module, name, patch) {
    let done = false;
    function loadDeferred() {
      done = true;
      var mod = module[loadedModule];
      var lib = mod[name];
      // Install unproxied module and library in caller's context.
      patch(mod, lib);
    }
    // The deferred library object.  Note, the only legal operations on a Dart
    // library object should be get (to read a top-level variable, method, or
    // Class) or set (to write a top-level variable).
    return new Proxy({}, {
      get: function(o, p) {
        if (!done) loadDeferred();
        return module[name][p];
      },
      set: function(o, p, value) {
        if (!done) loadDeferred();
        module[name][p] = value;
        return true;
      },
    });
  };

  let _reverseImports = new Map();
  class LibraryLoader {

    constructor(name, defaultValue, imports, loader) {
      imports.forEach(function(i) {
        var deps = _reverseImports.get(i);
        if (!deps) {
          deps = new Set();
          _reverseImports.set(i, deps);
        }
        deps.add(name);
      });
      this._name = name;
      this._library = defaultValue ? defaultValue : {};
      this._imports = imports;
      this._loader = loader;

      // Cyclic import detection
      this._state = LibraryLoader.NOT_LOADED;
    }

    loadImports() {
      let results = [];
      for (let name of this._imports) {
        let lib = libraries.get(name);
        if (!lib) {
          throwLibraryError('Library not available: ' + name);
        }
        results.push(lib.load());
      }
      return results;
    }

    load() {
      // Check for cycles
      if (this._state == LibraryLoader.LOADING) {
        throwLibraryError('Circular dependence on library: '
                              + this._name);
      } else if (this._state >= LibraryLoader.READY) {
        return this._library;
      }
      this._state = LibraryLoader.LOADING;

      // Handle imports
      let args = this.loadImports();

      // Load the library
      let loader = this;
      let library = this._library;

      library[libraryImports] = this._imports;
      library[loadedModule] = library;
      args.unshift(library);

      if (this._name == 'dart_sdk') {
        // Eagerly load the SDK.
        this._loader.apply(null, args);
      } else {
        // Load / parse other modules on demand.
        let done = false;
        this._library = new Proxy(library, {
          get: function(o, name) {
            if (!done) {
              done = true;
              loader._loader.apply(null, args);
            }
            return o[name];
          }
        });
      }

      this._state = LibraryLoader.READY;
      return this._library;
    }

    stub() {
      return this._library;
    }
  }
  LibraryLoader.NOT_LOADED = 0;
  LibraryLoader.LOADING = 1;
  LibraryLoader.READY = 2;

  // Map from name to LibraryLoader
  let _libraries = new Map();
  dart_library.libraries = function() { return libraries.keys(); };
  dart_library.debuggerLibraries = function() {
    var debuggerLibraries = [];
    _libraries.forEach(function (value, key, map) {
      debuggerLibraries.push(value.load());
    });
    debuggerLibraries.__proto__ = null;
    return debuggerLibraries;
  };

  // Invalidate a library and all things that depend on it
  function _invalidateLibrary(name) {
    let lib = _libraries.get(name);
    if (lib._state == LibraryLoader.NOT_LOADED) return;
    lib._state = LibraryLoader.NOT_LOADED;
    lib._library = {};
    let deps = _reverseImports.get(name);
    if (!deps) return;
    deps.forEach(_invalidateLibrary);
  }

  function library(name, defaultValue, imports, loader) {
    let result = _libraries.get(name);
    if (result) {
      console.log('Re-loading ' + name);
      _invalidateLibrary(name);
    }
    result = new LibraryLoader(name, defaultValue, imports, loader);
    _libraries.set(name, result);
    return result;
  }
  dart_library.library = library;

<<<<<<< HEAD
  function import_(libraryName) {
    let loader = libraries.get(libraryName);
    // TODO(vsm): A user might call this directly from JS (as we do in tests).
    // We may want a different error type.
    if (!loader) throwLibraryError('Library not found: ' + libraryName);
    return loader.load();
=======
  // Maintain a stack of active imports.  If a requested library/module is not
  // available, print the stack to show where/how it was requested.
  let _stack = [];
  function import_(name) {
    let lib = _libraries.get(name);
    if (!lib) {
      let message = 'Module ' + name + ' not loaded in the browser.';
      if (_stack != []) {
        message += '\nDependency via:';
        let indent = '';
        for (let last = _stack.length - 1; last >= 0; last--) {
          indent += ' ';
          message += '\n' + indent + '- ' + _stack[last];
        }
      }
      throwLibraryError(message);
    }
    _stack.push(name);
    let result = lib.load();
    _stack.pop();
    return result;
>>>>>>> origin/master
  }
  dart_library.import = import_;

  var _currentIsolate = false;

  function _restart() {
    start(_lastModuleName, _lastLibraryName, true);
  }

  function reload() {
    if (!window || !window.$dartWarmReload) {
      console.warn('Warm reload not supported in this environment.');
      return;
    }
    var result;
    if (_lastLibrary && _lastLibrary.onReloadStart) {
      result = _lastLibrary.onReloadStart();
    }
    if (result && result.then) {
      let sdk = _libraries.get("dart_sdk");
      result.then(sdk._library.dart.Dynamic)(function() {
        window.$dartWarmReload(_restart);
      });
    } else {
      window.$dartWarmReload(_restart);
    }
  }
  dart_library.reload = reload;

  var _lastModuleName;
  var _lastLibraryName;
  var _lastLibrary;
  var _originalBody;

  function start(moduleName, libraryName, isReload) {
    if (libraryName == null) libraryName = moduleName;
    _lastModuleName = moduleName;
    _lastLibraryName = libraryName;
    let library = import_(moduleName)[libraryName];
    _lastLibrary = library;
    let dart_sdk = import_('dart_sdk');

    if (!_currentIsolate) {
      // This import is only needed for chrome debugging. We should provide an
      // option to compile without it.
      dart_sdk._debugger.registerDevtoolsFormatter();

      // Create isolate.
      _currentIsolate = true;
      dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
    }
    if (isReload) {
      if (library.onReloadEnd) {
        library.onReloadEnd();
        return;
      } else {
        document.body = _originalBody;
      }
    } else {
      // If not a reload then store the initial html to reset it on reload.
      _originalBody = document.body.cloneNode(true);
    }
    library.main();
  }
  dart_library.start = start;

})(dart_library);
}
<commit_msg>fix libraries getter<commit_after>// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/* This file defines the module loader for the dart runtime.
*/
var dart_library;
if (!dart_library) {
dart_library =
  typeof module != "undefined" && module.exports || {};

(function (dart_library) {
  'use strict';

  /** Note that we cannot use dart_utils.throwInternalError from here. */
  function throwLibraryError(message) {
    throw Error(message);
  }

  const libraryImports = Symbol('libraryImports');
  dart_library.libraryImports = libraryImports;

  // Module support.  This is a simplified module system for Dart.
  // Longer term, we can easily migrate to an existing JS module system:
  // ES6, AMD, RequireJS, ....

  // Returns a proxy that delegates to the underlying loader.
  // This defers loading of a module until a library is actually used.
  const loadedModule = Symbol('loadedModule');
  dart_library.defer = function(module, name, patch) {
    let done = false;
    function loadDeferred() {
      done = true;
      var mod = module[loadedModule];
      var lib = mod[name];
      // Install unproxied module and library in caller's context.
      patch(mod, lib);
    }
    // The deferred library object.  Note, the only legal operations on a Dart
    // library object should be get (to read a top-level variable, method, or
    // Class) or set (to write a top-level variable).
    return new Proxy({}, {
      get: function(o, p) {
        if (!done) loadDeferred();
        return module[name][p];
      },
      set: function(o, p, value) {
        if (!done) loadDeferred();
        module[name][p] = value;
        return true;
      },
    });
  };

  let _reverseImports = new Map();
  class LibraryLoader {

    constructor(name, defaultValue, imports, loader) {
      imports.forEach(function(i) {
        var deps = _reverseImports.get(i);
        if (!deps) {
          deps = new Set();
          _reverseImports.set(i, deps);
        }
        deps.add(name);
      });
      this._name = name;
      this._library = defaultValue ? defaultValue : {};
      this._imports = imports;
      this._loader = loader;

      // Cyclic import detection
      this._state = LibraryLoader.NOT_LOADED;
    }

    loadImports() {
      let results = [];
      for (let name of this._imports) {
        let lib = libraries.get(name);
        if (!lib) {
          throwLibraryError('Library not available: ' + name);
        }
        results.push(lib.load());
      }
      return results;
    }

    load() {
      // Check for cycles
      if (this._state == LibraryLoader.LOADING) {
        throwLibraryError('Circular dependence on library: '
                              + this._name);
      } else if (this._state >= LibraryLoader.READY) {
        return this._library;
      }
      this._state = LibraryLoader.LOADING;

      // Handle imports
      let args = this.loadImports();

      // Load the library
      let loader = this;
      let library = this._library;

      library[libraryImports] = this._imports;
      library[loadedModule] = library;
      args.unshift(library);

      if (this._name == 'dart_sdk') {
        // Eagerly load the SDK.
        this._loader.apply(null, args);
      } else {
        // Load / parse other modules on demand.
        let done = false;
        this._library = new Proxy(library, {
          get: function(o, name) {
            if (!done) {
              done = true;
              loader._loader.apply(null, args);
            }
            return o[name];
          }
        });
      }

      this._state = LibraryLoader.READY;
      return this._library;
    }

    stub() {
      return this._library;
    }
  }
  LibraryLoader.NOT_LOADED = 0;
  LibraryLoader.LOADING = 1;
  LibraryLoader.READY = 2;

  // Map from name to LibraryLoader
  let _libraries = new Map();
  dart_library.libraries = function() { return _libraries.keys(); };
  dart_library.debuggerLibraries = function() {
    var debuggerLibraries = [];
    _libraries.forEach(function (value, key, map) {
      debuggerLibraries.push(value.load());
    });
    debuggerLibraries.__proto__ = null;
    return debuggerLibraries;
  };

  // Invalidate a library and all things that depend on it
  function _invalidateLibrary(name) {
    let lib = _libraries.get(name);
    if (lib._state == LibraryLoader.NOT_LOADED) return;
    lib._state = LibraryLoader.NOT_LOADED;
    lib._library = {};
    let deps = _reverseImports.get(name);
    if (!deps) return;
    deps.forEach(_invalidateLibrary);
  }

  function library(name, defaultValue, imports, loader) {
    let result = _libraries.get(name);
    if (result) {
      console.log('Re-loading ' + name);
      _invalidateLibrary(name);
    }
    result = new LibraryLoader(name, defaultValue, imports, loader);
    _libraries.set(name, result);
    return result;
  }
  dart_library.library = library;

<<<<<<< HEAD
  function import_(libraryName) {
    let loader = libraries.get(libraryName);
    // TODO(vsm): A user might call this directly from JS (as we do in tests).
    // We may want a different error type.
    if (!loader) throwLibraryError('Library not found: ' + libraryName);
    return loader.load();
=======
  // Maintain a stack of active imports.  If a requested library/module is not
  // available, print the stack to show where/how it was requested.
  let _stack = [];
  function import_(name) {
    let lib = _libraries.get(name);
    if (!lib) {
      let message = 'Module ' + name + ' not loaded in the browser.';
      if (_stack != []) {
        message += '\nDependency via:';
        let indent = '';
        for (let last = _stack.length - 1; last >= 0; last--) {
          indent += ' ';
          message += '\n' + indent + '- ' + _stack[last];
        }
      }
      throwLibraryError(message);
    }
    _stack.push(name);
    let result = lib.load();
    _stack.pop();
    return result;
>>>>>>> origin/master
  }
  dart_library.import = import_;

  var _currentIsolate = false;

  function _restart() {
    start(_lastModuleName, _lastLibraryName, true);
  }

  function reload() {
    if (!window || !window.$dartWarmReload) {
      console.warn('Warm reload not supported in this environment.');
      return;
    }
    var result;
    if (_lastLibrary && _lastLibrary.onReloadStart) {
      result = _lastLibrary.onReloadStart();
    }
    if (result && result.then) {
      let sdk = _libraries.get("dart_sdk");
      result.then(sdk._library.dart.Dynamic)(function() {
        window.$dartWarmReload(_restart);
      });
    } else {
      window.$dartWarmReload(_restart);
    }
  }
  dart_library.reload = reload;

  var _lastModuleName;
  var _lastLibraryName;
  var _lastLibrary;
  var _originalBody;

  function start(moduleName, libraryName, isReload) {
    if (libraryName == null) libraryName = moduleName;
    _lastModuleName = moduleName;
    _lastLibraryName = libraryName;
    let library = import_(moduleName)[libraryName];
    _lastLibrary = library;
    let dart_sdk = import_('dart_sdk');

    if (!_currentIsolate) {
      // This import is only needed for chrome debugging. We should provide an
      // option to compile without it.
      dart_sdk._debugger.registerDevtoolsFormatter();

      // Create isolate.
      _currentIsolate = true;
      dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
    }
    if (isReload) {
      if (library.onReloadEnd) {
        library.onReloadEnd();
        return;
      } else {
        document.body = _originalBody;
      }
    } else {
      // If not a reload then store the initial html to reset it on reload.
      _originalBody = document.body.cloneNode(true);
    }
    library.main();
  }
  dart_library.start = start;

})(dart_library);
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { subscription } from '/subscription';
import { api } from '/lib/api';
import classnames from 'classnames';

import Header from '/components/header';
import Tile from '/components/tile';

export default class Home extends Component {

  constructor(props) {
    super(props);
    subscription.subscribe("/main");
  }

  render() {
    let keys = [...this.props.keys];
    let tileElems = keys.map((tile) => {
      let tileData = {};
      if (tile in this.props.data && tile !== "invites") {
        tileData = this.props.data[tile] !== null
          ? this.props.data[tile] : {};

        tileData["invites"] = ("invites" in this.props.data)
        ? this.props.data["invites"] : {};
      }
      return <Tile key={tile} type={tile} data={tileData} />;
    });

    let headerData = {};
    if ("invites" in this.props.data) {
      headerData["invites"] = this.props.data["invites"];
    }

    return (

          {tileElems}

    );
  }

}

<commit_msg>launch: stop passing 'invite' prop to tile<commit_after>import React, { Component } from 'react';
import { subscription } from '/subscription';
import { api } from '/lib/api';
import classnames from 'classnames';

import Header from '/components/header';
import Tile from '/components/tile';

export default class Home extends Component {

  constructor(props) {
    super(props);
    subscription.subscribe("/main");
  }

  render() {
    let keys = [...this.props.keys];
    let tileElems = keys.map((tile) => {
      let tileData = {};
      if (tile in this.props.data && tile !== "invites") {
        tileData = this.props.data[tile] !== null
          ? this.props.data[tile] : {};

        // tileData["invites"] = ("invites" in this.props.data)
        // ? this.props.data["invites"] : {};
      }
      return <Tile key={tile} type={tile} data={tileData} />;
    });

    let headerData = {};
    if ("invites" in this.props.data) {
      headerData["invites"] = this.props.data["invites"];
    }

    return (

          {tileElems}

    );
  }

}

<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {Table} from 'react-bootstrap';
import {connect} from 'react-redux';
import _ from 'lodash';

class UsersTable extends Component {

  render() {
    return (

             {this.props.heading}

          {_.union(this.props.playerName, this.props.users)
            .map(_.startCase).sort().map((x) => _renderUserRow(x))}

    );
  }
}

function _renderUserRow(data) {
  return (

      {data}

  )
}

function mapStateToProps(state) {
  return {
    users: state.users,
    playerName: state.game.playerName,
  };
}

export default connect(mapStateToProps)(UsersTable);
<commit_msg>Add player name from props<commit_after>import React, {Component} from 'react';
import {Table} from 'react-bootstrap';
import {connect} from 'react-redux';
import _ from 'lodash';

class UsersTable extends Component {

  render() {
    return (

             {this.props.heading}

          {_.union([this.props.currentUser], this.props.users)
            .map(_.startCase).sort().map((x) => _renderUserRow(x))}

    );
  }
}

function _renderUserRow(data) {
  return (

      {data}

  )
}

function mapStateToProps(state) {
  return {
    users: state.users,
    currentUser: state.game.playerName,
  };
}

export default connect(mapStateToProps)(UsersTable);
<|endoftext|>


<commit_before>/*
 * Simple factory for Scope
 * @lastmodifiedBy ChengFuLin(chengfulin0806@gmail.com)
 * @lastmodifiedDate 2015-07-28
 */
var Scope = require('./scope'),
    namespace = require('../namespace'),
    internal = namespace();

/**
 * Simple factory for the Scope class
 * @constructor
 */
function ScopeFactory() {
    "use strict";
	internal(this)._numOfPageScopes = 0;
    internal(this)._numOfAnonymousFunctionScopes = 0;

    /* start-test-block */
    this._testonly_ = internal(this);
    /* end-test-block */
}

/* start-public-data-members */
Object.defineProperties(ScopeFactory.prototype, {
	/**
	 * Number of the counter of anonymous function scopes
	 * @type {Number}
	 * @memberof ScopeFactory.prototype
	 */
	numOfAnonymousFunctionScopes: {
	    get: function () {
	        "use strict";
	        return internal(this)._numOfAnonymousFunctionScopes;
	    },
	    set: function (num) {
	        "use strict";
	        if (typeof num === 'number' && num >= 0) {
	            internal(this)._numOfAnonymousFunctionScopes = num;
	        }
	    }
	},
	/**
	 * Number of the counter of page scopes
	 * @type {Number}
	 * @memberof ScopeFactory.prototype
	 */
	numOfPageScopes: {
		get: function () {
			"use strict";
			return internal(this)._numOfPageScopes;
		},
		set: function (num) {
			"use strict";
			if (typeof num === 'number' && num >= 0) {
				internal(this)._numOfPageScopes = num;
			}
		}
	}
});
/* end-public-data-members */

/* start-public-methods */
/**
 * Reset the counter of number of anonymous function Scope
 */
ScopeFactory.prototype.resetAnonymousFunctionScopeCounter = function () {
    "use strict";
    internal(this)._numOfAnonymousFunctionScopes = 0;
};

/**
 * Reset the counter of number of page scopes
 */
ScopeFactory.prototype.resetPageScopeCounter = function () {
	"use strict";
	internal(this)._numOfPageScopes = 0;
};

/**
 * Factory method for page scopes
 * @param {Object} cfg CFG of the page scope
 * @param {Object} [parent] Parent scope
 * @returns {Object} A scope with page scope type and name
 */
ScopeFactory.prototype.createPageScope = function (cfg, parent) {
    "use strict";
	var pageScopeIndex = internal(this)._numOfPageScopes++;
    return new Scope(cfg, Scope.PAGE_SCOPE_NAME + '_' + pageScopeIndex, Scope.PAGE_TYPE, parent);
};

/**
 * Factory method for the domain scope
 * @param {Object} cfg CFG of the domain scope
 * @returns {Scope} A scope with domain scope type and name
 */
ScopeFactory.prototype.createDomainScope = function (cfg) {
    "use strict";
    return new Scope(cfg, Scope.DOMAIN_SCOPE_NAME, Scope.DOMAIN_TYPE, null);
};

/**
 * Factory method for function scopes
 * @param {Object} cfg CFG of the function scope
 * @param {String} funName Name of the function
 * @param {Object} [parent] Parent scope
 * @returns {Scope} A scope with function name and function scope type
 */
ScopeFactory.prototype.createFunctionScope = function (cfg, funName, parent) {
    "use strict";
    return new Scope(cfg, funName, Scope.FUNCTION_TYPE, parent);
};

/**
 * Factory method for anonymous function scopes
 * @param {Object} cfg CFG of an anonymous function scope
 * @param {Object} [parent] Parent scope
 * @returns {Scope} A scope with indexed anonymous function scope name and anonymous function scope type
 */
ScopeFactory.prototype.createAnonymousFunctionScope = function (cfg, parent) {
    "use strict";
	var anonymousFunctionIndex = internal(this)._numOfAnonymousFunctionScopes++;
    return new Scope(cfg, Scope.ANONYMOUS_FUN_NAME + '_' + anonymousFunctionIndex, Scope.ANONYMOUS_FUN_TYPE, parent);
};
/* end-public-methods */

var singleton = new ScopeFactory();
module.exports = singleton;<commit_msg>Refactor to create instances of PageScope and DomainScope<commit_after>/*
 * Simple factory for Scope
 * @lastmodifiedBy ChengFuLin(chengfulin0806@gmail.com)
 * @lastmodifiedDate 2015-07-28
 */
var Scope = require('./scope'),
	PageScope = require('./pagescope'),
	DomainScope = require('./domainscope'),
    namespace = require('../namespace'),
    internal = namespace();

/**
 * Simple factory for the Scope class
 * @constructor
 */
function ScopeFactory() {
    "use strict";
	internal(this)._numOfPageScopes = 0;
    internal(this)._numOfAnonymousFunctionScopes = 0;

    /* start-test-block */
    this._testonly_ = internal(this);
    /* end-test-block */
}

/* start-public-data-members */
Object.defineProperties(ScopeFactory.prototype, {
	/**
	 * Number of the counter of anonymous function scopes
	 * @type {Number}
	 * @memberof ScopeFactory.prototype
	 */
	numOfAnonymousFunctionScopes: {
	    get: function () {
	        "use strict";
	        return internal(this)._numOfAnonymousFunctionScopes;
	    },
	    set: function (num) {
	        "use strict";
	        if (typeof num === 'number' && num >= 0) {
	            internal(this)._numOfAnonymousFunctionScopes = num;
	        }
	    }
	},
	/**
	 * Number of the counter of page scopes
	 * @type {Number}
	 * @memberof ScopeFactory.prototype
	 */
	numOfPageScopes: {
		get: function () {
			"use strict";
			return internal(this)._numOfPageScopes;
		},
		set: function (num) {
			"use strict";
			if (typeof num === 'number' && num >= 0) {
				internal(this)._numOfPageScopes = num;
			}
		}
	}
});
/* end-public-data-members */

/* start-public-methods */
/**
 * Reset the counter of number of anonymous function Scope
 */
ScopeFactory.prototype.resetAnonymousFunctionScopeCounter = function () {
    "use strict";
    internal(this)._numOfAnonymousFunctionScopes = 0;
};

/**
 * Reset the counter of number of page scopes
 */
ScopeFactory.prototype.resetPageScopeCounter = function () {
	"use strict";
	internal(this)._numOfPageScopes = 0;
};

/**
 * Factory method for page scopes
 * @param {Object} cfg CFG of the page scope
 * @param {Object} [parent] Parent scope
 * @returns {Object} A scope with page scope type and name
 */
ScopeFactory.prototype.createPageScope = function (cfg, parent) {
    "use strict";
	var pageScopeIndex = internal(this)._numOfPageScopes++;
    return new PageScope(cfg, Scope.PAGE_SCOPE_NAME + '_' + pageScopeIndex, parent);
};

/**
 * Factory method for the domain scope
 * @param {Object} cfg CFG of the domain scope
 * @returns {Scope} A scope with domain scope type and name
 */
ScopeFactory.prototype.createDomainScope = function (cfg) {
    "use strict";
    return new DomainScope(cfg);
};

/**
 * Factory method for function scopes
 * @param {Object} cfg CFG of the function scope
 * @param {String} funName Name of the function
 * @param {Object} [parent] Parent scope
 * @returns {Scope} A scope with function name and function scope type
 */
ScopeFactory.prototype.createFunctionScope = function (cfg, funName, parent) {
    "use strict";
    return new Scope(cfg, funName, Scope.FUNCTION_TYPE, parent);
};

/**
 * Factory method for anonymous function scopes
 * @param {Object} cfg CFG of an anonymous function scope
 * @param {Object} [parent] Parent scope
 * @returns {Scope} A scope with indexed anonymous function scope name and anonymous function scope type
 */
ScopeFactory.prototype.createAnonymousFunctionScope = function (cfg, parent) {
    "use strict";
	var anonymousFunctionIndex = internal(this)._numOfAnonymousFunctionScopes++;
    return new Scope(cfg, Scope.ANONYMOUS_FUN_NAME + '_' + anonymousFunctionIndex, Scope.ANONYMOUS_FUN_TYPE, parent);
};
/* end-public-methods */

var singleton = new ScopeFactory();
module.exports = singleton;<|endoftext|>


<commit_before>// Copyright 2016 Artem Lytvynov <buntarb@gmail.com>. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @license Apache-2.0
 * @copyright Artem Lytvynov <buntarb@gmail.com>
 */

goog.provide( 'zz.environment.services.EnvironmentTest' );
goog.require( 'goog.testing.jsunit' );
goog.setTestOnly( 'zz.environment.services.EnvironmentTest' );

goog.require( 'zz.environment.services.Environment' );

goog.require( 'goog.events.EventTarget' );
goog.require( 'goog.dom.ViewportSizeMonitor' );

var env;
var feBaseMock;

function setUp( ){

    env = new zz.environment.services.Environment( );
    feBaseMock = function( ){ };
}

function testConstructor( ){

    assertTrue(

        'Instance must be non-null and have the expected type',
        env instanceof zz.environment.services.Environment
    );
}

function testInheritance( ){

    assertTrue(

        'Instance must be non-null and have the expected type',
        env instanceof goog.events.EventTarget
    );
}

function testViewportSizeMonitor( ){

    assertTrue(

        'Instance must be non-null and have the expected type',
        env.viewportSizeMonitor_ instanceof goog.dom.ViewportSizeMonitor
    );
}

function testRootController( ){

    assertFalse(

        'Must be false for new instance',
        env.rootController_
    );
}

function testSetRootController( ){

    env.setRootController( feBaseMock );

    assertTrue(

        'Property must be a function since setter has been called',
        goog.isFunction( env.rootController_ )
    );

    assertEquals(

        'Property must be equals to passed parameter',
        env.rootController_,
        feBaseMock
    );
}

function testGetRootController( ){

    env.setRootController( feBaseMock );

    assertTrue(

        'Property must be a function since setter has been called',
        goog.isFunction( env.getRootController( ) )
    );

    assertEquals(

        'Property must be equals to passed parameter',
        env.getRootController( ),
        feBaseMock
    );
}

function testIsNode( ){

    assertFalse(

        'Must be false for current version',
        env.isNode( )
    );
}

function testIsCordova( ){

    assertFalse(

        'Must be false for current version',
        env.isCordova( )
    );
}

function testIsBrowser( ){

    assertTrue(

        'Must be true for current version',
        env.isBrowser( )
    );
}

function testDevice( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.device )
    );
}

function testOs( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.os )
    );
}

function testBrowserEngine( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.browserEngine )
    );
}<commit_msg>add testBrowser<commit_after>// Copyright 2016 Artem Lytvynov <buntarb@gmail.com>. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @license Apache-2.0
 * @copyright Artem Lytvynov <buntarb@gmail.com>
 */

goog.provide( 'zz.environment.services.EnvironmentTest' );
goog.require( 'goog.testing.jsunit' );
goog.setTestOnly( 'zz.environment.services.EnvironmentTest' );

goog.require( 'zz.environment.services.Environment' );

goog.require( 'goog.events.EventTarget' );
goog.require( 'goog.dom.ViewportSizeMonitor' );

var env;
var feBaseMock;

function setUp( ){

    env = new zz.environment.services.Environment( );
    feBaseMock = function( ){ };
}

function testConstructor( ){

    assertTrue(

        'Instance must be non-null and have the expected type',
        env instanceof zz.environment.services.Environment
    );
}

function testInheritance( ){

    assertTrue(

        'Instance must be non-null and have the expected type',
        env instanceof goog.events.EventTarget
    );
}

function testViewportSizeMonitor( ){

    assertTrue(

        'Instance must be non-null and have the expected type',
        env.viewportSizeMonitor_ instanceof goog.dom.ViewportSizeMonitor
    );
}

function testRootController( ){

    assertFalse(

        'Must be false for new instance',
        env.rootController_
    );
}

function testSetRootController( ){

    env.setRootController( feBaseMock );

    assertTrue(

        'Property must be a function since setter has been called',
        goog.isFunction( env.rootController_ )
    );

    assertEquals(

        'Property must be equals to passed parameter',
        env.rootController_,
        feBaseMock
    );
}

function testGetRootController( ){

    env.setRootController( feBaseMock );

    assertTrue(

        'Property must be a function since setter has been called',
        goog.isFunction( env.getRootController( ) )
    );

    assertEquals(

        'Property must be equals to passed parameter',
        env.getRootController( ),
        feBaseMock
    );
}

function testIsNode( ){

    assertFalse(

        'Must be false for current version',
        env.isNode( )
    );
}

function testIsCordova( ){

    assertFalse(

        'Must be false for current version',
        env.isCordova( )
    );
}

function testIsBrowser( ){

    assertTrue(

        'Must be true for current version',
        env.isBrowser( )
    );
}

function testDevice( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.device )
    );
}

function testOs( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.os )
    );
}

function testBrowserEngine( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.browserEngine )
    );
}

function testBrowser( ){

    assertTrue(

        'Property must have a type of Object',
        goog.isObject( env.browser )
    );
}<|endoftext|>


<commit_before>define([
    "engine/input",
    "physics/jello"
], function(Input, Jello) {

	var ToolEvent = mini.Class.subclass({
		initialize: function ToolEvent(tool, type, event) {
			this.tool = tool;
			this.type = type;
			this.event = event;
		},

		getPoint: function() {
			return this._choosePoint(this._point, this.tool._point);
		},

		setPoint: function(point) {
			this._point = point;
		},

		getLastPoint: function() {
			return this._choosePoint(this._lastPoint, this.tool._lastPoint);
		},

		setLastPoint: function(lastPoint) {
			this._lastPoint = lastPoint;
		},

		getDownPoint: function() {
			return this._choosePoint(this._downPoint, this.tool._downPoint);
		},

		setDownPoint: function(downPoint) {
			this._downPoint = downPoint;
		},

		getDelta: function() {
			return !this._delta && this.tool._lastPoint
			 		? this.tool._point.subtract(this.tool._lastPoint)
					: this._delta;
		},

		setDelta: function(delta) {
			this._delta = delta;
		},

		getCount: function() {
			return /^mouse(down|up)$/.test(this.type)
					? this.tool._downCount
					: this.tool._count;
		},

		setCount: function(count) {
			this.tool[/^mouse(down|up)$/.test(this.type) ? 'downCount' : 'count']
				= count;
		},

		getItem: function() {
			if (!this._item) {
				var result = this.tool._scope.project.hitTest(this.getPoint());
				if (result) {
					var item = result.item,
						parent = item._parent;
					while (/^(Group|CompoundPath)$/.test(parent._class)) {
						item = parent;
						parent = parent._parent;
					}
					this._item = item;
				}
			}
			return this._item;
		},
		setItem: function(item) {
			this._item = item;
		},

		toString: function() {
			return '{ type: ' + this.type
					+ ', point: ' + this.getPoint()
					+ ', count: ' + this.getCount()
					+ ', modifiers: ' + this.getModifiers()
					+ ' }';
		}
	});

	var Tool = mini.Class.subclass({
		_events: [ 'onActivate', 'onDeactivate',
				'onMouseDown', 'onMouseUp', 'onMouseDrag', 'onMouseMove',
				'onKeyDown', 'onKeyUp' ],

		initialize: function Tool() {
			env.input.initMouse();
			env.input.bind(Input.KEY.MOUSE1, Tool._mouseButton);

			this._firstMove = true;
			this._count = 0;
			this._downCount = 0;

			this._lastPosition = new Jello.Vector2(env.input.mouse.x, env.input.mouse.y);

			// callbacks
			this._activateCallback = function() {};
			this._deactivateCallback = function() {};
			this._mouseDownCallback = function() {};
			this._mouseDragCallback = function() {};
			this._mouseMoveCallback = function() {};
			this._mouseUpCallback = function() {};
			//this._KeyDownCallback = function() {};
			//this._KeyUpCallback = function() {};
		},

		onActivate: function(callback) { this._activateCallback = callback; },
		onDeactivate: function(callback) { this._deactivateCallback = callback; },
		onMouseDown: function(callback) { this._mouseDownCallback = callback; },
		onMouseDrag: function(callback) { this._mouseDragCallback = callback; },
		onMouseMove: function(callback) { this._mouseMoveCallback = callback; },
		onMouseUp: function(callback) { this._mouseUpCallback = callback; },
		//onKeyDown: function(callback) { this._KeyDownCallback = callback; },
		//onKeyUp: function(callback) { this._KeyUpCallback = callback; },

		activate: function() {
			env.input.tool.deactivate();
			env.input.tool = this;
			this._activateCallback.call(this);
		},

		deactivate: function() {
			this._deactivateCallback.call(this);
		},

		update: function() {
			var position = new Jello.Vector2(env.input.mouse.x, env.input.mouse.y);
			env.camera.screenToWorldCoordinates(env.input.mouse);

			var event = new ToolEvent();
			// down
			if(env.input.pressed(Tool._mouseButton))
				this._mouseUpCallback.call(this, event);

			// drag
			if(env.input.state(Tool._mouseButton))
				this._mouseUpCallback.call(this, event);

			// move
			if(!env.input.state(Tool._mouseButton))
				this._mouseUpCallback.call(this, event);

			// up
			if(env.input.released(Tool._mouseButton))
				this._mouseUpCallback.call(this, event);

			this._lastPosition = position.copy();
		},

		_updateEvent: function(type, point, minDistance, maxDistance, start,
				needsChange, matchMaxDistance) {
			if (!start) {
				if (minDistance != null || maxDistance != null) {
					var minDist = minDistance != null ? minDistance : 0,
						vector = point.subtract(this._point),
						distance = vector.getLength();
					if (distance < minDist)
						return false;
					var maxDist = maxDistance != null ? maxDistance : 0;
					if (maxDist != 0) {
						if (distance > maxDist) {
							point = this._point.add(vector.normalize(maxDist));
						} else if (matchMaxDistance) {
							return false;
						}
					}
				}
				if (needsChange && point.equals(this._point))
					return false;
			}
			this._lastPoint = start && type == 'mousemove' ? point : this._point;
			this._point = point;
			switch (type) {
			case 'mousedown':
				this._lastPoint = this._downPoint;
				this._downPoint = this._point;
				this._downCount++;
				break;
			case 'mouseup':
				this._lastPoint = this._downPoint;
				break;
			}
			this._count = start ? 0 : this._count + 1;
			return true;
		},

		_fireEvent: function(type, event) {
			var sets = paper.project._removeSets;
			if (sets) {
				if (type === 'mouseup')
					sets.mousedrag = null;
				var set = sets[type];
				if (set) {
					for (var id in set) {
						var item = set[id];
						for (var key in sets) {
							var other = sets[key];
							if (other && other != set)
								delete other[item._id];
						}
						item.remove();
					}
					sets[type] = null;
				}
			}
			return this.responds(type)
					&& this.fire(type, new ToolEvent(this, type, event));
		},

		_handleEvent: function(type, point, event) {
			paper = this._scope;
			var called = false;
			switch (type) {
			case 'mousedown':
				this._updateEvent(type, point, null, null, true, false, false);
				called = this._fireEvent(type, event);
				break;
			case 'mousedrag':
				var needsChange = false,
					matchMaxDistance = false;
				while (this._updateEvent(type, point, this.minDistance,
						this.maxDistance, false, needsChange, matchMaxDistance)) {
					called = this._fireEvent(type, event) || called;
					needsChange = true;
					matchMaxDistance = true;
				}
				break;
			case 'mouseup':
				if (!point.equals(this._point)
						&& this._updateEvent('mousedrag', point, this.minDistance,
								this.maxDistance, false, false, false)) {
					called = this._fireEvent('mousedrag', event);
				}
				this._updateEvent(type, point, null, this.maxDistance, false,
						false, false);
				called = this._fireEvent(type, event) || called;
				this._updateEvent(type, point, null, null, true, false, false);
				this._firstMove = true;
				break;
			case 'mousemove':
				while (this._updateEvent(type, point, this.minDistance,
						this.maxDistance, this._firstMove, true, false)) {
					called = this._fireEvent(type, event) || called;
					this._firstMove = false;
				}
				break;
			}
			if (called)
				event.preventDefault();
			return called;
		}

	});

	Tool._mouseButton = "leftclick";

	return Tool;
});
<commit_msg>added convenient methods to ToolEvent<commit_after>define([
    "engine/input",
    "physics/jello"
], function(Input, Jello) {

	var ToolEvent = mini.Class.subclass({
		initialize: function ToolEvent(tool) {
			this.tool = tool;
		},

		setScreenPosition: function(pos) { this._position = pos; },
		setLastScreenPosition: function(pos) { this._lastPosition = pos; },
		setDownScreenPosition: function(pos) { this._downPosition = pos; },

		getScreenPosition: function() { return this._position; },
		getLastScreenPosition: function() { return this._lastPosition; },
		getDownScreenPosition: function() { return this._downPosition; },

		_transformToLayer: function(vector, layer) {
			env.camera.pushLayer(layer);
			var layerPos = env.camera.screenToWorldCoordinates(vector);
			env.camera.popLayer();
			return layerPos;
		},

		getPositionInLayer: function(layer) {
			return this._transformToLayer(this._position, layer);
		},
		getLastPositionInLayer: function(layer) {
			return this._transformToLayer(this._lastPosition, layer);
		},
		getDownPositionInLayer: function(layer) {
			return this._transformToLayer(this._downPosition, layer);
		},

		getLastDelta: function() { return this._position.sub(this._lastPosition); },
		getDownDelta: function() { return this._position.sub(this._downPosition); },

		getLastDistance: function() { return this._position.distance(this._lastPosition); },
		getDownDistance: function() { return this._position.distance(this._downPosition); },

		getDistanceToPoint: function(point) { return this._position.distance(point); },
		getDistanceToPointInLayer: function(point, layer) {
			var toolPositionInLayer = this.getPositionInLayer(layer);
			return toolPositionInLayer.distance(point);
		},
		getDownCount: function() {},
		hitTest: function(layer) {},
		getDownPath: function() {}
	});

	var Tool = mini.Class.subclass({
		initialize: function Tool() {
			env.input.initMouse();

			this._downCount = 0;

			this._lastPosition = new Jello.Vector2(env.input.mouse.x, env.input.mouse.y);

			this._activateCallback = function() {};
			this._deactivateCallback = function() {};
			this._mouseDownCallback = function() {};
			this._mouseDragCallback = function() {};
			this._mouseMoveCallback = function() {};
			this._mouseUpCallback = function() {};
			//this._KeyDownCallback = function() {};
			//this._KeyUpCallback = function() {};
		},

		onActivate: function(callback) { this._activateCallback = callback; },
		onDeactivate: function(callback) { this._deactivateCallback = callback; },
		onMouseDown: function(callback) { this._mouseDownCallback = callback; },
		onMouseDrag: function(callback) { this._mouseDragCallback = callback; },
		onMouseMove: function(callback) { this._mouseMoveCallback = callback; },
		onMouseUp: function(callback) { this._mouseUpCallback = callback; },
		//onKeyDown: function(key, callback) { this._KeyDownCallback = callback; },
		//onKeyUp: function(key, callback) { this._KeyUpCallback = callback; },

		activate: function() {
			env.input.tool.deactivate();
			env.input.tool = this;
			this._activateCallback.call(this);
		},

		deactivate: function() {
			this._deactivateCallback.call(this);
		},

		update: function() {
			var position = new Jello.Vector2(env.input.mouse.x, env.input.mouse.y);
			if(env.input.pressed(Tool._mouseButton))
				this._downPosition = position.copy();

			var event = new ToolEvent(this);
			event.setScreenPosition(position);
			event.setLastScreenPosition(this._lastPosition || position);
			event.setDownScreenPosition(this._downPosition);

			// down
			if(env.input.pressed(Tool._mouseButton))
				this._mouseDownCallback.call(this, event);

			// drag
			if(env.input.state(Tool._mouseButton))
				this._mouseDragCallback.call(this, event);

			// move
			if(!env.input.state(Tool._mouseButton))
				this._mouseMoveCallback.call(this, event);

			// up
			if(env.input.released(Tool._mouseButton))
				this._mouseUpCallback.call(this, event);

			this._lastPosition = position.copy();
		}
	});

	Tool._mouseButton = "leftclick";

	return Tool;
});
<|endoftext|>


<commit_before>'use strict';
const dayjs = require('dayjs');
const max = Math.max;

const {
  calculateRequestHeaderSize,
  calculateResponseHeaderSize,
  getHeaderValue,
  parseHeaders
} = require('./headers');

const { parseRequestCookies, parseResponseCookies } = require('./cookies');
const { isHttp1x, formatMillis } = require('./util');
function firstNonNegative(values) {
  for (let i = 0; i < values.length; ++i) {
    if (values[i] >= 0) return values[i];
  }
  return -1;
}

function formatIP(ipAddress) {
  if (typeof ipAddress !== 'string') {
    return undefined;
  }
  // IPv6 addresses are listed as [2a00:1450:400f:80a::2003]
  return ipAddress.replace(/^\[|]$/g, '');
}

module.exports = function(entry, response, page, options) {
  const responseHeaders = response.headers;
  const cookieHeader = getHeaderValue(responseHeaders, 'Set-Cookie');

  let cookies = parseResponseCookies(cookieHeader);
  let headers = parseHeaders(responseHeaders);

  if (entry.extraResponseInfo) {
    if (entry.extraResponseInfo.headers) {
      headers = entry.extraResponseInfo.headers.concat(
        headers.filter(
          ({ name }) => !headers.find(header => header.name === name)
        )
      );
    }

    if (entry.extraResponseInfo.blockedCookies) {
      cookies = cookies.filter(
        ({ name }) =>
          !entry.extraResponseInfo.blockedCookies.find(blockedCookie => {
            if (blockedCookie.cookie) {
              return blockedCookie.cookie.name === name;
            } else if (blockedCookie.cookieLine) {
              const cookie = parseResponseCookies(blockedCookie.cookieLine)[0];
              if (cookie) {
                return cookie.name === name;
              }
            }

            return false;
          })
      );
    }

    // Remove extra info once it has been added to the response
    delete entry.extraResponseInfo;
  }

  // response.body must be set by the library user, by either calling
  // Network.getResponseBody or Network.getResponseBodyForInterception as it is
  // not part of the Chrome DevTools Protocol specification.
  // See https://chromedevtools.github.io/devtools-protocol/tot/Network#type-Response
  const text =
    options != null && options.includeTextFromResponseBody
      ? response.body
      : undefined;

  entry.response = {
    httpVersion: response.protocol,
    redirectURL: '',
    status: response.status,
    statusText: response.statusText,
    content: {
      encodig: response.encoding,
      mimeType: response.mimeType,
      size: text != null ? text.length : 0,
      text: text
    },
    headersSize: -1,
    bodySize: -1,
    cookies,
    headers,
    _transferSize: response.encodedDataLength
  };

  const locationHeaderValue = getHeaderValue(responseHeaders, 'Location');
  if (locationHeaderValue) {
    entry.response.redirectURL = locationHeaderValue;
  }

  entry.request.httpVersion = response.protocol;

  if (response.fromDiskCache === true) {
    if (isHttp1x(response.protocol)) {
      // In http2 headers are compressed, so calculating size from headers text wouldn't be correct.
      entry.response.headersSize = calculateResponseHeaderSize(response);
    }

    // h2 push might cause resource to be received before parser sees and requests it.
    if (response.timing && !(response.timing.pushStart > 0)) {
      entry.cache.beforeRequest = {
        lastAccess: '',
        eTag: '',
        hitCount: 0
      };
    }
  } else {
    if (response.requestHeaders) {
      entry.request.headers = parseHeaders(response.requestHeaders);

      const cookieHeader = getHeaderValue(response.requestHeaders, 'Cookie');
      entry.request.cookies = parseRequestCookies(cookieHeader);
    }

    if (isHttp1x(response.protocol)) {
      if (response.headersText) {
        entry.response.headersSize = response.headersText.length;
      } else {
        entry.response.headersSize = calculateResponseHeaderSize(response);
      }

      entry.response.bodySize =
        response.encodedDataLength - entry.response.headersSize;

      if (response.requestHeadersText) {
        entry.request.headersSize = response.requestHeadersText.length;
      } else {
        // Since entry.request.httpVersion is now set, we can calculate header size.
        entry.request.headersSize = calculateRequestHeaderSize(entry.request);
      }
    }
  }

  entry.connection = response.connectionId.toString();
  entry.serverIPAddress = formatIP(response.remoteIPAddress);

  function parseOptionalTime(timing, start, end) {
    if (timing[start] >= 0) {
      return formatMillis(timing[end] - timing[start]);
    }
    return -1;
  }

  const timing = response.timing;
  if (timing) {
    const blocked = formatMillis(
      firstNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart])
    );

    const dns = parseOptionalTime(timing, 'dnsStart', 'dnsEnd');
    const connect = parseOptionalTime(timing, 'connectStart', 'connectEnd');
    const send = formatMillis(timing.sendEnd - timing.sendStart);
    const wait = formatMillis(timing.receiveHeadersEnd - timing.sendEnd);
    const receive = 0;

    const ssl = parseOptionalTime(timing, 'sslStart', 'sslEnd');

    entry.timings = {
      blocked,
      dns,
      connect,
      send,
      wait,
      receive,
      ssl
    };

    entry._requestTime = timing.requestTime;
    entry.__receiveHeadersEnd = timing.receiveHeadersEnd;
    if (timing.pushStart > 0) {
      // use the same extended field as WebPageTest
      entry._was_pushed = 1;
    }

    entry.time =
      max(0, blocked) + max(0, dns) + max(0, connect) + send + wait + receive;

    // Some cached responses generate a Network.requestServedFromCache event,
    // but fromDiskCache is still set to false.
    if (!entry.__servedFromCache) {
      // wallTime is not necessarily monotonic, timestamp is. So calculate startedDateTime from timestamp diffs.
      // (see https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/network/ResourceLoadTiming.h?q=requestTime+package:%5Echromium$&dr=CSs&l=84)
      const entrySecs =
        page.__wallTime + (timing.requestTime - page.__timestamp);
      entry.startedDateTime = dayjs.unix(entrySecs).toISOString();

      const queuedMillis =
        (timing.requestTime - entry.__requestWillBeSentTime) * 1000;
      if (queuedMillis > 0) {
        entry.timings._queued = formatMillis(queuedMillis);
      }
    }

    if (entry.cache && entry.cache.beforeRequest) {
      // lastAccess needs to be a valid date
      entry.cache.beforeRequest.lastAccess = entry.startedDateTime;
    }
  } else {
    entry.timings = {
      blocked: -1,
      dns: -1,
      connect: -1,
      send: 0,
      wait: 0,
      receive: 0,
      ssl: -1,
      comment: 'No timings available from Chrome'
    };
    entry.time = 0;
  }
};
<commit_msg>Fixed typeo<commit_after>'use strict';
const dayjs = require('dayjs');
const max = Math.max;

const {
  calculateRequestHeaderSize,
  calculateResponseHeaderSize,
  getHeaderValue,
  parseHeaders
} = require('./headers');

const { parseRequestCookies, parseResponseCookies } = require('./cookies');
const { isHttp1x, formatMillis } = require('./util');
function firstNonNegative(values) {
  for (let i = 0; i < values.length; ++i) {
    if (values[i] >= 0) return values[i];
  }
  return -1;
}

function formatIP(ipAddress) {
  if (typeof ipAddress !== 'string') {
    return undefined;
  }
  // IPv6 addresses are listed as [2a00:1450:400f:80a::2003]
  return ipAddress.replace(/^\[|]$/g, '');
}

module.exports = function(entry, response, page, options) {
  const responseHeaders = response.headers;
  const cookieHeader = getHeaderValue(responseHeaders, 'Set-Cookie');

  let cookies = parseResponseCookies(cookieHeader);
  let headers = parseHeaders(responseHeaders);

  if (entry.extraResponseInfo) {
    if (entry.extraResponseInfo.headers) {
      headers = entry.extraResponseInfo.headers.concat(
        headers.filter(
          ({ name }) => !headers.find(header => header.name === name)
        )
      );
    }

    if (entry.extraResponseInfo.blockedCookies) {
      cookies = cookies.filter(
        ({ name }) =>
          !entry.extraResponseInfo.blockedCookies.find(blockedCookie => {
            if (blockedCookie.cookie) {
              return blockedCookie.cookie.name === name;
            } else if (blockedCookie.cookieLine) {
              const cookie = parseResponseCookies(blockedCookie.cookieLine)[0];
              if (cookie) {
                return cookie.name === name;
              }
            }

            return false;
          })
      );
    }

    // Remove extra info once it has been added to the response
    delete entry.extraResponseInfo;
  }

  // response.body must be set by the library user, by either calling
  // Network.getResponseBody or Network.getResponseBodyForInterception as it is
  // not part of the Chrome DevTools Protocol specification.
  // See https://chromedevtools.github.io/devtools-protocol/tot/Network#type-Response
  const text =
    options != null && options.includeTextFromResponseBody
      ? response.body
      : undefined;

  entry.response = {
    httpVersion: response.protocol,
    redirectURL: '',
    status: response.status,
    statusText: response.statusText,
    content: {
      encoding: response.encoding,
      mimeType: response.mimeType,
      size: text != null ? text.length : 0,
      text: text
    },
    headersSize: -1,
    bodySize: -1,
    cookies,
    headers,
    _transferSize: response.encodedDataLength
  };

  const locationHeaderValue = getHeaderValue(responseHeaders, 'Location');
  if (locationHeaderValue) {
    entry.response.redirectURL = locationHeaderValue;
  }

  entry.request.httpVersion = response.protocol;

  if (response.fromDiskCache === true) {
    if (isHttp1x(response.protocol)) {
      // In http2 headers are compressed, so calculating size from headers text wouldn't be correct.
      entry.response.headersSize = calculateResponseHeaderSize(response);
    }

    // h2 push might cause resource to be received before parser sees and requests it.
    if (response.timing && !(response.timing.pushStart > 0)) {
      entry.cache.beforeRequest = {
        lastAccess: '',
        eTag: '',
        hitCount: 0
      };
    }
  } else {
    if (response.requestHeaders) {
      entry.request.headers = parseHeaders(response.requestHeaders);

      const cookieHeader = getHeaderValue(response.requestHeaders, 'Cookie');
      entry.request.cookies = parseRequestCookies(cookieHeader);
    }

    if (isHttp1x(response.protocol)) {
      if (response.headersText) {
        entry.response.headersSize = response.headersText.length;
      } else {
        entry.response.headersSize = calculateResponseHeaderSize(response);
      }

      entry.response.bodySize =
        response.encodedDataLength - entry.response.headersSize;

      if (response.requestHeadersText) {
        entry.request.headersSize = response.requestHeadersText.length;
      } else {
        // Since entry.request.httpVersion is now set, we can calculate header size.
        entry.request.headersSize = calculateRequestHeaderSize(entry.request);
      }
    }
  }

  entry.connection = response.connectionId.toString();
  entry.serverIPAddress = formatIP(response.remoteIPAddress);

  function parseOptionalTime(timing, start, end) {
    if (timing[start] >= 0) {
      return formatMillis(timing[end] - timing[start]);
    }
    return -1;
  }

  const timing = response.timing;
  if (timing) {
    const blocked = formatMillis(
      firstNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart])
    );

    const dns = parseOptionalTime(timing, 'dnsStart', 'dnsEnd');
    const connect = parseOptionalTime(timing, 'connectStart', 'connectEnd');
    const send = formatMillis(timing.sendEnd - timing.sendStart);
    const wait = formatMillis(timing.receiveHeadersEnd - timing.sendEnd);
    const receive = 0;

    const ssl = parseOptionalTime(timing, 'sslStart', 'sslEnd');

    entry.timings = {
      blocked,
      dns,
      connect,
      send,
      wait,
      receive,
      ssl
    };

    entry._requestTime = timing.requestTime;
    entry.__receiveHeadersEnd = timing.receiveHeadersEnd;
    if (timing.pushStart > 0) {
      // use the same extended field as WebPageTest
      entry._was_pushed = 1;
    }

    entry.time =
      max(0, blocked) + max(0, dns) + max(0, connect) + send + wait + receive;

    // Some cached responses generate a Network.requestServedFromCache event,
    // but fromDiskCache is still set to false.
    if (!entry.__servedFromCache) {
      // wallTime is not necessarily monotonic, timestamp is. So calculate startedDateTime from timestamp diffs.
      // (see https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/network/ResourceLoadTiming.h?q=requestTime+package:%5Echromium$&dr=CSs&l=84)
      const entrySecs =
        page.__wallTime + (timing.requestTime - page.__timestamp);
      entry.startedDateTime = dayjs.unix(entrySecs).toISOString();

      const queuedMillis =
        (timing.requestTime - entry.__requestWillBeSentTime) * 1000;
      if (queuedMillis > 0) {
        entry.timings._queued = formatMillis(queuedMillis);
      }
    }

    if (entry.cache && entry.cache.beforeRequest) {
      // lastAccess needs to be a valid date
      entry.cache.beforeRequest.lastAccess = entry.startedDateTime;
    }
  } else {
    entry.timings = {
      blocked: -1,
      dns: -1,
      connect: -1,
      send: 0,
      wait: 0,
      receive: 0,
      ssl: -1,
      comment: 'No timings available from Chrome'
    };
    entry.time = 0;
  }
};
<|endoftext|>