<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.ticket',
  name: 'Ticket',

  documentation: 'Ticket Model',

  implements: [
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  javaImports: [
    'java.util.Date'
  ],

  imports: [
    'userDAO'
  ],

  tableColumns: [
    'id',
    'type',
    // REVIEW: view fails to display when owner in tableColumns
  //  'owner',
    'lastModified',
    'status',
    'summary'
  ],

  sections: [
     {
      name: 'ticketType',
      isAvailable: function(id) { return !! id; },
      order: 1
    },
    {
      name: 'basicInfo',
      title: '',
      order: 2
    },
    {
      name: 'comments',
      title: '',
      order: 3
    },
    {
      name: 'details',
      title: '',
      order: 4
    },
    {
      name: '_defaultSection',
      permissionRequired: true,
      hidden: true
    },
  ],

  properties: [
    {
      class: 'String',
      name: 'type',
      documentation: 'The type of the ticket.',
      transient: true,
      getter: function() {
        return this.cls_.name;
      },
      javaGetter: `
        return getClass().getSimpleName();
      `,
      tableWidth: 135,
      section: 'ticketType',
      visibility: 'RO'
    },
    {
      class: 'Long',
      name: 'id',
      visibility: 'RO',
      section: 'basicInfo',
      order: 1
    },
    {
      name: 'type',
      class: 'String',
      visibility: 'RO',
      storageTransient: true,
      section: 'basicInfo',
      getter: function() {
         return this.cls_.name;
      },
      javaGetter: `
    return getClass().getSimpleName();
      `,
      tableWidth: 160,
      order: 2
    },
    {
      class: 'foam.core.Enum',
      of: 'foam.nanos.ticket.TicketStatus',
      name: 'status',
      value: 'OPEN',
      includeInDigest: true,
      section: 'basicInfo',
      order: 3
   },
    // REVIEW: can't get this to work.
    // {
    //   name: 'watchers',
    //   class: 'List',
    //   javaType: 'java.util.ArrayList<java.lang.Long>',
    //   view: {
    //     class: 'foam.u2.view.ReferenceArrayView',
    //     daoKey: 'userDAO'
    //   },
    //   section: 'details',
    // },
    {
      class: 'String',
      name: 'title',
      required: true,
      section: 'basicInfo',
      validationPredicate: [
        {
          args: ['title', 'type'],
          predicateFactory: function(e) {
            return e.GT(
              foam.mlang.StringLength.create({
                arg1: foam.nanos.ticket.Ticket.TITLE
              }), 0);
          },
          errorString: 'Please provide a summary of the Ticket.'
        }
      ],
      order: 4
    },
    {
      class: 'String',
      name: 'comment',
      value: '',
    // required: true,
      storageTransient: true,
      section: 'comments',
      validationPredicate: [
        {
          args: ['id', 'title', 'comment'],
          predicateFactory: function(e) {
            return e.OR(
              e.AND(
                e.EQ(foam.nanos.ticket.Ticket.ID, 0),
                e.GT(
                  foam.mlang.StringLength.create({
                    arg1: foam.nanos.ticket.Ticket.TITLE
                  }), 0)
              ),
              e.GT(
              foam.mlang.StringLength.create({
                arg1: foam.nanos.ticket.Ticket.COMMENT
              }), 0)
            );
          },
          errorString: 'Please provide a comment.'
        }
      ],
      order: 1
    },
    {
      class: 'DateTime',
      name: 'created',
      visibility: 'RO',
      includeInDigest: true,
      section: 'details',
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      visibility: 'RO',
      includeInDigest: true,
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      },
      section: 'details',
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      visibility: 'RO',
      section: 'details',
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      },
      section: 'details',
    },
    {
      name: 'summary',
      class: 'String',
      transient: true,
      hidden: true,
      tableCellFormatter: function(value, obj) {
        this.add(obj.title);
      }
    }
  ],

  actions: [
    {
      name: 'close',
      tableWidth: 70,
      confirmationRequired: true,
      code: function() {
        var self = this;
        this.output = '';
        this.status = this.TicketStatus.CLOSED;
        this.ticketDAO.put(this).then(function(ticket) {
          self.copyFrom(ticket);
        });
      }
    },
  ]
});
<commit_msg>Add statusChoices to control which status are offered.<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.ticket',
  name: 'Ticket',

  documentation: 'Ticket Model',

  implements: [
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  requires: [
    'foam.nanos.ticket.TicketStatus'
  ],

  javaImports: [
    'java.util.Date',
  ],

  imports: [
    'controllerMode',
    'userDAO'
  ],

  tableColumns: [
    'id',
    'type',
    // REVIEW: view fails to display when owner in tableColumns
  //  'owner',
    'lastModified',
    'status',
    'summary'
  ],

  sections: [
     {
      name: 'ticketType',
      isAvailable: function(id) { return !! id; },
      order: 1
    },
    {
      name: 'basicInfo',
      title: '',
      order: 2
    },
    {
      name: 'comments',
      title: '',
      order: 3
    },
    {
      name: 'details',
      title: '',
      order: 4
    },
    {
      name: '_defaultSection',
      permissionRequired: true,
      hidden: true
    },
  ],

  properties: [
    {
      class: 'String',
      name: 'type',
      documentation: 'The type of the ticket.',
      transient: true,
      getter: function() {
        return this.cls_.name;
      },
      javaGetter: `
        return getClass().getSimpleName();
      `,
      tableWidth: 135,
      section: 'ticketType',
      visibility: 'RO'
    },
    {
      class: 'Long',
      name: 'id',
      visibility: 'RO',
      section: 'basicInfo',
      order: 1
    },
    {
      name: 'type',
      class: 'String',
      visibility: 'RO',
      storageTransient: true,
      section: 'basicInfo',
      getter: function() {
         return this.cls_.name;
      },
      javaGetter: `
    return getClass().getSimpleName();
      `,
      tableWidth: 160,
      order: 2
    },
    {
      class: 'foam.core.Enum',
      of: 'foam.nanos.ticket.TicketStatus',
      name: 'status',
      value: 'OPEN',
      javaFactory: 'return TicketStatus.OPEN;',
      includeInDigest: true,
      section: 'basicInfo',
      order: 3,
      tableWidth: 130,
      view: function(_, x) {
        // TODO: want regular detail view in VIEW mode.
        if ( this.controllerMode == foam.u2.ControllerMode.VIEW ) {
          return {
            class: 'foam.u2.DetailView'
          };
        } else {
          return {
            class: 'foam.u2.view.ChoiceView',
            choices: x.data.statusChoices
          };
        }
      },
    },
    {
      name: 'statusChoices',
      hidden: true,
      factory: function() {
        var s = [];
        if ( this.status == this.TicketStatus.CLOSED ) {
          s.push([foam.nanos.ticket.TicketStatus.CLOSED.name, foam.nanos.ticket.TicketStatus.CLOSED.label]);
        } else {
          s.push([foam.nanos.ticket.TicketStatus.OPEN.name, foam.nanos.ticket.TicketStatus.OPEN.label]);
        }
        return s;
      },
      documentation: 'Returns available statuses for each ticket depending on current status'
    },
    // REVIEW: can't get this to work.
    // {
    //   name: 'watchers',
    //   class: 'List',
    //   javaType: 'java.util.ArrayList<java.lang.Long>',
    //   view: {
    //     class: 'foam.u2.view.ReferenceArrayView',
    //     daoKey: 'userDAO'
    //   },
    //   section: 'details',
    // },
    {
      class: 'String',
      name: 'title',
      required: true,
      section: 'basicInfo',
      validationPredicate: [
        {
          args: ['title', 'type'],
          predicateFactory: function(e) {
            return e.GT(
              foam.mlang.StringLength.create({
                arg1: foam.nanos.ticket.Ticket.TITLE
              }), 0);
          },
          errorString: 'Please provide a summary of the Ticket.'
        }
      ],
      order: 4
    },
    {
      class: 'String',
      name: 'comment',
      value: '',
    // required: true,
      storageTransient: true,
      section: 'comments',
      validationPredicate: [
        {
          args: ['id', 'title', 'comment'],
          predicateFactory: function(e) {
            return e.OR(
              e.AND(
                e.EQ(foam.nanos.ticket.Ticket.ID, 0),
                e.GT(
                  foam.mlang.StringLength.create({
                    arg1: foam.nanos.ticket.Ticket.TITLE
                  }), 0)
              ),
              e.GT(
              foam.mlang.StringLength.create({
                arg1: foam.nanos.ticket.Ticket.COMMENT
              }), 0)
            );
          },
          errorString: 'Please provide a comment.'
        }
      ],
      order: 1
    },
    {
      class: 'DateTime',
      name: 'created',
      visibility: 'RO',
      includeInDigest: true,
      section: 'details',
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      visibility: 'RO',
      includeInDigest: true,
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      },
      section: 'details',
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      visibility: 'RO',
      section: 'details',
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      },
      section: 'details',
    },
    {
      name: 'summary',
      class: 'String',
      transient: true,
      hidden: true,
      tableCellFormatter: function(value, obj) {
        this.add(obj.title);
      }
    }
  ],

  actions: [
    {
      name: 'close',
      tableWidth: 70,
      confirmationRequired: true,
      code: function() {
        var self = this;
        this.output = '';
        this.status = this.TicketStatus.CLOSED;
        this.ticketDAO.put(this).then(function(ticket) {
          self.copyFrom(ticket);
        });
      }
    },
  ]
});
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name Project
 *
 * @class A Project object in Paper.js is what usually is refered to as the
 * document: The top level object that holds all the items contained in the
 * scene graph. As the term document is already taken in the browser context,
 * it is called Project.
 *
 * Projects allow the manipluation of the styles that are applied to all newly
 * created items, give access to the selected items, and will in future versions
 * offer ways to query for items in the scene graph defining specific
 * requirements, and means to persist and load from different formats, such as
 * SVG and PDF.
 *
 * The currently active project can be accessed through the global
 * {@see PaperScope#project} variable.
 *
 * An array of all open projects is accessible through the global
 * {@see PaperScope#projects} variable.
 */
var Project = this.Project = Base.extend(/** @lends Project# */{
	// TODO: Add arguments to define pages
	/**
	 * Creates a Paper.js project.
	 *
	 * When working with PaperScript, a project is automatically created for us
	 * and the global {@see PaperScope#project} variable points to it.
	 */
	initialize: function() {
		// Store reference to the currently active global paper scope:
		this._scope = paper;
		// Push it onto this._scope.projects and set index:
		this._index = this._scope.projects.push(this) - 1;
		this._currentStyle = new PathStyle();
		this._selectedItems = {};
		this._selectedItemCount = 0;
		// Activate straight away so paper.project is set, as required by
		// Layer and DoumentView constructors.
		this.activate();
		this.layers = [];
		this.symbols = [];
		this.activeLayer = new Layer();
	},

	_needsRedraw: function() {
		if (this._scope)
			this._scope._needsRedraw();
	},

	/**
	 * The currently active path style. All selected items and newly
	 * created items will be styled with this style.
	 *
	 * @type PathStyle
	 * @bean
	 *
	 * @example {@paperscript}
	 * project.currentStyle = {
	 * 	fillColor: 'red',
	 * 	strokeColor: 'black',
	 * 	strokeWidth: 5
	 * }
	 *
	 * // The following paths will take over all style properties of
	 * // the current style:
	 * var path = new Path.Circle(new Point(75, 50), 30);
	 * var path2 = new Path.Circle(new Point(175, 50), 20);
	 *
	 * @example {@paperscript}
	 * project.currentStyle.fillColor = 'red';
	 *
	 * // The following path will take over the fill color we just set:
	 * var path = new Path.Circle(new Point(75, 50), 30);
	 * var path2 = new Path.Circle(new Point(175, 50), 20);
	 */
	getCurrentStyle: function() {
		return this._currentStyle;
	},

	setCurrentStyle: function(style) {
		// TODO: Style selected items with the style:
		this._currentStyle.initialize(style);
	},

	/**
	 * Activates this project, so all newly created items will be placed
	 * in it.
	 */
	activate: function() {
		if (this._scope) {
			this._scope.project = this;
			return true;
		}
		return false;
	},

	/**
	 * Removes this project from the global {@see PaperScope#projects} list.
	 */
	remove: function() {
		if (this._scope) {
			Base.splice(this._scope.projects, null, this._index, 1);
			// Clear the active project reference if it was pointint to this.
			if (this._scope.project == this)
				this._scope.project = null;
			this._scope = null;
			return true;
		}
		return false;
	},

	/**
	 * The index of the project in the global projects array.
	 *
	 * @type Number
	 * @bean
	 */
	getIndex: function() {
		return this._index;
	},

	/**
	 * The selected items contained within the project.
	 *
	 * @type Item[]
	 * @bean
	 */
	getSelectedItems: function() {
		// TODO: Return groups if their children are all selected,
		// and filter out their children from the list.
		// TODO: The order of these items should be that of their
		// drawing order.
		var items = [];
		Base.each(this._selectedItems, function(item) {
			items.push(item);
		});
		return items;
	},

	// TODO: Implement setSelectedItems?

	_updateSelection: function(item) {
		if (item._selected) {
			this._selectedItemCount++;
			this._selectedItems[item.getId()] = item;
		} else {
			this._selectedItemCount--;
			delete this._selectedItems[item.getId()];
		}
	},

	/**
	 * Selects all items in the project.
	 */
	selectAll: function() {
		for (var i = 0, l = this.layers.length; i < l; i++)
			this.layers[i].setSelected(true);
	},

	/**
	 * Deselects all selected items in the project.
	 */
	deselectAll: function() {
		for (var i in this._selectedItems)
			this._selectedItems[i].setSelected(false);
	},

	hitTest: function(point, options) {
		options = HitResult.getOptions(point, options);
		point = options.point;
		// Loop backwards, so layers that get drawn last are tested first
		for (var i = this.layers.length - 1; i >= 0; i--) {
			var res = this.layers[i].hitTest(point, options);
			if (res) return res;
		}
		return null;
	},

	/**
	 * {@grouptitle Project Hierarchy}
	 *
	 * The layers contained within the project.
	 *
	 * @name Project#layers
	 * @type Layer[]
	 */

	/**
	 * The layer which is currently active. New items will be created on this
	 * layer by default.
	 *
	 * @name Project#activeLayer
	 * @type Layer
	 */

	/**
	 * The symbols contained within the project.
	 *
	 * @name Project#symbols
	 * @type Symbol[]
	 */

	/**
	 * The views contained within the project.
	 *
	 * @name Project#views
	 * @type View[]
	 */

	/**
	 * The view which is currently active.
	 *
	 * @name Project#activeView
	 * @type View
	 */

	draw: function(ctx) {
		ctx.save();
		var param = { offset: new Point(0, 0) };
		for (var i = 0, l = this.layers.length; i < l; i++)
			Item.draw(this.layers[i], ctx, param);
		ctx.restore();

		// Draw the selection of the selected items in the project:
		if (this._selectedItemCount > 0) {
			ctx.save();
			ctx.strokeWidth = 1;
			// TODO: use Layer#color
			ctx.strokeStyle = ctx.fillStyle = '#009dec';
			param = { selection: true };
			Base.each(this._selectedItems, function(item) {
				item.draw(ctx, param);
			});
			ctx.restore();
		}
	}
});
<commit_msg>Fix links and typos.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name Project
 *
 * @class A Project object in Paper.js is what usually is referred to as the
 * document: The top level object that holds all the items contained in the
 * scene graph. As the term document is already taken in the browser context,
 * it is called Project.
 *
 * Projects allow the manipluation of the styles that are applied to all newly
 * created items, give access to the selected items, and will in future versions
 * offer ways to query for items in the scene graph defining specific
 * requirements, and means to persist and load from different formats, such as
 * SVG and PDF.
 *
 * The currently active project can be accessed through the
 * {@link PaperScope#project} variable.
 *
 * An array of all open projects is accessible through the
 * {@link PaperScope#projects} variable.
 */
var Project = this.Project = Base.extend(/** @lends Project# */{
	// TODO: Add arguments to define pages
	/**
	 * Creates a Paper.js project.
	 *
	 * When working with PaperScript, a project is automatically created for us
	 * and the {@link PaperScope#project} variable points to it.
	 */
	initialize: function() {
		// Store reference to the currently active global paper scope:
		this._scope = paper;
		// Push it onto this._scope.projects and set index:
		this._index = this._scope.projects.push(this) - 1;
		this._currentStyle = new PathStyle();
		this._selectedItems = {};
		this._selectedItemCount = 0;
		// Activate straight away so paper.project is set, as required by
		// Layer and DoumentView constructors.
		this.activate();
		this.layers = [];
		this.symbols = [];
		this.activeLayer = new Layer();
	},

	_needsRedraw: function() {
		if (this._scope)
			this._scope._needsRedraw();
	},

	/**
	 * The currently active path style. All selected items and newly
	 * created items will be styled with this style.
	 *
	 * @type PathStyle
	 * @bean
	 *
	 * @example {@paperscript}
	 * project.currentStyle = {
	 * 	fillColor: 'red',
	 * 	strokeColor: 'black',
	 * 	strokeWidth: 5
	 * }
	 *
	 * // The following paths will take over all style properties of
	 * // the current style:
	 * var path = new Path.Circle(new Point(75, 50), 30);
	 * var path2 = new Path.Circle(new Point(175, 50), 20);
	 *
	 * @example {@paperscript}
	 * project.currentStyle.fillColor = 'red';
	 *
	 * // The following path will take over the fill color we just set:
	 * var path = new Path.Circle(new Point(75, 50), 30);
	 * var path2 = new Path.Circle(new Point(175, 50), 20);
	 */
	getCurrentStyle: function() {
		return this._currentStyle;
	},

	setCurrentStyle: function(style) {
		// TODO: Style selected items with the style:
		this._currentStyle.initialize(style);
	},

	/**
	 * Activates this project, so all newly created items will be placed
	 * in it.
	 */
	activate: function() {
		if (this._scope) {
			this._scope.project = this;
			return true;
		}
		return false;
	},

	/**
	 * Removes this project from the {@link PaperScope#projects} list.
	 */
	remove: function() {
		if (this._scope) {
			Base.splice(this._scope.projects, null, this._index, 1);
			// Clear the active project reference if it was pointint to this.
			if (this._scope.project == this)
				this._scope.project = null;
			this._scope = null;
			return true;
		}
		return false;
	},

	/**
	 * The index of the project in the {@link PaperScope#projects} list.
	 *
	 * @type Number
	 * @bean
	 */
	getIndex: function() {
		return this._index;
	},

	/**
	 * The selected items contained within the project.
	 *
	 * @type Item[]
	 * @bean
	 */
	getSelectedItems: function() {
		// TODO: Return groups if their children are all selected,
		// and filter out their children from the list.
		// TODO: The order of these items should be that of their
		// drawing order.
		var items = [];
		Base.each(this._selectedItems, function(item) {
			items.push(item);
		});
		return items;
	},

	// TODO: Implement setSelectedItems?

	_updateSelection: function(item) {
		if (item._selected) {
			this._selectedItemCount++;
			this._selectedItems[item.getId()] = item;
		} else {
			this._selectedItemCount--;
			delete this._selectedItems[item.getId()];
		}
	},

	/**
	 * Selects all items in the project.
	 */
	selectAll: function() {
		for (var i = 0, l = this.layers.length; i < l; i++)
			this.layers[i].setSelected(true);
	},

	/**
	 * Deselects all selected items in the project.
	 */
	deselectAll: function() {
		for (var i in this._selectedItems)
			this._selectedItems[i].setSelected(false);
	},

	hitTest: function(point, options) {
		options = HitResult.getOptions(point, options);
		point = options.point;
		// Loop backwards, so layers that get drawn last are tested first
		for (var i = this.layers.length - 1; i >= 0; i--) {
			var res = this.layers[i].hitTest(point, options);
			if (res) return res;
		}
		return null;
	},

	/**
	 * {@grouptitle Project Hierarchy}
	 *
	 * The layers contained within the project.
	 *
	 * @name Project#layers
	 * @type Layer[]
	 */

	/**
	 * The layer which is currently active. New items will be created on this
	 * layer by default.
	 *
	 * @name Project#activeLayer
	 * @type Layer
	 */

	/**
	 * The symbols contained within the project.
	 *
	 * @name Project#symbols
	 * @type Symbol[]
	 */

	/**
	 * The views contained within the project.
	 *
	 * @name Project#views
	 * @type View[]
	 */

	/**
	 * The view which is currently active.
	 *
	 * @name Project#activeView
	 * @type View
	 */

	draw: function(ctx) {
		ctx.save();
		var param = { offset: new Point(0, 0) };
		for (var i = 0, l = this.layers.length; i < l; i++)
			Item.draw(this.layers[i], ctx, param);
		ctx.restore();

		// Draw the selection of the selected items in the project:
		if (this._selectedItemCount > 0) {
			ctx.save();
			ctx.strokeWidth = 1;
			// TODO: use Layer#color
			ctx.strokeStyle = ctx.fillStyle = '#009dec';
			param = { selection: true };
			Base.each(this._selectedItems, function(item) {
				item.draw(ctx, param);
			});
			ctx.restore();
		}
	}
});
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var Project = this.Project = Base.extend({
	/** @lends Project# */

	beans: true,

	// TODO: Add arguments to define pages
	// DOCS: document Project constructor and class
	/**
	 * Creates a Paper.js project
	 *
	 * @name Project
	 * @constructor
	 *
	 * @class The Project item refers to..
	 *
	 * The currently active project can be accessed through the global {@code
	 * project} variable.
	 *
	 * An array of all open projects is accessible through the global {@code
	 * projects} variable.
	 */
	initialize: function() {
		// Store reference to the currently active global paper scope:
		this._scope = paper;
		// Push it onto this._scope.projects and set index:
		this._index = this._scope.projects.push(this) - 1;
		this._currentStyle = PathStyle.create(null);
		this._selectedItems = {};
		this._selectedItemCount = 0;
		// Activate straight away so paper.project is set, as required by
		// Layer and DoumentView constructors.
		this.activate();
		this.layers = [];
		this.symbols = [];
		this.activeLayer = new Layer();
	},

	/**
	 * The currently active path style. All selected items and newly
	 * created items will be styled with this style.
	 *
	 * @type PathStyle
	 * @bean
	 */
	getCurrentStyle: function() {
		return this._currentStyle;
	},

	// TODO: style selected items with the style:
	setCurrentStyle: function(style) {
		this._currentStyle.initialize(style);
	},

	/**
	 * Activates this project, so all newly created items will be placed
	 * in it.
	 */
	activate: function() {
		if (this._index != null) {
			this._scope.project = this;
			return true;
		}
		return false;
	},

	remove: function() {
		var res = Base.splice(this._scope.projects, null, this._index, 1);
		this._scope = null;
		return !!res.length;
	},

	/**
	 * The index of the project in the global projects array.
	 *
	 * @type Number
	 * @bean
	 */
	getIndex: function() {
		return this._index;
	},

	/**
	 * The selected items contained within the project.
	 *
	 * @type Item[]
	 * @bean
	 */
	getSelectedItems: function() {
		// TODO: return groups if their children are all selected,
		// and filter out their children from the list.
		// TODO: the order of these items should be that of their
		// drawing order.
		var items = [];
		Base.each(this._selectedItems, function(item) {
			items.push(item);
		});
		return items;
	},

	// TODO: implement setSelectedItems?

	_selectItem: function(item, select) {
		if (select) {
			this._selectedItemCount++;
			this._selectedItems[item.getId()] = item;
		} else {
			this._selectedItemCount--;
			delete this._selectedItems[item.getId()];
		}
	},

	/**
	 * Selects all items in the project.
	 */
	selectAll: function() {
		for (var i = 0, l = this.layers.length; i < l; i++)
			this.layers[i].setSelected(true);
	},

	/**
	 * Deselects all selected items in the project.
	 */
	deselectAll: function() {
		// TODO: is using for var i in good practice?
		// or should we use Base.each? (JP)
		for (var i in this._selectedItems)
			this._selectedItems[i].setSelected(false);
	},

	/**
	 * {@grouptitle Project Hierarchy}
	 *
	 * The layers contained within the project.
	 *
	 * @name Project#layers
	 * @type Layer[]
	 */

	/**
	 * The layer which is currently active. New items will be created on this
	 * layer by default.
	 *
	 * @name Project#activeLayer
	 * @type Layer
	 */

	/**
	 * The symbols contained within the project.
	 *
	 * @name Project#symbols
	 * @type Symbol[]
	 */

	/**
	 * The views contained within the project.
	 *
	 * @name Project#views
	 * @type View[]
	 */

	/**
	 * The view which is currently active.
	 *
	 * @name Project#activeView
	 * @type View
	 */

	draw: function(ctx) {
		ctx.save();
		var param = { offset: new Point(0, 0) };
		for (var i = 0, l = this.layers.length; i < l; i++)
			Item.draw(this.layers[i], ctx, param);
		ctx.restore();

		// Draw the selection of the selected items in the project:
		if (this._selectedItemCount > 0) {
			ctx.save();
			ctx.strokeWidth = 1;
			// TODO: use Layer#color
			ctx.strokeStyle = ctx.fillStyle = '#009dec';
			param = { selection: true };
			Base.each(this._selectedItems, function(item) {
				item.draw(ctx, param);
			});
			ctx.restore();
		}
	},

	/**
	 * @deprecated
	 * @ignore
	 */
	redraw: function() {
		this._scope.view.draw();
	}
});
<commit_msg>Set default styles for Project#currentStyle.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var Project = this.Project = Base.extend({
	/** @lends Project# */

	beans: true,

	// TODO: Add arguments to define pages
	// DOCS: document Project constructor and class
	/**
	 * Creates a Paper.js project
	 *
	 * @name Project
	 * @constructor
	 *
	 * @class The Project item refers to..
	 *
	 * The currently active project can be accessed through the global {@code
	 * project} variable.
	 *
	 * An array of all open projects is accessible through the global {@code
	 * projects} variable.
	 */
	initialize: function() {
		// Store reference to the currently active global paper scope:
		this._scope = paper;
		// Push it onto this._scope.projects and set index:
		this._index = this._scope.projects.push(this) - 1;
		this._currentStyle = PathStyle.create(null);
		this.setCurrentStyle({
			strokeWidth: 1,
			strokeCap: 'butt',
			strokeJoin: 'miter',
			miterLimit: 10,
			dashOffset: 0,
			dashArray: []
		});
		this._selectedItems = {};
		this._selectedItemCount = 0;
		// Activate straight away so paper.project is set, as required by
		// Layer and DoumentView constructors.
		this.activate();
		this.layers = [];
		this.symbols = [];
		this.activeLayer = new Layer();
	},

	/**
	 * The currently active path style. All selected items and newly
	 * created items will be styled with this style.
	 *
	 * @type PathStyle
	 * @bean
	 */
	getCurrentStyle: function() {
		return this._currentStyle;
	},

	// TODO: style selected items with the style:
	setCurrentStyle: function(style) {
		this._currentStyle.initialize(style);
	},

	/**
	 * Activates this project, so all newly created items will be placed
	 * in it.
	 */
	activate: function() {
		if (this._index != null) {
			this._scope.project = this;
			return true;
		}
		return false;
	},

	remove: function() {
		var res = Base.splice(this._scope.projects, null, this._index, 1);
		this._scope = null;
		return !!res.length;
	},

	/**
	 * The index of the project in the global projects array.
	 *
	 * @type Number
	 * @bean
	 */
	getIndex: function() {
		return this._index;
	},

	/**
	 * The selected items contained within the project.
	 *
	 * @type Item[]
	 * @bean
	 */
	getSelectedItems: function() {
		// TODO: return groups if their children are all selected,
		// and filter out their children from the list.
		// TODO: the order of these items should be that of their
		// drawing order.
		var items = [];
		Base.each(this._selectedItems, function(item) {
			items.push(item);
		});
		return items;
	},

	// TODO: implement setSelectedItems?

	_selectItem: function(item, select) {
		if (select) {
			this._selectedItemCount++;
			this._selectedItems[item.getId()] = item;
		} else {
			this._selectedItemCount--;
			delete this._selectedItems[item.getId()];
		}
	},

	/**
	 * Selects all items in the project.
	 */
	selectAll: function() {
		for (var i = 0, l = this.layers.length; i < l; i++)
			this.layers[i].setSelected(true);
	},

	/**
	 * Deselects all selected items in the project.
	 */
	deselectAll: function() {
		// TODO: is using for var i in good practice?
		// or should we use Base.each? (JP)
		for (var i in this._selectedItems)
			this._selectedItems[i].setSelected(false);
	},

	/**
	 * {@grouptitle Project Hierarchy}
	 *
	 * The layers contained within the project.
	 *
	 * @name Project#layers
	 * @type Layer[]
	 */

	/**
	 * The layer which is currently active. New items will be created on this
	 * layer by default.
	 *
	 * @name Project#activeLayer
	 * @type Layer
	 */

	/**
	 * The symbols contained within the project.
	 *
	 * @name Project#symbols
	 * @type Symbol[]
	 */

	/**
	 * The views contained within the project.
	 *
	 * @name Project#views
	 * @type View[]
	 */

	/**
	 * The view which is currently active.
	 *
	 * @name Project#activeView
	 * @type View
	 */

	draw: function(ctx) {
		ctx.save();
		var param = { offset: new Point(0, 0) };
		for (var i = 0, l = this.layers.length; i < l; i++)
			Item.draw(this.layers[i], ctx, param);
		ctx.restore();

		// Draw the selection of the selected items in the project:
		if (this._selectedItemCount > 0) {
			ctx.save();
			ctx.strokeWidth = 1;
			// TODO: use Layer#color
			ctx.strokeStyle = ctx.fillStyle = '#009dec';
			param = { selection: true };
			Base.each(this._selectedItems, function(item) {
				item.draw(ctx, param);
			});
			ctx.restore();
		}
	},

	/**
	 * @deprecated
	 * @ignore
	 */
	redraw: function() {
		this._scope.view.draw();
	}
});
<|endoftext|>


<commit_before>import { Component, DefaultDOMElement, platform } from 'substance'
import { EditorPackage as TextureEditorPackage } from 'substance-texture'
import SheetEditor from '../sheet/SheetEditor'
import ContextPane from './ContextPane'
import { addNewDocument } from './ProjectManipulations'

export default class Project extends Component {

  constructor(...args) {
    super(...args)

    // Store the viewports, so we can restore scroll positions
    this._viewports = {}

    this.appState = {
      reproduce: false
    }
  }

  didMount() {
    this.handleActions({
      'addDocument': this._addDocument,
      'openDocument': this._openDocument,
      'removeDocument': this._removeDocument,
      'updateDocumentName': this._updateDocumentName,
      'closeContext': this._closeContext,
      'openHelp': this._openHelp,
      'toggleHelp': this._toggleHelp,
      'toggleHosts': this._toggleHosts,
      'toggleReproduce': this._toggleReproduce
    })

    if (platform.inBrowser) {
      this.documentEl = DefaultDOMElement.wrapNativeElement(document)
      this.documentEl.on('keydown', this.onKeyDown, this)
    }

  }

  willUpdateState() {
    let oldDocumentId = this.state.documentId
    this._viewports[oldDocumentId] = this.refs.editor.getViewport()
  }

  _dispose() {
    if (platform.inBrowser) {
      this.documentEl.off(this)
    }
  }

  getInitialState() {
    let activeDocument = this._getActiveDocument()
    return {
      documentId: activeDocument.id
    }
  }

  getChildContext() {
    // ATTENTION: we should be careful with adding things here.
    // If something is missing, we likely should fix it somewhere else.
    // Add only project related things here.
    // One example for what better not to add: 'pubMetaDbSession'.
    // This is passed to Texture as prop which in turn exposes it via childContext.
    return {
      documentArchive: this.props.documentArchive,
      urlResolver: this.props.documentArchive,
      appState: this.appState
    }
  }

  render($$) {
    let el = $$('div').addClass('sc-project')
    el.append(
      $$('div').addClass('se-main-pane').append(
        this._renderEditorPane($$),
        $$(ContextPane, {
          contextId: this._contextId,
          contextProps: this._contextProps
        }).ref('contextPane')
      )
      // $$(ProjectBar, {
      //   contextId: this._contextId,
      //   documentId: this.state.documentId,
      //   archive: this.props.documentArchive
      // }).ref('projectBar')
    )
    return el
  }

  _getPubMetaDbSession() {
    return this._getDocumentArchive().getEditorSession('pub-meta')
  }

  _getActiveDocument() {
    let archive = this._getDocumentArchive()
    let firstEntry = archive.getDocumentEntries()[0]
    return firstEntry
  }

  _getActiveEditorSession() {
    let documentId = this.state.documentId
    return this.props.documentArchive.getEditorSession(documentId)
  }

  _getDocumentArchive() {
    return this.props.documentArchive
  }

  _getDocumentRecordById(id) {
    let dc = this._getDocumentArchive()
    let entries = dc.getDocumentEntries()
    return entries.find(e => e.id === id)
  }

  _renderEditorPane($$) {
    let el = $$('div').addClass('se-editor-pane')
    let documentId = this.state.documentId
    let documentRecord = this._getDocumentRecordById(documentId)
    let documentType = documentRecord.type
    let viewport = this._viewports[documentId]
    let da = this._getDocumentArchive()
    let editorSession = da.getEditorSession(documentId)

    if (documentType === 'article') {
      el.append(
        $$(TextureEditorPackage.Editor, {
          viewport,
          editorSession,
          pubMetaDbSession: this._getPubMetaDbSession(),
          disabled: true
        }).ref('editor')
          .addClass('sc-article-editor')
      )
    } else if (documentType === 'sheet') {
      el.append(
        $$(SheetEditor, {
          viewport,
          editorSession
        }).ref('editor')
      )
    }
    return el
  }

  _addDocument(type) {
    let archive = this._getDocumentArchive()
    let newDocumentId = addNewDocument(archive, type)
    this._openDocument(newDocumentId)
  }

  _openDocument(documentId) {
    this.extendState({
      documentId: documentId
    })
  }

  _updateDocumentName(documentId, name) { // eslint-disable-line no-unused-vars
    let archive = this._getDocumentArchive()
    archive.renameDocument(documentId, name)
    this.refs.projectBar.rerender()
  }

  _removeDocument(documentId) { // eslint-disable-line no-unused-vars
    let archive = this._getDocumentArchive()
    let documentEntries = archive.getDocumentEntries()
    if (documentEntries.length > 1) {
      archive.removeDocument(documentId)
      let firstDocument = this._getActiveDocument()
      this.extendState({
        documentId: firstDocument.id
      })
    } else {
      console.warn('Not allowed to delete the last document in the archive. Skipping.')
    }
  }

  /*
    E.g. _openHelp('function/sum')
  */
  _openHelp(page) {
    this._contextId = 'help'
    this._contextProps = { page }
    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  _closeContext() {
    this._contextId = undefined
    this._contextProps = undefined
    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  /*
    Either hide help or show function index
  */
  _toggleHelp() {
    let contextId = this._contextId
    if (contextId === 'help') {
      this._contextId = undefined
      this._contextProps = undefined
    } else {
      this._contextId = 'help'
      this._contextProps = { page: 'function/index'}
    }
    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  _toggleReproduce() {
    this.appState.reproduce = !this.appState.reproduce

    // Update all cell nodes in the document
    let cellComps = this.findAll('.sc-cell')
    cellComps.forEach((cellComponent) => {
      cellComponent.extendState({
        hideCodeToggle: !this.appState.reproduce
      })
    })

  }

  /*
    Either open or hide hosts connection information
  */
  _toggleHosts() {
    let contextId = this._contextId
    if (contextId === 'hosts') {
      this._contextId = undefined
      this._contextProps = undefined
    } else {
      this._contextId = 'hosts'
      this._contextProps = { page: 'hosts' }
    }

    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  onKeyDown(event) {
    // ignore fake IME events (emitted in IE and Chromium)
    if ( event.key === 'Dead' ) return
    // Handle custom keyboard shortcuts globally
    let editorSession = this._getActiveEditorSession()
    let custom = editorSession.keyboardManager.onKeydown(event)
    return custom
  }

}
<commit_msg>Starting the Engine.<commit_after>import { Component, DefaultDOMElement, platform } from 'substance'
import { EditorPackage as TextureEditorPackage } from 'substance-texture'
import SheetEditor from '../sheet/SheetEditor'
import ContextPane from './ContextPane'
import { addNewDocument } from './ProjectManipulations'
import { _initStencilaArchive } from '../stencilaAppHelpers'

export default class Project extends Component {

  constructor(...args) {
    super(...args)

    // Store the viewports, so we can restore scroll positions
    this._viewports = {}

    this.appState = {
      reproduce: false,
      engineRunning: false
    }
  }

  didMount() {
    this.handleActions({
      'addDocument': this._addDocument,
      'openDocument': this._openDocument,
      'removeDocument': this._removeDocument,
      'updateDocumentName': this._updateDocumentName,
      'closeContext': this._closeContext,
      'openHelp': this._openHelp,
      'toggleHelp': this._toggleHelp,
      'toggleHosts': this._toggleHosts,
      'toggleReproduce': this._toggleReproduce
    })

    if (platform.inBrowser) {
      this.documentEl = DefaultDOMElement.wrapNativeElement(document)
      this.documentEl.on('keydown', this.onKeyDown, this)
    }

  }

  willUpdateState() {
    let oldDocumentId = this.state.documentId
    this._viewports[oldDocumentId] = this.refs.editor.getViewport()
  }

  _dispose() {
    if (platform.inBrowser) {
      this.documentEl.off(this)
    }
  }

  getInitialState() {
    let activeDocument = this._getActiveDocument()
    return {
      documentId: activeDocument.id
    }
  }

  getChildContext() {
    // ATTENTION: we should be careful with adding things here.
    // If something is missing, we likely should fix it somewhere else.
    // Add only project related things here.
    // One example for what better not to add: 'pubMetaDbSession'.
    // This is passed to Texture as prop which in turn exposes it via childContext.
    return {
      documentArchive: this.props.documentArchive,
      urlResolver: this.props.documentArchive,
      appState: this.appState
    }
  }

  render($$) {
    let el = $$('div').addClass('sc-project')
    el.append(
      $$('div').addClass('se-main-pane').append(
        this._renderEditorPane($$),
        $$(ContextPane, {
          contextId: this._contextId,
          contextProps: this._contextProps
        }).ref('contextPane')
      )
      // $$(ProjectBar, {
      //   contextId: this._contextId,
      //   documentId: this.state.documentId,
      //   archive: this.props.documentArchive
      // }).ref('projectBar')
    )
    return el
  }

  _getPubMetaDbSession() {
    return this._getDocumentArchive().getEditorSession('pub-meta')
  }

  _getActiveDocument() {
    let archive = this._getDocumentArchive()
    let firstEntry = archive.getDocumentEntries()[0]
    return firstEntry
  }

  _getActiveEditorSession() {
    let documentId = this.state.documentId
    return this.props.documentArchive.getEditorSession(documentId)
  }

  _getDocumentArchive() {
    return this.props.documentArchive
  }

  _getDocumentRecordById(id) {
    let dc = this._getDocumentArchive()
    let entries = dc.getDocumentEntries()
    return entries.find(e => e.id === id)
  }

  _renderEditorPane($$) {
    let el = $$('div').addClass('se-editor-pane')
    let documentId = this.state.documentId
    let documentRecord = this._getDocumentRecordById(documentId)
    let documentType = documentRecord.type
    let viewport = this._viewports[documentId]
    let da = this._getDocumentArchive()
    let editorSession = da.getEditorSession(documentId)

    if (documentType === 'article') {
      el.append(
        $$(TextureEditorPackage.Editor, {
          viewport,
          editorSession,
          pubMetaDbSession: this._getPubMetaDbSession(),
          disabled: true
        }).ref('editor')
          .addClass('sc-article-editor')
      )
    } else if (documentType === 'sheet') {
      el.append(
        $$(SheetEditor, {
          viewport,
          editorSession
        }).ref('editor')
      )
    }
    return el
  }

  _addDocument(type) {
    let archive = this._getDocumentArchive()
    let newDocumentId = addNewDocument(archive, type)
    this._openDocument(newDocumentId)
  }

  _openDocument(documentId) {
    this.extendState({
      documentId: documentId
    })
  }

  _updateDocumentName(documentId, name) { // eslint-disable-line no-unused-vars
    let archive = this._getDocumentArchive()
    archive.renameDocument(documentId, name)
    this.refs.projectBar.rerender()
  }

  _removeDocument(documentId) { // eslint-disable-line no-unused-vars
    let archive = this._getDocumentArchive()
    let documentEntries = archive.getDocumentEntries()
    if (documentEntries.length > 1) {
      archive.removeDocument(documentId)
      let firstDocument = this._getActiveDocument()
      this.extendState({
        documentId: firstDocument.id
      })
    } else {
      console.warn('Not allowed to delete the last document in the archive. Skipping.')
    }
  }

  /*
    E.g. _openHelp('function/sum')
  */
  _openHelp(page) {
    this._contextId = 'help'
    this._contextProps = { page }
    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  _closeContext() {
    this._contextId = undefined
    this._contextProps = undefined
    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  /*
    Either hide help or show function index
  */
  _toggleHelp() {
    let contextId = this._contextId
    if (contextId === 'help') {
      this._contextId = undefined
      this._contextProps = undefined
    } else {
      this._contextId = 'help'
      this._contextProps = { page: 'function/index'}
    }
    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  _toggleReproduce () {
    // TODO: we should update the state after the engine has been
    // started successfully
    let reproduce = !this.appState.reproduce
    this.appState.reproduce = reproduce
    if (reproduce && !this.appState.engineRunning) {
      this._launchExecutionEngine().then(running => {
        if (!running) {
          this._toggleReproduce()
        }
      })
    }
    this._updateCellComponents()
  }

  _launchExecutionEngine () {
    return new Promise((resolve, reject) => {
      resolve(window.confirm('Start the Engine?'))
    }).then(yesPlease => {
      if (yesPlease) {
        const archive = this.props.documentArchive
        return _initStencilaArchive(archive, this.context).then(() => {
          this.appState.engineRunning = true
          return true
        })
      }
      return false
    })
  }

  _updateCellComponents () {
    // Update all cell nodes in the document
    let cellComps = this.findAll('.sc-cell')
    cellComps.forEach((cellComponent) => {
      cellComponent.extendState({
        hideCodeToggle: !this.appState.reproduce,
        hideCode: true
      })
    })
  }

  /*
    Either open or hide hosts connection information
  */
  _toggleHosts() {
    let contextId = this._contextId
    if (contextId === 'hosts') {
      this._contextId = undefined
      this._contextProps = undefined
    } else {
      this._contextId = 'hosts'
      this._contextProps = { page: 'hosts' }
    }

    this.refs.contextPane.extendProps({
      contextId: this._contextId,
      contextProps: this._contextProps
    })
    this.refs.projectBar.extendProps({
      contextId: this._contextId
    })
  }

  onKeyDown(event) {
    // ignore fake IME events (emitted in IE and Chromium)
    if ( event.key === 'Dead' ) return
    // Handle custom keyboard shortcuts globally
    let editorSession = this._getActiveEditorSession()
    let custom = editorSession.keyboardManager.onKeydown(event)
    return custom
  }

}
<|endoftext|>


<commit_before>const deltasLastIndex = 2
const transform = 'transform'
var isScrolling

const defaults = {
  direction: 'y',
  getOffsetSize: ({ currentTarget }) => currentTarget.parentNode.clientHeight,
  getScrollSize: ({ currentTarget }) => currentTarget.scrollHeight,
  getTarget: ({ currentTarget }) => currentTarget
}

const scrollInit = currentTarget => {
  if (!('scrollManager' in currentTarget)) {
    const settings = currentTarget._.scrollSettings
    const scrollManager = {
      getOffsetSize: settings.getOffsetSize || defaults.getOffsetSize,
      getScrollSize: settings.getScrollSize || defaults.getScrollSize,
      getTarget: settings.getTarget || defaults.getTarget,
      direction: settings.direction || defaults.direction,
      state: currentTarget._s,
      currentTarget,
    }
    if ('onScroll' in settings) scrollManager.onScroll = settings.onScroll
    currentTarget.addEventListener('touchmove', onTouchMove, false)
    currentTarget.scrollManager = scrollManager
  }
  return currentTarget.scrollManager
}

const scrollStart = scroll => {
  scroll.target = scroll.getTarget(scroll)
  scroll.deltaSize = scroll.getOffsetSize(scroll) - scroll.getScrollSize(scroll)

  if (scroll.deltaSize) {
    scroll.deltasIndex = 0
    scroll.deltas = [0,0,0]
    scroll.position = scroll.position || 0
    scroll.style = scroll.target.style
    return true
  }
}

const scrollMove = (scroll, position) => {
  var withinBounds
  if (position > 0) {
    position = 0
  } else if (position < scroll.deltaSize) {
    position = scroll.deltaSize
  } else {
    withinBounds = true
  }

  scroll.position = position
  scroll.style[transform] = scroll.direction === 'y'
    ? `translate3d(0, ${position}px, 0)`
    : `translate3d(${position}px, 0, 0)`

  return withinBounds
}

const scrollEnd = scroll => {
  var delta = 0
  var i = deltasLastIndex
  while (i) { delta += scroll.deltas[i--] }
  delta /= deltasLastIndex + 1
  isScrolling = false
  ;(function ease () {
    delta *= 0.95
    if (delta > 0.5 || delta < -0.5) {
      scroll.isScrolling = scrollMove(scroll, scroll.position + delta) &&
        global.requestAnimationFrame(ease)
    } else {
      scroll.isScrolling = false
    }
    if ('onScroll' in scroll) scroll.onScroll(scroll)
  })()
}

const onTouchStart = ({ target, event }) => {
  const scroll = scrollInit(target, event)
  if (scroll.isScrolling) {
    global.cancelAnimationFrame(scroll.isScrolling)
    scroll.isScrolling = false
  }
  if (!isScrolling) {
    const e = event.changedTouches[0]
    if (scroll.direction === 'y') {
      scroll.clientPos = e.clientY
      scroll.oppositePos = e.clientX
    } else {
      scroll.clientPos = e.clientX
      scroll.oppositePos = e.clientY
    }

    scroll.canScroll = scrollStart(scroll)
  }
}

const onTouchMove = e => {
  const scroll = e.currentTarget.scrollManager
  if (scroll.canScroll) {
    const clientPos = scroll.direction === 'y'
      ? e.changedTouches[0].clientY
      : e.changedTouches[0].clientX
    const delta = clientPos - scroll.clientPos

    if (!scroll.isScrolling) {
      const oppositePos = scroll.direction === 'y'
      ? e.changedTouches[0].clientX
      : e.changedTouches[0].clientY
      if (Math.abs(delta) > Math.abs(oppositePos - scroll.oppositePos)) {
        scroll.isScrolling = true
        isScrolling = true
      } else {
        scroll.canScroll = false
        return
      }
    }

    const deltasIndex = scroll.deltasIndex
    scroll.deltasIndex = deltasIndex === deltasLastIndex ? 0 : deltasIndex + 1
    scroll.deltas[deltasIndex] = scrollMove(scroll, scroll.position + delta) ? delta : 0
    scroll.clientPos = clientPos
    scroll.timeStamp = e.timeStamp

    if ('onScroll' in scroll) scroll.onScroll(scroll)
  }
}

const onTouchEnd = ({ target }) => {
  const scroll = target.scrollManager
  if (scroll.isScrolling) {
    scrollEnd(scroll)
  }
}

const scrollTo = (node, position, animate) => {
  const scroll = scrollInit(node)
  if (animate) {

  } else {
    if (scrollStart(scroll)) {
      scrollMove(scroll, position)
      scrollEnd(scroll)
    }
  }
}

export default {
  props: {
    scroll (t, scrollSettings) {
      t.set({
        define: {
          scrollTo,
          scrollSettings
        },
        on: {
          touchstart: { scroll: onTouchStart },
          touchend: { scroll: onTouchEnd }
        }
      }, false)
    }
  }
}
<commit_msg>got some scroll<commit_after>const deltasLastIndex = 2
const transform = 'transform'
const abs = Math.abs

const defaults = {
  direction: 'y',
  getOffsetSize: ({ target }) => target.parentNode.clientHeight,
  getScrollSize: ({ target }) => target.scrollHeight,
  getTarget: ({ currentTarget }) => currentTarget
}

const getScrollManager = currentTarget => {
  var scroll
  if (!('scrollManager' in currentTarget)) {
    const settings = currentTarget._.scrollSettings
    scroll = {
      getOffsetSize: settings.getOffsetSize || defaults.getOffsetSize,
      getScrollSize: settings.getScrollSize || defaults.getScrollSize,
      getTarget: settings.getTarget || defaults.getTarget,
      direction: settings.direction || defaults.direction,
      state: currentTarget._s,
      timeStamp: 0,
      currentTarget,
    }
    if ('onScroll' in settings) {
      scroll.onScroll = settings.onScroll
    }
    currentTarget.addEventListener('touchmove', onTouchMove, false)
    currentTarget.scrollManager = scroll
  } else {
    scroll = currentTarget.scrollManager
    if (scroll.isScrolling) {
      global.cancelAnimationFrame(scroll.isScrolling)
      scroll.isScrolling = false
    }
  }
  return scroll
}

const updateScrollManager = scroll => {
  scroll.target = scroll.getTarget(scroll)
  scroll.scrollDelta = scroll.getOffsetSize(scroll) - scroll.getScrollSize(scroll)
  scroll.style = scroll.target.style
  scroll.isScrolling = false
}

const scrollMove = (scroll, position) => {
  var withinBounds
  if (position > 0) {
    position = 0
  } else if (position < scroll.scrollDelta) {
    position = scroll.scrollDelta
  } else {
    withinBounds = true
  }

  scroll.position = position
  scroll.style[transform] = scroll.direction === 'y'
    ? `translate3d(0, ${position}px, 0)`
    : `translate3d(${position}px, 0, 0)`

  return withinBounds
}

const scrollEnd = scroll => {
  var delta = 0
  var i = deltasLastIndex
  while (i) { delta += scroll.deltas[i--] }
  delta /= deltasLastIndex + 1
  ;(function ease () {
    delta *= 0.95
    if (delta > 0.5 || delta < -0.5) {
      scroll.isScrolling = scrollMove(scroll, scroll.position + delta) &&
        global.requestAnimationFrame(ease)
    } else {
      scroll.isScrolling = false
    }
    if ('onScroll' in scroll) scroll.onScroll(scroll)
  })()
}

const onTouchStart = ({ target, event }) => {
  const scroll = getScrollManager(target)
  const e = event.changedTouches[0]
  if (scroll.direction === 'y') {
    scroll.clientPos = e.clientY
    scroll.oppositePos = e.clientX
  } else {
    scroll.clientPos = e.clientX
    scroll.oppositePos = e.clientY
  }
  updateScrollManager(scroll)
}

const onMoveEvent = (e, scroll, delta) => {
  if (scroll.scrollDelta) {
    if (!scroll.isScrolling) {
      let oppositeDelta
      if ('changedTouches' in e) {
        oppositeDelta = scroll.direction === 'y'
        ? e.changedTouches[0].clientX - scroll.oppositePos
        : e.changedTouches[0].clientY - scroll.oppositePos
      } else {
        oppositeDelta = scroll.direction === 'y'
        ? e.deltaX
        : e.deltaY
      }
      if (abs(delta) > abs(oppositeDelta)) {
        scroll.position = scroll.position || 0
        scroll.deltasIndex = 0
        scroll.deltas = [0,0,0]
        scroll.isScrolling = true
      } else {
        scroll.scrollDelta = false
        return
      }
    }

    const deltasIndex = scroll.deltasIndex
    scroll.deltasIndex = deltasIndex === deltasLastIndex ? 0 : deltasIndex + 1
    scroll.deltas[deltasIndex] = scrollMove(scroll, scroll.position + delta) ? delta : 0
    scroll.timeStamp = e.timeStamp

    if ('onScroll' in scroll) scroll.onScroll(scroll)
  }
}

const onTouchMove = e => {
  const scroll = e.currentTarget.scrollManager
  if (scroll.scrollDelta) {
    const clientPos = scroll.direction === 'y'
      ? e.changedTouches[0].clientY
      : e.changedTouches[0].clientX
    onMoveEvent(e, scroll, clientPos - scroll.clientPos)
    scroll.clientPos = clientPos
  }
}

const onTouchEnd = ({ target }) => {
  const scroll = target.scrollManager
  if (scroll.isScrolling) {
    scrollEnd(scroll)
  }
}

const onWheel = ({ target, event }) => {
  const scroll = getScrollManager(target)
  if (scroll.timeStamp < event.timeStamp - 100) {
    updateScrollManager(scroll)
    scroll.timeStamp = event.timeStamp
  }
  onMoveEvent(event, scroll, scroll.direction === 'y' ? -event.deltaY : -event.deltaX)
  event.preventDefault()
}

const scrollTo = (node, position, animate) => {
  const scroll = getScrollManager(node)
  updateScrollManager(scroll)
  scrollMove(scroll, position)
}

export default {
  props: {
    scroll (t, scrollSettings) {
      t.set({
        define: {
          scrollTo,
          scrollSettings
        },
        on: {
          touchstart: { scroll: onTouchStart },
          touchend: { scroll: onTouchEnd },
          wheel: { scroll: onWheel }
        }
      }, false)
    }
  }
}
<|endoftext|>


<commit_before>const easingCache = 3
const easingFraction = 0.95
const easingAccelerator = 1.5
const quadraticEasing = 0.25

const bounds = (target, val) => {
  if (val < -target._height) {
    // target._easing = false
    return -target._height
  } else if (val > 0) {
    // target._easing = false
    return 0
  } else {
    return val
  }
}

const setVal = (target, val, original, event, stamp) => {
  val = bounds(target, val)
  target.style.transform = `translate3d(0, ${val}rem, 0)`
  if (!original) {
    original = target
  }

  if (original._ && original._._scrollListener) {
    original._._scrollListener({ y: val, target: original }, stamp)
  }
  return val
}

const touchstart = ({ target, y, event }) => {
  const ch = target.parentNode.clientHeight
  const sh = target.scrollHeight
  global.cancelAnimationFrame(target._isEasing)
  if (ch >= sh) {
    target._block = true
    target.__init = false
    return true
  }
  target.__init = true
  target._start = y
  target._y = target._ly || 0
  target._easing = false
  target._prev = [ 1, 0, 0, 0 ]
  target._height = sh - ch
  target._block = ch >= sh
}

const easeOut = (target, distance, original, event, stamp, easingFraction) => {
  if (target._easing) {
    target._ly = setVal(target, target._ly + distance * (1 - easingFraction), original, event, stamp)
    if (distance > 0.5 || distance < -0.5) {
      target._isEasing = global.requestAnimationFrame(() => easeOut(target, distance * easingFraction, original, event, stamp, easingFraction))
    } else {
      target._easing = false
    }
  }
}

const touchend = (event, stamp) => {
  const target = event.target
  target.__init = false
  const original = event.original
  var delta = 0
  var i = easingCache
  while (i--) {
    delta += target._prev[i] || 0
  }
  delta = (delta / easingCache) * easingAccelerator
  const sing = delta < 0 ? -1 : 1
  var distance = quadraticEasing * ((delta * delta) * sing)
  if (distance > 750) {
    distance = 750
  }
  target._easing = true
  easeOut(target, distance, original, event, stamp, easingFraction)
}

const touchmove = (event, stamp) => {
  const target = event.target
  if (target._block) return true
  const original = event.original
  const y = event.y
  const index = target._prev[0]
  target._prev[0]++
  if (target._prev[0] > easingCache) {
    target._prev[0] = 1
  }
  const val = y - target._start + target._y
  target._prev[index] = val - (target._ly || 0)
  target._ly = setVal(target, val, original, event, stamp)
}

const lookupMode = [1.0, 28.0, 500.0]

const wheel = (event, stamp) => {
  const evt = event.event
  evt.preventDefault()
  if ('deltaY' in evt) {
    const mode = lookupMode[evt.deltaMode] || lookupMode[0]
    event.y = event.event.deltaY * mode * -1
  } else if ('wheelDeltaX' in evt) {
    event.y = evt.wheelDelta / -3
  } else {
    event.y = evt.wheelDelta / -3
  }
  const target = event.target
  if (!target.__init) {
    if (!target._ly) {
      target._ly = 0
    }
    if (touchstart(event, stamp)) {
      return
    }
  }
  clearTimeout(target._timeout)
  target._timeout = setTimeout(() => {
    if (target.offsetParent !== null) {
      target.__init = false
    }
  }, 20)
  target._ly = setVal(target, target._ly + event.y, event.original, event, stamp)
}

export default {
  props: {
    scroll: (t, val) => {
      var fn, target
      if (typeof val === 'function') {
        fn = val
      } else if (typeof val === 'object') {
        if (val.onScroll) {
          fn = val.onScroll
        }
        if (val.target) {
          target = val.target
        }
      }

      t.set({
        define: {
          hasScrollY: true
        }
      }, false)

      if (fn) {
        t.set({
          define: {
            _scrollListener: fn
          }
        }, false)
      }
      if (target) {
        t.set({
          define: {
            easeScrollY (y, t, stamp) {
              const rt = target(t)
              const event = {
                original: t,
                target: rt
              }
              global.cancelAnimationFrame(rt._isEasing)
              rt._easing = true
              if (!rt._ly) rt._ly = 0
              console.log('?', bounds(rt, -y))
              easeOut(rt, bounds(rt, -y) - rt._ly, t, event, stamp, 0.9)
            }
          },
          on: {
            touchstart: {
              scroll: (val, stamp) => {
                val.target = target(val.target)
                touchstart(val, stamp)
              }
            },
            touchmove: {
              scroll: (val, stamp) => {
                val.original = val.target
                val.target = target(val.target)
                touchmove(val, stamp)
              }
            },
            touchend: {
              scroll: (val, stamp) => {
                val.original = val.target
                val.target = target(val.target)
                touchend(val, stamp)
              }
            },
            wheel: {
              scroll: (val, stamp) => {
                val.original = val.target
                val.target = target(val.target)
                wheel(val, stamp)
              }
            }
          }
        }, false)
      } else {
        t.set({
          define: {
            easeScrollY (y, node, stamp) {
              // target._easi
              easeOut(node, y - (target._ly || 0), node, { target: node }, stamp, 0.9)
            }
          },
          on: {
            touchmove: { scroll: touchmove },
            touchstart: { scroll: touchstart },
            touchend: { scroll: touchend },
            wheel: { scroll: wheel }
          }
        }, false)
      }
    }
  }
}
<commit_msg>removed ogs<commit_after>const easingCache = 3
const easingFraction = 0.95
const easingAccelerator = 1.5
const quadraticEasing = 0.25

const bounds = (target, val) => {
  if (val < -target._height) {
    // target._easing = false
    return -target._height
  } else if (val > 0) {
    // target._easing = false
    return 0
  } else {
    return val
  }
}

const setVal = (target, val, original, event, stamp) => {
  val = bounds(target, val)
  target.style.transform = `translate3d(0, ${val}rem, 0)`
  if (!original) {
    original = target
  }

  if (original._ && original._._scrollListener) {
    original._._scrollListener({ y: val, target: original }, stamp)
  }
  return val
}

const touchstart = ({ target, y, event }) => {
  const ch = target.parentNode.clientHeight
  const sh = target.scrollHeight
  global.cancelAnimationFrame(target._isEasing)
  if (ch >= sh) {
    target._block = true
    target.__init = false
    return true
  }
  target.__init = true
  target._start = y
  target._y = target._ly || 0
  target._easing = false
  target._prev = [ 1, 0, 0, 0 ]
  target._height = sh - ch
  target._block = ch >= sh
}

const easeOut = (target, distance, original, event, stamp, easingFraction) => {
  if (target._easing) {
    target._ly = setVal(target, target._ly + distance * (1 - easingFraction), original, event, stamp)
    if (distance > 0.5 || distance < -0.5) {
      target._isEasing = global.requestAnimationFrame(() => easeOut(target, distance * easingFraction, original, event, stamp, easingFraction))
    } else {
      target._easing = false
    }
  }
}

const touchend = (event, stamp) => {
  const target = event.target
  target.__init = false
  const original = event.original
  var delta = 0
  var i = easingCache
  while (i--) {
    delta += target._prev[i] || 0
  }
  delta = (delta / easingCache) * easingAccelerator
  const sing = delta < 0 ? -1 : 1
  var distance = quadraticEasing * ((delta * delta) * sing)
  if (distance > 750) {
    distance = 750
  }
  target._easing = true
  easeOut(target, distance, original, event, stamp, easingFraction)
}

const touchmove = (event, stamp) => {
  const target = event.target
  if (target._block) return true
  const original = event.original
  const y = event.y
  const index = target._prev[0]
  target._prev[0]++
  if (target._prev[0] > easingCache) {
    target._prev[0] = 1
  }
  const val = y - target._start + target._y
  target._prev[index] = val - (target._ly || 0)
  target._ly = setVal(target, val, original, event, stamp)
}

const lookupMode = [1.0, 28.0, 500.0]

const wheel = (event, stamp) => {
  const evt = event.event
  evt.preventDefault()
  if ('deltaY' in evt) {
    const mode = lookupMode[evt.deltaMode] || lookupMode[0]
    event.y = event.event.deltaY * mode * -1
  } else if ('wheelDeltaX' in evt) {
    event.y = evt.wheelDelta / -3
  } else {
    event.y = evt.wheelDelta / -3
  }
  const target = event.target
  if (!target.__init) {
    if (!target._ly) {
      target._ly = 0
    }
    if (touchstart(event, stamp)) {
      return
    }
  }
  clearTimeout(target._timeout)
  target._timeout = setTimeout(() => {
    if (target.offsetParent !== null) {
      target.__init = false
    }
  }, 20)
  target._ly = setVal(target, target._ly + event.y, event.original, event, stamp)
}

export default {
  props: {
    scroll: (t, val) => {
      var fn, target
      if (typeof val === 'function') {
        fn = val
      } else if (typeof val === 'object') {
        if (val.onScroll) {
          fn = val.onScroll
        }
        if (val.target) {
          target = val.target
        }
      }

      t.set({
        define: {
          hasScrollY: true
        }
      }, false)

      if (fn) {
        t.set({
          define: {
            _scrollListener: fn
          }
        }, false)
      }
      if (target) {
        t.set({
          define: {
            easeScrollY (y, t, stamp) {
              const rt = target(t)
              const event = {
                original: t,
                target: rt
              }
              global.cancelAnimationFrame(rt._isEasing)
              rt._easing = true
              if (!rt._ly) rt._ly = 0
              easeOut(rt, bounds(rt, -y) - rt._ly, t, event, stamp, 0.9)
            }
          },
          on: {
            touchstart: {
              scroll: (val, stamp) => {
                val.target = target(val.target)
                touchstart(val, stamp)
              }
            },
            touchmove: {
              scroll: (val, stamp) => {
                val.original = val.target
                val.target = target(val.target)
                touchmove(val, stamp)
              }
            },
            touchend: {
              scroll: (val, stamp) => {
                val.original = val.target
                val.target = target(val.target)
                touchend(val, stamp)
              }
            },
            wheel: {
              scroll: (val, stamp) => {
                val.original = val.target
                val.target = target(val.target)
                wheel(val, stamp)
              }
            }
          }
        }, false)
      } else {
        t.set({
          define: {
            easeScrollY (y, node, stamp) {
              // target._easi
              easeOut(node, y - (target._ly || 0), node, { target: node }, stamp, 0.9)
            }
          },
          on: {
            touchmove: { scroll: touchmove },
            touchstart: { scroll: touchstart },
            touchend: { scroll: touchend },
            wheel: { scroll: wheel }
          }
        }, false)
      }
    }
  }
}
<|endoftext|>


<commit_before>var gulp = require('gulp');
var runSequence = require('run-sequence');
var del = require('del');

gulp.task('copy:watch', function() {
  gulp.watch(GLOBAL.config.src + '/*.*', ['copy:root']);
});

gulp.task('copy:cleanRoot', function(cb) {
  del([GLOBAL.config.dest + '/*.{json,txt,ico}'], {dot: true})
    .then(function() {
      cb();
    });
});

gulp.task('copy:root', ['copy:cleanRoot'], function() {
  return gulp.src([
      GLOBAL.config.src + '/*.{json,txt,ico}',
    ])
    .pipe(gulp.dest(GLOBAL.config.dest));
});

gulp.task('copy', function(cb) {
  runSequence(
    'copy:root',
  cb);
});
<commit_msg>cleaned up tabs<commit_after>var gulp = require('gulp');
var runSequence = require('run-sequence');
var del = require('del');

gulp.task('copy:watch', function() {
  gulp.watch(GLOBAL.config.src + '/*.*', ['copy:root']);
});

gulp.task('copy:cleanRoot', function(cb) {
  del([GLOBAL.config.dest + '/*.{json,txt,ico}'], {dot: true})
  .then(function() {
    cb();
  });
});

gulp.task('copy:root', ['copy:cleanRoot'], function() {
  return gulp.src([
    GLOBAL.config.src + '/*.{json,txt,ico}'
  ])
  .pipe(gulp.dest(GLOBAL.config.dest));
});

gulp.task('copy', function(cb) {
  runSequence(
    'copy:root',
  cb);
});
<|endoftext|>


<commit_before>var cacheBust = require('gulp-cache-bust');
var foundationDocs = require('foundation-docs');
var gulp = require('gulp');
var newer = require('gulp-newer');
var panini = require('panini');
var sequence = require('run-sequence');
var supercollider = require('supercollider');

var PANINI_CONFIG = {
  root: 'docs/pages/',
  layouts: 'docs/layout/',
  partials: ['docs/partials/', 'node_modules/foundation-docs/templates/partials/'],
  helpers: foundationDocs.handlebarsHelpers,
}

var SEARCH_SORT_ORDER = ['page', 'component', 'sass variable', 'sass mixin', 'sass function', 'js class', 'js function', 'js plugin option', 'js event'];

var SEARCH_PAGE_TYPES = {
  'library': function(item) {
    return !!(item.library);
  }
}

supercollider
  .config({
    template: foundationDocs.componentTemplate,
    marked: foundationDocs.marked,
    handlebars: foundationDocs.handlebars,
    keepFm: true,
    quiet: false,
    pageRoot: 'docs/pages',
    data: {
      repoName: 'foundation-sites',
      editBranch: 'master'
    }
  })
  .searchConfig({
    extra: 'docs/search.yml',
    sort: SEARCH_SORT_ORDER,
    pageTypes: SEARCH_PAGE_TYPES
  })
  .adapter('sass')
  .adapter('js');

// Assembles the layout, pages, and partials in the docs folder
gulp.task('docs', function() {
  return gulp.src('docs/pages/**/*')
    .pipe(newer({
      dest: '_build',
      ext: '.html'
    }))
    .pipe(supercollider.init())
    .pipe(panini(PANINI_CONFIG))
    .pipe(cacheBust({
		basePath: '_build/'
	}))
    .pipe(gulp.dest('_build'))
    .on('finish', buildSearch);
});

gulp.task('docs:all', function() {
  panini.refresh();

  return gulp.src('docs/pages/**/*')
    .pipe(supercollider.init())
    .pipe(panini(PANINI_CONFIG))
    .pipe(cacheBust({
		basePath: '_build/'
	}))
    .pipe(gulp.dest('_build'))
    .on('finish', buildSearch);
});

function buildSearch() {
  supercollider.buildSearch('_build/data/search.json', function() {});
}

gulp.task('docs:debug', ['docs:all'], function(cb) {
  var output = JSON.stringify(supercollider.tree, null, '  ');
  require('fs').writeFile('./_debug.json', output, cb);
});
<commit_msg>chore: fix indentation<commit_after>var cacheBust = require('gulp-cache-bust');
var foundationDocs = require('foundation-docs');
var gulp = require('gulp');
var newer = require('gulp-newer');
var panini = require('panini');
var sequence = require('run-sequence');
var supercollider = require('supercollider');

var PANINI_CONFIG = {
  root: 'docs/pages/',
  layouts: 'docs/layout/',
  partials: ['docs/partials/', 'node_modules/foundation-docs/templates/partials/'],
  helpers: foundationDocs.handlebarsHelpers,
}

var SEARCH_SORT_ORDER = ['page', 'component', 'sass variable', 'sass mixin', 'sass function', 'js class', 'js function', 'js plugin option', 'js event'];

var SEARCH_PAGE_TYPES = {
  'library': function(item) {
    return !!(item.library);
  }
}

supercollider
  .config({
    template: foundationDocs.componentTemplate,
    marked: foundationDocs.marked,
    handlebars: foundationDocs.handlebars,
    keepFm: true,
    quiet: false,
    pageRoot: 'docs/pages',
    data: {
      repoName: 'foundation-sites',
      editBranch: 'master'
    }
  })
  .searchConfig({
    extra: 'docs/search.yml',
    sort: SEARCH_SORT_ORDER,
    pageTypes: SEARCH_PAGE_TYPES
  })
  .adapter('sass')
  .adapter('js');

// Assembles the layout, pages, and partials in the docs folder
gulp.task('docs', function() {
  return gulp.src('docs/pages/**/*')
    .pipe(newer({
      dest: '_build',
      ext: '.html'
    }))
    .pipe(supercollider.init())
    .pipe(panini(PANINI_CONFIG))
    .pipe(cacheBust({
        basePath: '_build/'
    }))
    .pipe(gulp.dest('_build'))
    .on('finish', buildSearch);
});

gulp.task('docs:all', function() {
  panini.refresh();

  return gulp.src('docs/pages/**/*')
    .pipe(supercollider.init())
    .pipe(panini(PANINI_CONFIG))
    .pipe(cacheBust({
        basePath: '_build/'
    }))
    .pipe(gulp.dest('_build'))
    .on('finish', buildSearch);
});

function buildSearch() {
  supercollider.buildSearch('_build/data/search.json', function() {});
}

gulp.task('docs:debug', ['docs:all'], function(cb) {
  var output = JSON.stringify(supercollider.tree, null, '  ');
  require('fs').writeFile('./_debug.json', output, cb);
});
<|endoftext|>


<commit_before>App.Components.DatePickerComponent = Frontend.Component.extend({
    setup: function($elements) {
        $elements.each(function(i, element) {
            var $container = $(element);
            var $selectContainer = $container.find('select:first').parent();
            $container.find('select').hide();

            var pickerMarkup = '
<input type="text" class="form-control"/>
';
            $selectContainer.append(pickerMarkup);

            var type = $container.hasClass('dateTime') ? 'dateTime' : 'date';
            var format = 'DD.MM.YYYY';
            if(type === 'dateTime') {
                format = 'DD.MM.YYYY HH:mm';
            }

            $selectContainer.find('input[type=text]').blur(function (e) {
                // if only day and month were entered, make sure the current year is used.
                if (e.currentTarget.value.substring(6) == '0000') {
                    e.currentTarget.value = e.currentTarget.value.substring(0, 6) + moment().year();
                    $(e.currentTarget).trigger('change');
                }
            });

            var $picker = $selectContainer.find('.input-group.date');
            $picker.datetimepicker({
                format: format,
                sideBySide: true,
                locale: this.Controller.getVar('locale') || 'en',
                date: this._getDateFromSelects($container)
            });

            // Update the selects to the correct values after a datepicker change
            $picker.on('dp.change', function(e) {
                var $container = $(e.currentTarget).parents('.form-group');
                this._updateSelects($container, e.date, $(e.currentTarget));
            }.bind(this));
        }.bind(this));
    },
    _updateSelects: function($selectContainer, date, input) {
        if (input.find('input').val().length == 0) {
            $selectContainer.find('select option[selected="selected"]').each(function(i, el) {
                $(el).removeAttr("selected");
            });
            return null;
        }
        $selectContainer.find('select').each(function(i, el) {
            var $select = $(el);
            if($select.attr('name').indexOf('[year]') > -1) {
                $select.val(date.year());
            }
            if($select.attr('name').indexOf('[month]') > -1) {
                $select.val(date.format('MM'));
            }
            if($select.attr('name').indexOf('[day]') > -1) {
                $select.val(date.format('DD'));
            }
            if($select.attr('name').indexOf('[hour]') > -1) {
                $select.val(date.format('HH'));
            }
            if($select.attr('name').indexOf('[minute]') > -1) {
                $select.val(date.format('mm'));
            }
        });
    },
    _getDateFromSelects: function($selectContainer) {
        var date = moment();
        $selectContainer.find('select').each(function(i, el) {
            var $select = $(el);
            var val = parseInt($select.val(), 10);
            if($select.attr('name').indexOf('[year]') > -1) {
                date.year(val);
            }
            if($select.attr('name').indexOf('[month]') > -1) {
                date.month(val - 1);
            }
            if($select.attr('name').indexOf('[day]') > -1) {
                date.date(val);
            }
            if($select.attr('name').indexOf('[hour]') > -1) {
                date.hour(val);
            }
            if($select.attr('name').indexOf('[minute]') > -1) {
                date.minute(val);
            }
        });
        return date;
    }
});<commit_msg>prevent datepicker elements from being applied more than once<commit_after>App.Components.DatePickerComponent = Frontend.Component.extend({
    setup: function($elements) {
        $elements.each(function(i, element) {
            var $container = $(element);

            if ($container.data('datePickerApplied')) {
                return;
            }

            var $selectContainer = $container.find('select:first').parent();
            $container.find('select').hide();

            var pickerMarkup = '
<input type="text" class="form-control"/>
';
            $selectContainer.append(pickerMarkup);

            var type = $container.hasClass('dateTime') ? 'dateTime' : 'date';
            var format = 'DD.MM.YYYY';
            if(type === 'dateTime') {
                format = 'DD.MM.YYYY HH:mm';
            }

            $selectContainer.find('input[type=text]').blur(function (e) {
                // if only day and month were entered, make sure the current year is used.
                if (e.currentTarget.value.substring(6) == '0000') {
                    e.currentTarget.value = e.currentTarget.value.substring(0, 6) + moment().year();
                    $(e.currentTarget).trigger('change');
                }
            });

            var $picker = $selectContainer.find('.input-group.date');
            $picker.datetimepicker({
                format: format,
                sideBySide: true,
                locale: this.Controller.getVar('locale') || 'en',
                date: this._getDateFromSelects($container)
            });

            // Update the selects to the correct values after a datepicker change
            $picker.on('dp.change', function(e) {
                var $container = $(e.currentTarget).parents('.form-group');
                this._updateSelects($container, e.date, $(e.currentTarget));
            }.bind(this));

            $container.data('datePickerApplied', true);
        }.bind(this));
    },
    _updateSelects: function($selectContainer, date, input) {
        if (input.find('input').val().length == 0) {
            $selectContainer.find('select option[selected="selected"]').each(function(i, el) {
                $(el).removeAttr("selected");
            });
            return null;
        }
        $selectContainer.find('select').each(function(i, el) {
            var $select = $(el);
            if($select.attr('name').indexOf('[year]') > -1) {
                $select.val(date.year());
            }
            if($select.attr('name').indexOf('[month]') > -1) {
                $select.val(date.format('MM'));
            }
            if($select.attr('name').indexOf('[day]') > -1) {
                $select.val(date.format('DD'));
            }
            if($select.attr('name').indexOf('[hour]') > -1) {
                $select.val(date.format('HH'));
            }
            if($select.attr('name').indexOf('[minute]') > -1) {
                $select.val(date.format('mm'));
            }
        });
    },
    _getDateFromSelects: function($selectContainer) {
        var date = moment();
        $selectContainer.find('select').each(function(i, el) {
            var $select = $(el);
            var val = parseInt($select.val(), 10);
            if($select.attr('name').indexOf('[year]') > -1) {
                date.year(val);
            }
            if($select.attr('name').indexOf('[month]') > -1) {
                date.month(val - 1);
            }
            if($select.attr('name').indexOf('[day]') > -1) {
                date.date(val);
            }
            if($select.attr('name').indexOf('[hour]') > -1) {
                date.hour(val);
            }
            if($select.attr('name').indexOf('[minute]') > -1) {
                date.minute(val);
            }
        });
        return date;
    }
});<|endoftext|>


<commit_before>#!/usr/bin/env node
/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

/**
 * This file is required because package.json cannot reference a file that
 * is not distributed with the package, and we use node-pre-gyp to distribute
 * the plugin binary
 */

'use strict';

var path = require('path');
var execFile = require('child_process').execFile;

var exe_ext = process.platform === 'win32' ? '.exe' : '';

var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext);

var child_process = execFile(plugin, process.argv.slice(2), {encoding: 'buffer'}, function(error, stdout, stderr) {
  if (error) {
    throw error;
  }
});

process.stdin.pipe(child_process.stdin);
child_process.stdout.pipe(process.stdout);
child_process.stderr.pipe(process.stderr);
<commit_msg>Added a 1MB maxBuffer since the default 200kb is too small on larger proto codebases<commit_after>#!/usr/bin/env node
/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

/**
 * This file is required because package.json cannot reference a file that
 * is not distributed with the package, and we use node-pre-gyp to distribute
 * the plugin binary
 */

'use strict';

var path = require('path');
var execFile = require('child_process').execFile;

var exe_ext = process.platform === 'win32' ? '.exe' : '';

var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext);

var child_process = execFile(plugin, process.argv.slice(2), {encoding: 'buffer', maxBuffer: 1024 * 1000}, function(error, stdout, stderr) {
  if (error) {
    throw error;
  }
});

process.stdin.pipe(child_process.stdin);
child_process.stdout.pipe(process.stdout);
child_process.stderr.pipe(process.stderr);
<|endoftext|>