<commit_before>/*
 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */

(function(scope) {

  // element api

  var properties = {
    inferObservers: function(prototype) {
      // called before prototype.observe is chained to inherited object
      var observe = prototype.observe, property;
      for (var n in prototype) {
        if (n.slice(-7) === 'Changed') {
          if (!observe) {
            observe  = (prototype.observe = {});
          }
          property = n.slice(0, -7)
          observe[property] = observe[property] || n;
        }
      }
    },
    explodeObservers: function(prototype) {
      // called before prototype.observe is chained to inherited object
      var o = prototype.observe;
      if (o) {
        var exploded = {};
        for (var n in o) {
          var names = n.split(' ');
          for (var i=0, ni; ni=names[i]; i++) {
            exploded[ni] = o[n];
          }
        }
        prototype.observe = exploded;
      }
    },
    optimizePropertyMaps: function(prototype) {
      if (prototype.observe) {
        // construct name list
        var a = prototype._observeNames = [];
        for (var n in prototype.observe) {
          var names = n.split(' ');
          for (var i=0, ni; ni=names[i]; i++) {
            a.push(ni);
          }
        }
      }
      if (prototype.publish) {
        // construct name list
        var a = prototype._publishNames = [];
        for (var n in prototype.publish) {
          a.push(n);
        }
      }
      if (prototype.computed) {
        // construct name list
        var a = prototype._computedNames = [];
        for (var n in prototype.computed) {
          a.push(n);
        }
      }
    },
    publishProperties: function(prototype, base) {
      // if we have any properties to publish
      var publish = prototype.publish;
      if (publish) {
        // transcribe `publish` entries onto own prototype
        this.requireProperties(publish, prototype, base);
        // construct map of lower-cased property names
        prototype._publishLC = this.lowerCaseMap(publish);
      }
    },
    // sync prototype to property descriptors;
    // desriptor format contains default value and optionally a
    // hint for reflecting the property to an attribute.
    // e.g. {foo: 5, bar: {value: true, reflect: true}}
    // reflect: {foo: true} is also supported
    //
    requireProperties: function(propertyDescriptors, prototype, base) {
      // reflected properties
      prototype.reflect = prototype.reflect || {};
      // ensure a prototype value for each property
      // and update the property's reflect to attribute status
      for (var n in propertyDescriptors) {
        var propertyDescriptor = propertyDescriptors[n];
        var reflects = this.reflectHintForDescriptor(propertyDescriptor);
        if (prototype.reflect[n] === undefined && reflects !== undefined) {
          prototype.reflect[n] = reflects;
        }
        if (prototype[n] === undefined) {
          prototype[n] = this.valueForDescriptor(propertyDescriptor);
        }
      }
    },
    valueForDescriptor: function(propertyDescriptor) {
      var value = typeof propertyDescriptor === 'object' &&
          propertyDescriptor ? propertyDescriptor.value : propertyDescriptor;
      return value !== undefined ? value : null;
    },
    // returns the value of the descriptor's 'reflect' property or undefined
    reflectHintForDescriptor: function(propertyDescriptor) {
      if (typeof propertyDescriptor === 'object' &&
          propertyDescriptor && propertyDescriptor.reflect !== undefined) {
        return propertyDescriptor.reflect;
      }
    },
    lowerCaseMap: function(properties) {
      var map = {};
      for (var n in properties) {
        map[n.toLowerCase()] = n;
      }
      return map;
    },
    createPropertyAccessor: function(name) {
      var proto = this.prototype;

      var privateName = name + '_';
      var privateObservable  = name + 'Observable_';
      proto[privateName] = proto[name];

      Object.defineProperty(proto, name, {
        get: function() {
          var observable = this[privateObservable];
          if (observable)
            observable.deliver();

          return this[privateName];
        },
        set: function(value) {
          var observable = this[privateObservable];
          if (observable) {
            observable.setValue(value);
            return;
          }

          var oldValue = this[privateName];
          this[privateName] = value;
          this.emitPropertyChangeRecord(name, value, oldValue);

          return value;
        },
        configurable: true
      });
    },
    createPropertyAccessors: function(prototype) {
      var n$ = prototype._publishNames;
      if (n$ && n$.length) {
        for (var i=0, l=n$.length, n, fn; (i<l) && (n=n$[i]); i++) {
          this.createPropertyAccessor(n);
        }
      }

      var n$ = prototype._computedNames;
      if (n$ && n$.length) {
        for (var i=0, l=n$.length, n, fn; (i<l) && (n=n$[i]); i++) {
          this.createPropertyAccessor(n);
        }
      }

    }
  };

  // exports

  scope.api.declaration.properties = properties;

})(Polymer);
<commit_msg>Simplify `requireProperties` logic, document the conventions<commit_after>/*
 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */

(function(scope) {

  // element api

  var properties = {
    inferObservers: function(prototype) {
      // called before prototype.observe is chained to inherited object
      var observe = prototype.observe, property;
      for (var n in prototype) {
        if (n.slice(-7) === 'Changed') {
          if (!observe) {
            observe  = (prototype.observe = {});
          }
          property = n.slice(0, -7)
          observe[property] = observe[property] || n;
        }
      }
    },
    explodeObservers: function(prototype) {
      // called before prototype.observe is chained to inherited object
      var o = prototype.observe;
      if (o) {
        var exploded = {};
        for (var n in o) {
          var names = n.split(' ');
          for (var i=0, ni; ni=names[i]; i++) {
            exploded[ni] = o[n];
          }
        }
        prototype.observe = exploded;
      }
    },
    optimizePropertyMaps: function(prototype) {
      if (prototype.observe) {
        // construct name list
        var a = prototype._observeNames = [];
        for (var n in prototype.observe) {
          var names = n.split(' ');
          for (var i=0, ni; ni=names[i]; i++) {
            a.push(ni);
          }
        }
      }
      if (prototype.publish) {
        // construct name list
        var a = prototype._publishNames = [];
        for (var n in prototype.publish) {
          a.push(n);
        }
      }
      if (prototype.computed) {
        // construct name list
        var a = prototype._computedNames = [];
        for (var n in prototype.computed) {
          a.push(n);
        }
      }
    },
    publishProperties: function(prototype, base) {
      // if we have any properties to publish
      var publish = prototype.publish;
      if (publish) {
        // transcribe `publish` entries onto own prototype
        this.requireProperties(publish, prototype, base);
        // construct map of lower-cased property names
        prototype._publishLC = this.lowerCaseMap(publish);
      }
    },
    //
    // `name: value` entries in the `publish` object may need to generate
    // matching properties on the prototype.
    //
    // Values that are objects may have a `reflect` property, which
    // signals that the value describes property control metadata.
    // In metadata objects, the prototype default value (if any)
    // is encoded in the `value` property.
    //
    // publish: {
    //   foo: 5,
    //   bar: {value: true, reflect: true},
    //   zot: {}
    // }
    //
    // `reflect` metadata property controls whether changes to the property
    // are reflected back to the attribute (default false).
    //
    // A value is stored on the prototype unless it's === `undefined`,
    // in which case the base chain is checked for a value.
    // If the basal value is also undefined, `null` is stored on the prototype.
    //
    // The reflection data is stored on another prototype object, `reflect`
    // which also can be specified directly.
    //
    // reflect: {
    //   foo: true
    // }
    //
    requireProperties: function(propertyInfos, prototype, base) {
      // per-prototype storage for reflected properties
      prototype.reflect = prototype.reflect || {};
      // ensure a prototype value for each property
      // and update the property's reflect to attribute status
      for (var n in propertyInfos) {
        var value = propertyInfos[n];
        // value has metadata if it has a `reflect` property
        if (value && value.reflect !== undefined) {
          prototype.reflect[n] = Boolean(value.reflect);
          value = value.value;
        }
        // only set a value if one is specified
        if (value !== undefined) {
          prototype[n] = value;
        }
      }
    },
    lowerCaseMap: function(properties) {
      var map = {};
      for (var n in properties) {
        map[n.toLowerCase()] = n;
      }
      return map;
    },
    createPropertyAccessor: function(name) {
      var proto = this.prototype;

      var privateName = name + '_';
      var privateObservable  = name + 'Observable_';
      proto[privateName] = proto[name];

      Object.defineProperty(proto, name, {
        get: function() {
          var observable = this[privateObservable];
          if (observable)
            observable.deliver();

          return this[privateName];
        },
        set: function(value) {
          var observable = this[privateObservable];
          if (observable) {
            observable.setValue(value);
            return;
          }

          var oldValue = this[privateName];
          this[privateName] = value;
          this.emitPropertyChangeRecord(name, value, oldValue);

          return value;
        },
        configurable: true
      });
    },
    createPropertyAccessors: function(prototype) {
      var n$ = prototype._publishNames;
      if (n$ && n$.length) {
        for (var i=0, l=n$.length, n, fn; (i<l) && (n=n$[i]); i++) {
          this.createPropertyAccessor(n);
        }
      }
      var n$ = prototype._computedNames;
      if (n$ && n$.length) {
        for (var i=0, l=n$.length, n, fn; (i<l) && (n=n$[i]); i++) {
          this.createPropertyAccessor(n);
        }
      }
    }
  };

  // exports

  scope.api.declaration.properties = properties;

})(Polymer);
<|endoftext|>


<commit_before>const prompt = require("prompt");
const sh = require("shelljs");

// Start the prompt
prompt.start();

const schema = {
	"properties": {
		"BootstrapUI": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n",
			"description": "Install Bootstrap UI? [y/n]",
			"required": true
		},
		"MaterialUI": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Material UI? [y/n]",
			"required": true
		}
	}
};

prompt.get(schema, (err, input) => {
	sh.exec("npm i https://github.com/abbotto/rectangular-ui.git");
	if (input.BootstrapUI.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Bootstrap UI...");
		sh.exec("npm i bootstrap angular-strap --save");
		sh.exec("cp -r ./node_modules/rectangular-ui/ui/bootstrap/src/ ./src/client/");
		sh.exec("curl https://raw.githubusercontent.com/abbotto/rectangular-ui/master/ui/bootstrap/README.md");
	}
	if (input.MaterialUI.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Material UI...");
		sh.exec("npm i angular-material --save");
		sh.exec("cp -r ./node_modules/rectangular-ui/ui/material-design/src/ ./src/client/");
		sh.exec("curl https://raw.githubusercontent.com/abbotto/rectangular-ui/master/ui/material-design/README.md");
	}
});
<commit_msg>Update install-ui.js<commit_after>// Todo
// Make sure UI scripts and styles get added to the build process
// Make sure UI dependencies get injected into app.service.js

const prompt = require("prompt");
const sh = require("shelljs");

// Start the prompt
prompt.start();

const schema = {
	"properties": {
		"BootstrapUI": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n",
			"description": "Install Bootstrap UI? [y/n]",
			"required": true
		},
		"MaterialUI": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Material UI? [y/n]",
			"required": true
		}
	}
};

prompt.get(schema, (err, input) => {
	sh.exec("npm i https://github.com/abbotto/rectangular-ui.git");
	if (input.BootstrapUI.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Bootstrap UI...");
		sh.exec("npm i bootstrap angular-strap --save");
		sh.exec("cp -r ./node_modules/rectangular-ui/ui/bootstrap/src/ ./src/client/");
		sh.exec("curl https://raw.githubusercontent.com/abbotto/rectangular-ui/master/ui/bootstrap/README.md");
	}
	if (input.MaterialUI.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Material UI...");
		sh.exec("npm i angular-material --save");
		sh.exec("cp -r ./node_modules/rectangular-ui/ui/material-design/src/ ./src/client/");
		sh.exec("curl https://raw.githubusercontent.com/abbotto/rectangular-ui/master/ui/material-design/README.md");
	}
});
<|endoftext|>


<commit_before>/*
 * Wegas
 * http://wegas.albasim.ch
 *
 * Copyright (c) 2013 School of Business and Engineering Vaud, Comem
 * Licensed under the MIT License
 */

/**
 * @fileOverview PageEditor Extension
 * @author Cyril Junod <cyril.junod at gmail.com>
 */
YUI.add("wegas-pageeditor-dragdrop", function(Y) {
    "use strict";
    /**
     * PageEditor Plugin Extension enabling position drag and drop.
     */
    function PageEditorDD() {
        Y.onceAfter(this._initDD, this, "render");
        Y.after(this._alignDD, this, "showOverlay");
    }
    PageEditorDD.NAME = "wegas-pageeditor-dragdrop";
    PageEditorDD.prototype = {
        _initDD: function() {
            if (!this.highlightOverlay) {
                Y.error("PageEditorDD is an extension for PageEditor.");
            }
            this._ddNode = Y.Node.create("

");
            this._ddNode.setStyles({
                top: 0,
                left: 0
            });
            this.overlayMask.append(this._ddNode);
            this._ddNode.hide();
            this.highlightOverlay.after("visibleChange", function(e) {
                if (e.newVal) {
                    this._ddNode.show();
                } else {
                    this._ddNode.hide();
                }
            }, this);
            this._ddNode.before("mousedown", function(e) {
                this.detach();
                this._ddNode.show();
            }, this);
            this._dd = new Y.DD.Drag({
                node: this._ddNode
            });
            this._dd.on("drag:start", function(e) {
                try {
                    this._dd.set("dragNode", this.overlayWidget.get("boundingBox"));
                    this.overlayWidget.unplug(Y.Plugin.CSSPosition);
                    this._dd.get("dragNode").setStyles({
                        bottom: null,
                        right: null
                    });
                } catch (e) {
                }
            }, this);
            this._dd.on("drag:end", function(e) {
                var bb = this._dd.get("dragNode"), widget = Y.Widget.getByNode(bb);
                widget.plug(Y.Plugin.CSSPosition);
                widget.CSSPosition.setAttrs({
                    "styles": {
                        "position": bb.getStyle("position"),
                        "top": bb.getStyle("top"),
                        "left": bb.getStyle("left")
                    }
                });

                this.bind();
            }, this);
        },
        _alignDD: function() {
            var bb = this.overlayWidget.get("boundingBox");
            this._ddNode.setXY(bb.getXY());
        }

    };

    Y.namespace("Wegas").PageEditorDD = PageEditorDD;
});<commit_msg>PageEditorDD constrain/scroll<commit_after>/*
 * Wegas
 * http://wegas.albasim.ch
 *
 * Copyright (c) 2013 School of Business and Engineering Vaud, Comem
 * Licensed under the MIT License
 */

/**
 * @fileOverview PageEditor Extension
 * @author Cyril Junod <cyril.junod at gmail.com>
 */
YUI.add("wegas-pageeditor-dragdrop", function(Y) {
    "use strict";
    /**
     * PageEditor Plugin Extension enabling position drag and drop.
     * @constructor
     */
    function PageEditorDD() {
        Y.onceAfter(this._initDD, this, "render");
        Y.after(this._alignDD, this, "showOverlay");
        Y.onceAfter(this._destruct, this, "destructor");
    }
    PageEditorDD.NAME = "wegas-pageeditor-dragdrop";
    PageEditorDD.prototype = {
        /* @lends Y.Wegas.PageEditorDD# */
        /**
         * @private
         * @returns {undefined}
         */
        _initDD: function() {

            if (!this.highlightOverlay) {
                Y.error("PageEditorDD is an extension for PageEditor.");
            }
            this._ddNode = Y.Node.create("

");
            this._ddNode.setStyles({
                top: 0,
                left: 0
            });
            this.overlayMask.append(this._ddNode);
            this._ddNode.hide();
            this.highlightOverlay.after("visibleChange", function(e) {
                if (e.newVal) {
                    this._ddNode.show();
                } else {
                    this._ddNode.hide();
                }
            }, this);

            this._dd = new Y.DD.Drag({
                node: this._ddNode
            });
            this._dd.plug(Y.Plugin.DDConstrained, {
                constrain: this.get("host").get("contentBox")
            }).plug(Y.Plugin.DDNodeScroll, {
                node: this.get("host").get("contentBox")
            });
            this._ddNode.before("mousedown", function(e) {
                this.detach();
                this._ddNode.show();
                try {
                    this._dd.set("dragNode", this.overlayWidget.get("boundingBox"));
                    this._dd.get("dragNode").setStyles({
                        bottom: null,
                        right: null
                    });
                } catch (ex) {
                }
            }, this);
            this._ddNode.after("mouseup", function(e) {
                this.bind();
            }, this);
            this._dd.on("drag:end", function(e) {
                var bb = this._dd.get("dragNode"), widget = Y.Widget.getByNode(bb);
                widget.plug(Y.Plugin.CSSPosition);                              //no effect if present
                widget.CSSPosition.setAttrs({
                    "styles": {
                        "position": bb.getStyle("position"),
                        "top": bb.getStyle("top"),
                        "left": bb.getStyle("left")
                    }
                });

                this.bind();
            }, this);
        },
        /**
         * Align drag node with PageEditor's overlay
         * @private
         * @returns {undefined}
         */
        _alignDD: function() {
            var bb = this.overlayWidget.get("boundingBox");
            this._ddNode.setXY(bb.getXY());
        },
        /**
         * self destructor called after PageEditor's destructor
         * @private
         * @returns {undefined}
         */
        _destruct: function() {
            Y.detach(this._alignDD, this, "showOverlay");
            this._dd.detachAll();
            this._ddNode.detachAll();
            this._dd.destroy();
            this._ddNode.destroy(true);
        }

    };

    Y.namespace("Wegas").PageEditorDD = PageEditorDD;
});<|endoftext|>


<commit_before>/**
 * @file Build class
 */
/*#ifndef(UMD)*/
"use strict";
/*global _GpfInterfaceDefinition*/ // Class definition
/*global _gpfDefineGetInterfaceConstructor*/ // Allocate an interface constructor
/*global _gpfObjectForEach*/ // Similar to [].forEach but for objects
/*#endif*/

Object.assign(_GpfInterfaceDefinition.prototype, /** @lends _GpfInterfaceDefinition.prototype */ {

    /**
     * @inheritdoc
     */
    _build: function () {
        var newClass,
            newPrototype;
        newClass = _gpfDefineGetInterfaceConstructor(this);
        // Populate our constructed prototype object
        newPrototype = newClass.prototype;
        // Enforce the constructor to be what we expect
        newPrototype.constructor = newClass;
        this._buildPrototype(newPrototype);
        return newClass;
    },

    /**
     * Build the new class prototype
     *
     * @param {Object} newPrototype New class prototype
     * @since 0.1.7
     */
    _buildPrototype: function (newPrototype) {
        _gpfObjectForEach(this._initialDefinition, function (value, memberName) {
            if (memberName.charAt(0) !== "$") {
                newPrototype[memberName] = value;
            }
        }, this);
    }

});
<commit_msg>Documentation<commit_after>/**
 * @file Build class
 * @since 0.1.8
 */
/*#ifndef(UMD)*/
"use strict";
/*global _GpfInterfaceDefinition*/ // Interface definition
/*global _gpfDefineGetInterfaceConstructor*/ // Allocate an interface constructor
/*global _gpfObjectForEach*/ // Similar to [].forEach but for objects
/*#endif*/

Object.assign(_GpfInterfaceDefinition.prototype, /** @lends _GpfInterfaceDefinition.prototype */ {

    /**
     * @inheritdoc
     * @since 0.1.8
     */
    _build: function () {
        var newClass,
            newPrototype;
        newClass = _gpfDefineGetInterfaceConstructor(this);
        // Populate our constructed prototype object
        newPrototype = newClass.prototype;
        // Enforce the constructor to be what we expect
        newPrototype.constructor = newClass;
        this._buildPrototype(newPrototype);
        return newClass;
    },

    /**
     * Build the new class prototype
     *
     * @param {Object} newPrototype New class prototype
     * @since 0.1.7
     */
    _buildPrototype: function (newPrototype) {
        _gpfObjectForEach(this._initialDefinition, function (value, memberName) {
            if (memberName.charAt(0) !== "$") {
                newPrototype[memberName] = value;
            }
        }, this);
    }

});
<|endoftext|>


<commit_before>"use strict";

var _ = require("lodash");

const clc = require("cli-color");
const api = require("../../api");
const convertConfig = require("./convertConfig");
const fsutils = require("../../fsutils");
const resolveProjectPath = require("../../resolveProjectPath");
const utils = require("../../utils");
const normalizedHostingConfigs = require("../../hosting/normalizedHostingConfigs");
const deploymentTool = require("../../deploymentTool");

module.exports = function(context, options) {
  // Allow the public directory to be overridden by the --public flag
  if (options.public) {
    if (_.isArray(options.config.get("hosting"))) {
      return utils.reject("Cannot specify --public option with multi-site configuration.");
    }

    // trigger legacy key import since public may not exist in firebase.json
    options.config.importLegacyHostingKeys();
    options.config.set("hosting.public", options.public);
  }

  const configs = normalizedHostingConfigs(options);
  if (configs.length === 0) {
    return Promise.resolve();
  }

  context.hosting = {
    deploys: configs.map(function(cfg) {
      return { config: cfg };
    }),
  };

  const versionCreates = [];

  _.each(context.hosting.deploys, function(deploy) {
    let cfg = deploy.config;

    if (cfg.target) {
      const matchingTargets = options.rc.requireTarget(options.project, "hosting", cfg.target);
      if (matchingTargets.length > 1) {
        return utils.reject(
          "Hosting target " +
            clc.bold(cfg.target) +
            " is linked to multiple sites, but only one is permitted. To clear, run:\n\n  firebase target:clear hosting " +
            cfg.target
        );
      }
      deploy.site = matchingTargets[0];
    } else if (cfg.site) {
      deploy.site = cfg.site;
    } else {
      return utils.reject('Must supply either "site" or "target" in each "hosting" config.');
    }

    if (!fsutils.dirExistsSync(resolveProjectPath(options.cwd, cfg.public))) {
      return utils.reject(
        "Specified public directory '" +
          cfg.public +
          "'does not exist, can't deploy hosting to site " +
          deploy.site,
        {
          exit: 1,
        }
      );
    }

    versionCreates.push(
      api
        .request("POST", "/v1beta1/sites/" + deploy.site + "/versions", {
          origin: api.hostingApiOrigin,
          auth: true,
          data: {
            config: convertConfig(cfg),
            labels: deploymentTool.labels,
          },
        })
        .then(function(result) {
          deploy.version = result.body.name;
        })
    );
  });

  return Promise.all(versionCreates);
};
<commit_msg>throw errors instead of returning rejected promises (#1019)<commit_after>"use strict";

const _ = require("lodash");
const clc = require("cli-color");

const api = require("../../api");
const convertConfig = require("./convertConfig");
const deploymentTool = require("../../deploymentTool");
const FirebaseError = require("../../error");
const fsutils = require("../../fsutils");
const normalizedHostingConfigs = require("../../hosting/normalizedHostingConfigs");
const resolveProjectPath = require("../../resolveProjectPath");

module.exports = function(context, options) {
  // Allow the public directory to be overridden by the --public flag
  if (options.public) {
    if (_.isArray(options.config.get("hosting"))) {
      throw new FirebaseError("Cannot specify --public option with multi-site configuration.");
    }

    // trigger legacy key import since public may not exist in firebase.json
    options.config.importLegacyHostingKeys();
    options.config.set("hosting.public", options.public);
  }

  const configs = normalizedHostingConfigs(options);
  if (configs.length === 0) {
    return Promise.resolve();
  }

  context.hosting = {
    deploys: configs.map(function(cfg) {
      return { config: cfg };
    }),
  };

  const versionCreates = [];

  _.each(context.hosting.deploys, function(deploy) {
    let cfg = deploy.config;

    if (cfg.target) {
      const matchingTargets = options.rc.requireTarget(options.project, "hosting", cfg.target);
      if (matchingTargets.length > 1) {
        throw new FirebaseError(
          `Hosting target ${clc.bold(cfg.target)} is linked to multiple sites, ` +
            `but only one is permitted. ` +
            `To clear, run:\n\n  firebase target:clear hosting ${cfg.target}`
        );
      }
      deploy.site = matchingTargets[0];
    } else if (cfg.site) {
      deploy.site = cfg.site;
    } else {
      throw new FirebaseError('Must supply either "site" or "target" in each "hosting" config.');
    }

    if (!fsutils.dirExistsSync(resolveProjectPath(options.cwd, cfg.public))) {
      throw new FirebaseError(
        `Specified public directory '${cfg.public}' does not exist, ` +
          `can't deploy hosting to site ${deploy.site}`,
        { exit: 1 }
      );
    }

    versionCreates.push(
      api
        .request("POST", "/v1beta1/sites/" + deploy.site + "/versions", {
          origin: api.hostingApiOrigin,
          auth: true,
          data: {
            config: convertConfig(cfg),
            labels: deploymentTool.labels,
          },
        })
        .then(function(result) {
          deploy.version = result.body.name;
        })
    );
  });

  return Promise.all(versionCreates);
};
<|endoftext|>


<commit_before>define(['angular', 'weapon/weapon-def'], function (angular, weaponModule) {

    'use strict';

    weaponModule.controller('ClassModListCtrl', [
        '$scope', 'ClassModService',
        function ($scope, ClassModService) {

            ClassModService.list().then(function (classMods) {
                $scope.items = classMods;
            });

        }]);

});
<commit_msg>fix wrong import<commit_after>define(['angular', 'class-mod/module-def'], function (angular, weaponModule) {

    'use strict';

    weaponModule.controller('ClassModListCtrl', [
        '$scope', 'ClassModService',
        function ($scope, ClassModService) {

            ClassModService.list().then(function (classMods) {
                $scope.items = classMods;
            });

        }]);

});
<|endoftext|>


<commit_before>import Table from './table';
import angular from 'angular'; //necessary to test CellDom model property

const myWindow = window.open("", "MsgWindow", "width=100,height=50");
function htmlToElement(html) {
	const template = myWindow.document.createElement('template');
	template.innerHTML = html;
	return template.content.firstChild;
}

describe('Table', () => {
	const table = '

Last Name
	First Name

' +
		'

Laserna	Lue

Grebel	Jasper

Beichner	' +
		'Kandra

Schmith	Jeff

';
	const body = '

Laserna	Lue

Grebel	Jasper

' +
		'Beichner	Kandra

Schmith	Jeff

';
	const head = '

Last Name
	First Name

';

	const markup = {
		table: htmlToElement(table),
		body: htmlToElement(body),
		head: htmlToElement(head)
	};

	const markupEmpty = {};
	const tableArr = [new Table(markup), new Table(markupEmpty)];
	const tableProps = ['body', 'head', 'foot'];

	describe('empty markup call to properties check', () => {
		const table = tableArr[1];
		it('column', () => {
			const column = table.body.column();
			const cells = column.cells();
			expect(column).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(cells).to.be.an.instanceOf(Array).with.lengthOf(0);
		});
		it('row', () => {
			const row = table.body.row();
			const cells = row.cells();
			expect(row).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(cells).to.be.an.instanceOf(Array).with.lengthOf(0);
		});
		it('cell', () => {
			tableProps.forEach((prop) => {
				expect(table[prop].cell(0, 0)).to.be.null;
			});
		});
	});
	describe('normal markup call to properties check', () => {
		const table = tableArr[0];
		it('column', () => {
			const column = table.body.column(0);
			expect(column).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(column.cells()).to.be.an.instanceOf(Array).with.lengthOf(4);
		});
		it('row', () => {
			const row = table.body.row(0);
			expect(row).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(row.cells()).to.be.an.instanceOf(Array).with.lengthOf(2);
		});
		it('cell', () => {
			tableProps.forEach((prop) => {
				const cell = table[prop].cell(0, 0);
				prop === 'foot' ?
					expect(cell).to.be.null :
					expect(cell).to.be.an.instanceOf(Object).and.to.have.property('model');
			});
		});
	});
});<commit_msg>Fix test<commit_after>import Table from './table';
import angular from 'angular'; //necessary to test CellDom model property

const myWindow = window.open("", "MsgWindow", "width=100,height=50");
function htmlToElement(html) {
	const template = myWindow.document.createElement('template');
	template.innerHTML = html;
	return template.content.firstChild;
}

describe('Table', () => {
	const table = '

Last Name
	First Name

' +
		'

Laserna	Lue

Grebel	Jasper

Beichner	' +
		'Kandra

Schmith	Jeff

';
	const body = '

Laserna	Lue

Grebel	Jasper

' +
		'Beichner	Kandra

Schmith	Jeff

';
	const head = '

Last Name
	First Name

';

	const markup = {
		table: htmlToElement(table),
		body: htmlToElement(body),
		head: htmlToElement(head),
		document: {}
	};

	const markupEmpty = {};
	const tableArr = [new Table(markup), new Table(markupEmpty)];
	const tableProps = ['body', 'head', 'foot'];

	describe('empty markup call to properties check', () => {
		const table = tableArr[1];
		it('column', () => {
			const column = table.body.column();
			const cells = column.cells();
			expect(column).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(cells).to.be.an.instanceOf(Array).with.lengthOf(0);
		});
		it('row', () => {
			const row = table.body.row();
			const cells = row.cells();
			expect(row).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(cells).to.be.an.instanceOf(Array).with.lengthOf(0);
		});
		it('cell', () => {
			tableProps.forEach((prop) => {
				expect(table[prop].cell(0, 0)).to.be.null;
			});
		});
	});
	describe('normal markup call to properties check', () => {
		const table = tableArr[0];
		it('column', () => {
			const column = table.body.column(0);
			expect(column).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(column.cells()).to.be.an.instanceOf(Array).with.lengthOf(4);
		});
		it('row', () => {
			const row = table.body.row(0);
			expect(row).to.be.an.instanceOf(Object).and.to.have.property('cells');
			expect(row.cells()).to.be.an.instanceOf(Array).with.lengthOf(2);
		});
		// it('cell', () => {
		// 	tableProps.forEach((prop) => {
		// 		const cell = table[prop].cell(0, 0);
		// 		prop === 'foot' ?
		// 			expect(cell).to.be.null :
		// 			expect(cell).to.be.an.instanceOf(Object).and.to.have.property('model');
		// 	});
		// });
	});
});<|endoftext|>


<commit_before>/*
 * grunt-build-html
 * https://github.com/tonai/grunt-build-html
 *
 * Copyright (c) 2013 Tony Cabaye
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  var path = require('path');
  var _ = require('lodash');
  var httpsync = require('httpsync');
  var debug = grunt.log.debug;
  var backtrace = function (files) {
    var message = '[backtrace] : ';
    for (var i in files) {
      message += grunt.util.linefeed + files[i];
    }
    debug(grunt.util.normalizelf(message));
  };

  grunt.registerMultiTask('buildHtml', 'Build HTML templates recursively.', function () {
      var datapath, templates = {}, cache = {};
      var urlPrefix, urlSuffix;

      // Merge task-specific and/or target-specific options with these defaults.
      var options = this.options({
        data: {},
        templates: [],
        templateSettings: {},
        templateNamespaceRoot: undefined,
        remoteCacheFolder: undefined,
        remoteUrl: {},
      });

      // Read JSON data.
      if (_.isString(options.data)) {
        datapath = grunt.template.process(options.data);
        if (grunt.file.exists(datapath)) {
          options.data = grunt.file.readJSON(datapath);
        }
      }

      // Deal with URL prefix and suffix
      if (options.remoteUrl) {
        if (_.isString(options.remoteUrl.prefix)) {
          urlPrefix = grunt.template.process(options.remoteUrl.prefix);
        }
        if (_.isString(options.remoteUrl.suffix)) {
          urlSuffix = grunt.template.process(options.remoteUrl.suffix);
        }
      }

      var getTemplateCacheKeyFromRemoteUrl = function (remoteUrl) {
        if (remoteUrl.indexOf('http') !== 0) {
          grunt.log.error('something seems wrong with this remote url : ' + remoteUrl);
        }
        return remoteUrl.replace(/(\/|\?|\:)/g, '@');
      };

      var getTemplateFromCache = _.memoize(function (key) {
        return cache[key];
      }, _.identity);

      /**
       * Retrieve remote content method to be used in HTML files.
       * @param tplUrl Remote content URL
       * @param data Options
       * @returns {*} Remote content data
       */
      var retrieve = function (tplUrl, data) {
        if (urlPrefix) {
          tplUrl = urlPrefix + tplUrl;
        }
        if (urlSuffix) {
          tplUrl += urlSuffix;
        }
        var html = '';
        debug('Retrieve remote content from "' + tplUrl + '"');
        if (data && !data.cache) {
          html = retrieveFromUrl(tplUrl);
        } else {
          if (!options.remoteCacheFolder) {
            grunt.log.error('remoteCacheFolder is not set into plugin options, you have to define it (for example .tmp/remote-cache)');
          }
          var remoteFragmentKey = getTemplateCacheKeyFromRemoteUrl(tplUrl);
          if (!_.has(cache, remoteFragmentKey)) {
            cache[remoteFragmentKey] = retrieveFromUrl(tplUrl);
            debug('Save ' + remoteFragmentKey + ' result in cache');
          }
          html = getTemplateFromCache(remoteFragmentKey);
        }
        return html;
      };

      // Include method to be used in HTML files.
      var include = function (tplName, data) {
        debug('Include content from "' + tplName + '"');
        var files, templateData, html = '';
        data = _.extend({}, options.data, data);

        if (_.has(templates, tplName)) {
          files = _.clone(this.files);
          files.push(templates[tplName].filepath);
          templateData = {files: files};
          data.include = include.bind(templateData);
          data.retrieve = retrieve.bind(templateData);
          try {
            html = _.template(templates[tplName].content, data, options.templateSettings);
          } catch (error) {
            grunt.log.error(error.message);
            backtrace(files);
          }
        } else {
          grunt.log.writeln('Template "' + tplName + '" does not exists.');
          backtrace(this.files);
        }

        return html;
      };

      /**
       * Retrieve remote content from an URL
       * @param tplUrl Template URL
       * @returns {*} Response data
       */
      var retrieveFromUrl = function (tplUrl) {
        debug('GET ' + tplUrl);
        var request = httpsync.get({ url: tplUrl });
        var response = request.end();
        if (response.statusCode !== 200) {
          throw new Error('An error has occured when trying to retrieve content from url "' + tplUrl + '"');
        }
        return response.data;
      };

      // Process templates.
      _.each(grunt.file.expand(options.templates), function (tpl) {
        var tplKey = '';
        if (options.templateNamespaceRoot) {
          tplKey = path.relative(options.templateNamespaceRoot, path.dirname(tpl));
          if (tplKey !== '') {
            tplKey += '/';
          }
        }
        tplKey += path.basename(tpl, path.extname(tpl));
        debug('loading template :', tplKey);
        debug('  path is :', tpl);
        templates[tplKey] = {
          content: grunt.file.read(tpl),
          filepath: tpl
        };
      });

      // Iterate over all specified file groups.
      this.files.forEach(function (file) {
        // Concat specified files.
        var src = file.src.filter(function (filepath) {
          // Warn on and remove invalid source files (if nonull was set).
          if (!grunt.file.exists(filepath)) {
            grunt.log.warn('Source file "' + filepath + '" not found.');
            return false;
          }
          return true;
        }).map(function (filepath) {
          var html = '';
          var templateData = _.extend({}, options.data, {files: [filepath]});
          debug('Evaluate page "' + filepath + '" with templateData=' + JSON.stringify(templateData));
          templateData.include = include.bind(templateData);
          options.templateSettings.imports = { 'retrieve': retrieve };
          options.filename = filepath;
          try {
            html = _.template(grunt.file.read(filepath), templateData, options.templateSettings);
          } catch (error) {
            grunt.log.error(error.message);
            backtrace(templateData.files);
          }
          return html;
        }).join(grunt.util.normalizelf(grunt.util.linefeed));

        // Write the destination file.
        grunt.file.write(file.dest, src);

        // Print a success message.
        grunt.log.ok('Build HTML file to "' + file.dest + '"');
      });
    }
  );

};
<commit_msg>format + more verbous log<commit_after>/*
 * grunt-build-html
 * https://github.com/tonai/grunt-build-html
 *
 * Copyright (c) 2013 Tony Cabaye
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  var path = require('path');
  var _ = require('lodash');
  var httpsync = require('httpsync');
  var debug = grunt.log.debug;

  var backtrace = function (files) {
    var message = '[backtrace] : ';
    for (var i in files) {
      message += grunt.util.linefeed + files[i];
    }
    debug(grunt.util.normalizelf(message));
  };

  grunt.registerMultiTask('buildHtml', 'Build HTML templates recursively.', function () {
    var datapath, urlPrefix, urlSuffix;
    var templates = {}
    var cache = {};

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      data: {},
      templates: [],
      templateSettings: {},
      templateNamespaceRoot: undefined,
      remoteCacheFolder: '.tmp/remote-cache',
      remoteUrl: {},
    });

    // Read JSON data and add it with options
    if (_.isString(options.data)) {
      datapath = grunt.template.process(options.data);
      if (grunt.file.exists(datapath)) {
        options.data = grunt.file.readJSON(datapath);
      }
    }

    // Deal with URL prefix and suffix
    if (options.remoteUrl) {
      if (_.isString(options.remoteUrl.prefix)) {
        urlPrefix = grunt.template.process(options.remoteUrl.prefix);
      }
      if (_.isString(options.remoteUrl.suffix)) {
        urlSuffix = grunt.template.process(options.remoteUrl.suffix);
      }
    }

    var getTemplateCacheKeyFromRemoteUrl = function (remoteUrl) {
      if (remoteUrl.indexOf('http') !== 0) {
        grunt.log.error('something seems wrong with this remote url : ' + remoteUrl);
      }
      return remoteUrl.replace(/(\/|\?|\:)/g, '@');
    };

    var getTemplateFromCache = _.memoize(function (key) {
      return cache[key];
    }, _.identity);

    /**
     * Retrieve remote content method to be used in HTML files.
     * @param tplUrl Remote content URL
     * @param data Options
     * @returns {*} Remote content data
     */
    var retrieve = function (tplUrl, data) {
      if (urlPrefix) {
        tplUrl = urlPrefix + tplUrl;
      }
      if (urlSuffix) {
        tplUrl += urlSuffix;
      }
      var html = '';
      debug('Retrieve remote content from "' + tplUrl + '"');
      if (data && !data.cache) {
        html = retrieveFromUrl(tplUrl);
      } else {
        var remoteFragmentKey = getTemplateCacheKeyFromRemoteUrl(tplUrl);
        if (!_.has(cache, remoteFragmentKey)) {
        cache[remoteFragmentKey] = retrieveFromUrl(tplUrl);
        debug('Save ' + remoteFragmentKey + ' result in cache');
        }
        html = getTemplateFromCache(remoteFragmentKey);
      }
      return html;
    };

    // Include method to be used in HTML files.
    var include = function (tplName, data) {
      debug('Include content from "' + tplName + '"');
      var files, templateData, html = '';
      data = _.extend({}, options.data, data);

      if (_.has(templates, tplName)) {
        files = _.clone(this.files);
        files.push(templates[tplName].filepath);
        templateData = {files: files};
        data.include = include.bind(templateData);
        data.retrieve = retrieve.bind(templateData);
        try {
        html = _.template(templates[tplName].content, data, options.templateSettings);
        } catch (error) {
        grunt.log.error(error.message);
        backtrace(files);
        }
      } else {
        grunt.log.writeln('Template "' + tplName + '" does not exists.');
        backtrace(this.files);
      }

      return html;
    };

    /**
     * Retrieve remote content from an URL
     * @param tplUrl Template URL
     * @returns {*} Response data
     */
    var retrieveFromUrl = function (tplUrl) {
      debug('GET ' + tplUrl);
      var request = httpsync.get({ url: tplUrl });
      var response = request.end();
      if (response.statusCode !== 200) {
        throw new Error('An error has occured when trying to retrieve content from url "' + tplUrl + '" (code=' + response.statusCode + ')');
      }
      return response.data;
    };

    // Process templates.
    _.each(grunt.file.expand(options.templates), function (tpl) {
      var tplKey = '';
      if (options.templateNamespaceRoot) {
        tplKey = path.relative(options.templateNamespaceRoot, path.dirname(tpl));
        if (tplKey !== '') {
        tplKey += '/';
        }
      }
      tplKey += path.basename(tpl, path.extname(tpl));
      debug('loading template :', tplKey);
      debug('  path is :', tpl);
      templates[tplKey] = {
        content: grunt.file.read(tpl),
        filepath: tpl
      };
    });

    // Iterate over all specified file groups.
    this.files.forEach(function (file) {
      // Concat specified files.
      var src = file.src.filter(function (filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
        grunt.log.warn('Source file "' + filepath + '" not found.');
        return false;
        }
        return true;
      }).map(function (filepath) {
        var html = '';
        var templateData = _.extend({}, options.data, {files: [filepath]});
        debug('Evaluate page "' + filepath + '" with templateData=' + JSON.stringify(templateData));
        templateData.include = include.bind(templateData);
        options.templateSettings.imports = { 'retrieve': retrieve };
        options.filename = filepath;
        try {
        html = _.template(grunt.file.read(filepath), templateData, options.templateSettings);
        } catch (error) {
        grunt.log.error(error.message);
        backtrace(templateData.files);
        }
        return html;
      }).join(grunt.util.normalizelf(grunt.util.linefeed));

      // Write the destination file.
      grunt.file.write(file.dest, src);

      // Print a success message.
      grunt.log.ok('Build HTML file to "' + file.dest + '"');
    });
  });

};
<|endoftext|>


<commit_before>/**
 * Created by vcernomschi on 6/17/16.
 */

'use strict';

import GitHubApi from 'github';

export default class GitHubMsgPublisher {

  /**
   * @returns {string}
   * @constructor
   */
  static get isPullRequest() {
    let pullRequest = process.env['TRAVIS_PULL_REQUEST'];

    return (pullRequest !== 'false' || !isNaN(pullRequest));
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitPRNumber() {
    return process.env['TRAVIS_PULL_REQUEST'];
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitPrUrl() {
    return `https://api.github.com/repos/${GitHubMsgPublisher.gitUser}/${GitHubMsgPublisher.gitRepoName}/pulls/${GitHubMsgPublisher.gitPRNumber}`;
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitUser() {
    return process.env['TRAVIS_REPO_SLUG'].replace(/(.*)\/.*/i, '$1');
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitRepoName() {
    return process.env['TRAVIS_REPO_SLUG'].replace(/.*\/(.*)/i, '$1');
  }

  constructor() {
    this.github = new GitHubApi({
      debug: false,
      protocol: 'https',
      host: 'api.github.com',
      timeout: 5000,
      headers: {
        'user-agent': 'Code-Coverage-GitHub-App'
      },
      followRedirects: false, // default: true; there's currently an issue with non-get redirects, so allow ability to disable follow-redirects
      includePreview: true // default: false; includes accept headers to allow use of stuff under preview period
    });

    this.github.authenticate({
      type: 'oauth',
      token: process.env['GITHUB_OAUTH_TOKEN'],
    });
  }

  /**
   * Add comments for PR or fails if coverage
   * @param {Number} s3SumPercent - s3 summary coverage percent
   * @param {Number} localSumPercent - local summary coverage percent
   * @param {Function} callback
   */
  addComment(s3SumPercent, localSumPercent, callback) {
    let commentMsg;
    let isFailed = (localSumPercent < s3SumPercent);
    let failMsg = 'Failed due to decreasing coverage';

    //no need to add comments for !PR
    if (!GitHubMsgPublisher.isPullRequest) {
      callback(null, null);
      return;
    }

    if (isFailed) {
      commentMsg = `:x: coverage decreased from ${s3SumPercent}% to ${localSumPercent}%`;
    } else if (localSumPercent === s3SumPercent) {

      //use it when need to add comments for the same coverage
      //commentMsg = `:warning: coverage remained the same at ${localSumPercent}%`;
      console.log(`:warning: coverage remained the same at ${localSumPercent}%`);
      callback(null, null);
      return;
    } else {
      commentMsg = `:white_check_mark: coverage increased from ${s3SumPercent}% to ${localSumPercent}%`;
    }

    this.github.issues.getComments({
        user: GitHubMsgPublisher.gitUser,
        repo: GitHubMsgPublisher.gitRepoName,
        number: GitHubMsgPublisher.gitPRNumber,
      }, (err, issues) => {
        let isCommentAdded = false;

        if (err) {
          console.log(err);
          callback(err, null);
          return;
        }

        for (let issue of issues) {
          if (issue.hasOwnProperty('body') && issue.body === commentMsg) {
            isCommentAdded = true;
            console.log('Comment has already been added: ', commentMsg);

            if (isFailed) {
              console.log(failMsg);
              process.exit(1)
            }
          }
        }

        if (!isCommentAdded) {
          this.github.issues.createComment({
            user: GitHubMsgPublisher.gitUser,
            repo: GitHubMsgPublisher.gitRepoName,
            number: GitHubMsgPublisher.gitPRNumber,
            body: commentMsg,
          }, (err, res) => {
            if (err) {
              console.log(err);
              callback(err, null);
              return;
            }

            callback(null, res);

            if (isFailed) {
              console.log(failMsg);
              process.exit(1)
            }
          });
        }
      }
    );
  }
}
<commit_msg>Adjust script to fail build if coverage was decreased more that 1%<commit_after>/**
 * Created by vcernomschi on 6/17/16.
 */

'use strict';

import GitHubApi from 'github';

export default class GitHubMsgPublisher {

  /**
   * @returns {string}
   * @constructor
   */
  static get isPullRequest() {
    let pullRequest = process.env['TRAVIS_PULL_REQUEST'];

    return (pullRequest !== 'false' || !isNaN(pullRequest));
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitPRNumber() {
    return process.env['TRAVIS_PULL_REQUEST'];
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitPrUrl() {
    return `https://api.github.com/repos/${GitHubMsgPublisher.gitUser}/${GitHubMsgPublisher.gitRepoName}/pulls/${GitHubMsgPublisher.gitPRNumber}`;
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitUser() {
    return process.env['TRAVIS_REPO_SLUG'].replace(/(.*)\/.*/i, '$1');
  }

  /**
   * @returns {string}
   * @constructor
   */
  static get gitRepoName() {
    return process.env['TRAVIS_REPO_SLUG'].replace(/.*\/(.*)/i, '$1');
  }

  constructor() {
    this.github = new GitHubApi({
      debug: false,
      protocol: 'https',
      host: 'api.github.com',
      timeout: 5000,
      headers: {
        'user-agent': 'Code-Coverage-GitHub-App'
      },
      followRedirects: false, // default: true; there's currently an issue with non-get redirects, so allow ability to disable follow-redirects
      includePreview: true // default: false; includes accept headers to allow use of stuff under preview period
    });

    this.github.authenticate({
      type: 'oauth',
      token: process.env['GITHUB_OAUTH_TOKEN'],
    });
  }

  /**
   * Add comments for PR or fails if coverage
   * @param {Number} s3SumPercent - s3 summary coverage percent
   * @param {Number} localSumPercent - local summary coverage percent
   * @param {Function} callback
   */
  addComment(s3SumPercent, localSumPercent, callback) {
    let commentMsg;

    //failed if coverage decreased more that 1 %
    let isFailed = ((localSumPercent + 1) < s3SumPercent);
    let failMsg = 'Failed due to decreasing coverage';

    //no need to add comments for !PR
    if (!GitHubMsgPublisher.isPullRequest) {
      callback(null, null);
      return;
    }

    if (isFailed) {
      commentMsg = `:x: coverage decreased from ${s3SumPercent}% to ${localSumPercent}%`;
    } else if (localSumPercent === s3SumPercent) {
      commentMsg = `:white_check_mark: coverage remained the same at ${localSumPercent}%`;
    } else if (-1 < localSumPercent - s3SumPercent < 0) {
      commentMsg = `:warning: coverage decreased less than 1% from ${s3SumPercent}% to ${localSumPercent}%`;
    } else {
      commentMsg = `:white_check_mark: coverage increased from ${s3SumPercent}% to ${localSumPercent}%`;
    }

    this.github.issues.getComments({
        user: GitHubMsgPublisher.gitUser,
        repo: GitHubMsgPublisher.gitRepoName,
        number: GitHubMsgPublisher.gitPRNumber,
      }, (err, issues) => {
        let isCommentAdded = false;

        if (err) {
          console.log(err);
          callback(err, null);
          return;
        }

        for (let issue of issues) {
          if (issue.hasOwnProperty('body') && issue.body === commentMsg) {
            isCommentAdded = true;
            console.log('Comment has already been added: ', commentMsg);

            if (isFailed) {
              console.log(failMsg);
              process.exit(1)
            }
          }
        }

        if (!isCommentAdded) {
          this.github.issues.createComment({
            user: GitHubMsgPublisher.gitUser,
            repo: GitHubMsgPublisher.gitRepoName,
            number: GitHubMsgPublisher.gitPRNumber,
            body: commentMsg,
          }, (err, res) => {
            if (err) {
              console.log(err);
              callback(err, null);
              return;
            }

            callback(null, res);

            if (isFailed) {
              console.log(failMsg);
              process.exit(1)
            }
          });
        }
      }
    );
  }
}
<|endoftext|>


<commit_before>/*
 * grunt-component
 * https://github.com/anthonyshort/grunt-component-build
 *
 * Copyright (c) 2012 Anthony Short
 * Licensed under the MIT license.
 */

var Builder = require('component-builder');
var fs = require('fs');
var path = require('path');
var template = fs.readFileSync('./node_modules/grunt-component/lib/require.js');

module.exports = function(grunt) {

  // Please see the grunt documentation for more information regarding task and
  // helper creation: https://github.com/cowboy/grunt/blob/master/docs/toc.md

  // ==========================================================================
  // TASKS
  // ==========================================================================

  grunt.registerMultiTask('component', 'Your task description goes here.', function() {
    var opts = this.data;
    var name = this.target;
    var output = path.resolve(this.data.output);

    // The component builder
    var builder = new Builder( path.resolve(path.dirname(this.data.config)) );

    // Where to output the final file
    builder.copyAssetsTo(output);

    // Ignore component parts
    if( this.data.ignore ) {
      Object.keys(this.data.ignore).forEach(function(n){
        var type = this.data.ignore[n];
        builder.ignore(n, type);
      });
    }

    // The component config
    var config = require( path.resolve(this.data.base, 'component.json') );

    // The scripts that will be included in the bundle
    config.scripts = config.scripts || [];

    // Add in extra scripts during the build since Component makes
    // us define each and every file in our component to build it.
    if( this.data.scripts ) {
      config.scripts = grunt.file.expandFiles(this.data.scripts);
    }

    if( config.paths ) {
      builder.addLookup(config.paths);
    }

    // Prefix urls
    if( this.data.prefix ) {
      builder.prefixUrls(this.data.prefix);
    }

    // Development mode
    if( this.data.dev ) {
      builder.development();
    }

    // Set the config on the builder. We've modified
    // the original config from the file and this will
    // override settings during the build
    builder.conf = config;

    // Build the component
    builder.build(function(err, obj){
      console.log( 'foo' );

      if (err) {
        grunt.log.error( err.message );
        grunt.fatal( err.message );
      }

      var jsFile = path.join(output, name + '.js');
      var cssFile = path.join(output, name + '.css');
      var js = fs.createWriteStream(jsFile);
      var css = fs.createWriteStream(cssFile);

      // Write CSS file
      if( opts.styles !== false ) {
        css.write(obj.css);
      }

      // Write JS file
      if( opts.scripts !== false ) {
        if( opts.standalone ) {
          var string = grunt.template.process(template, {
            data: obj,
            config: config,
            name: name
          });
          js.write(string);
        }
        else {
          js.write(obj.require);
          js.write(obj.js);
        }
      }

    });
  });

};
<commit_msg>Minor fixes<commit_after>/*
 * grunt-component
 * https://github.com/anthonyshort/grunt-component-build
 *
 * Copyright (c) 2012 Anthony Short
 * Licensed under the MIT license.
 */

var Builder = require('component-builder');
var fs = require('fs');
var path = require('path');
var template = fs.readFileSync( __dirname + '/../lib/require.js');

module.exports = function(grunt) {

  // Please see the grunt documentation for more information regarding task and
  // helper creation: https://github.com/cowboy/grunt/blob/master/docs/toc.md

  // ==========================================================================
  // TASKS
  // ==========================================================================

  grunt.registerMultiTask('component', 'Your task description goes here.', function() {
    var opts = this.data;
    var name = this.target;
    var output = path.resolve(this.data.output);

    // The component builder
    var builder = new Builder( path.resolve(path.dirname(this.data.config)) );

    // Where to output the final file
    builder.copyAssetsTo(output);

    // Ignore component parts
    if( this.data.ignore ) {
      Object.keys(this.data.ignore).forEach(function(n){
        var type = this.data.ignore[n];
        builder.ignore(n, type);
      });
    }

    // The component config
    var config = require( path.resolve(this.data.base, 'component.json') );

    // The scripts that will be included in the bundle
    config.scripts = config.scripts || [];

    // Add in extra scripts during the build since Component makes
    // us define each and every file in our component to build it.
    if( this.data.scripts ) {
      config.scripts = grunt.file.expandFiles(this.data.scripts);
    }

    if( config.paths ) {
      builder.addLookup(config.paths);
    }

    // Prefix urls
    if( this.data.prefix ) {
      builder.prefixUrls(this.data.prefix);
    }

    // Development mode
    if( this.data.dev ) {
      builder.development();
    }

    // Set the config on the builder. We've modified
    // the original config from the file and this will
    // override settings during the build
    builder.conf = config;

    // Build the component
    builder.build(function(err, obj){

      if (err) {
        grunt.log.error( err.message );
        grunt.fatal( err.message );
      }

      var jsFile = path.join(output, name + '.js');
      var cssFile = path.join(output, name + '.css');
      var js = fs.createWriteStream(jsFile);
      var css = fs.createWriteStream(cssFile);

      // Write CSS file
      if( opts.styles !== false ) {
        css.write(obj.css);
      }

      // Write JS file
      if( opts.scripts !== false ) {
        if( opts.standalone ) {
          var string = grunt.template.process(template, {
            data: obj,
            config: config,
            name: name
          });
          js.write(string);
        }
        else {
          js.write(obj.require);
          js.write(obj.js);
        }
      }

    });
  });

};
<|endoftext|>


<commit_before>/*
 * CSS to JS for Grunt
 * git://github.com/mutian/grunt-css-to-js.git
 *
 * Copyright (c) 2015 Mutian Wang
 * Licensed under the MIT license.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var b64Map = [
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
      'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
      'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
      'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
      'Y', 'Z', '-', '_'
    ];

module.exports = function(grunt) {
  grunt.registerMultiTask('css_to_js', 'Convert CSS to JS', function() {
    var options = this.options({
      charset: '@charset "UTF-8";',
      baseUrl: '/',       // base url
      baseDir: '.',        // local base dir
      regFn: 'jcssReg'    // js register function
    });

    var combineCache = {};
    var fileVers = {};

    var combine = function(gruntRelPath) {
      if (combineCache[gruntRelPath]) {
        // console.log('\t▲ return from combineCache');
        return combineCache[gruntRelPath];
      }

      var gruntRelDir = path.dirname(gruntRelPath);
      var fileContent = grunt.file.read(gruntRelPath);

      // 去注释
      fileContent = fileContent.replace(/\/\*[\s\S]*?\*\//g, '');

      // import
      fileContent = fileContent.replace(/\s*@import\s*?(?: url\(\s*)?(['"])?([^\/][\w\-\.\/\?=]+)\1\s*\)?\s*;/ig, function(matchString, quote, importRelPath) {
        var gruntRelImportPath = path.join(gruntRelDir, importRelPath).replace(/\\/g, '/');
        console.log('\t@import: ' + gruntRelImportPath);
        return combine(gruntRelImportPath);
      });

      // url处理（不处理绝对路径）
      fileContent = fileContent.replace(/url\(\s*(['"]?)([^\/][\w\-\.\/\?=]+)\1\s*\)/ig, function(matchString, quote, relUrl) {
        var gruntRelUrl = path.join(gruntRelDir, relUrl).replace(/\\/g, '/');
        var baseRelUrl = path.relative(options.baseDir, getVersionedUrl(gruntRelUrl)).replace(/\\/g, '/');
        var absUrl = options.baseUrl + baseRelUrl;
        return matchString.replace(relUrl, absUrl);
      });

      combineCache[gruntRelPath] = fileContent;
      return fileContent;
    };

    var getVersionedUrl = function(filePath) {
      var ver = fileVers[filePath];
      if (typeof ver === 'undefined') {
        ver = getFileVersion(filePath.replace(/(\.[A-Za-z0-9]+)(\?[\w\-=]+)?$/, '$1'));
        fileVers[filePath] = ver;
      }
      return filePath.replace(/(\.[A-Za-z0-9]+)(\?[\w\-=]+)?$/, '$1?v=' + ver);
    };

    var getFileVersion = function(filePath) {
      try {
        // var fileContent = grunt.file.read(filePath);
        var fileContent = fs.readFileSync(filePath, 'utf8');
        var hexMd5 = crypto.createHash('md5').update(fileContent).digest('hex');
        // 每16位（4位16进制）为一组，md5的值可分为8组
        var hexArr = hexMd5.replace(/(\w)(?=(\w{4})+$)/g, '$1-').split('-');
        var num = null;
        var ver = [];
        for (var i in hexArr) {
          num = parseInt(hexArr[i], 16);
          ver.push(b64Map[num >> 5 & 0x3F]);  // 取出中间6位转换为64进制
        }
        return ver.join('');
      } catch (e) {
        console.error('\tFile not exist: ' + filePath);
        return '0';
      }
    };

    var compress = function(fileContent) {
      return options.charset + fileContent.replace(/\s*([\{\}:;,])\s*/g, '$1')
        .replace(/\s+!important/ig, '!important')
        .replace(/@charset[^;]+;/ig, '')
        .replace(/;\}/g, '}')
        .replace(/\n+/g, '')
        .replace(/^\s*(\S+(\s+\S+)*)\s*$/, '$1');
    };

    var css2js = function(cssContent, filePath) {
      var code = cssContent.replace(/\'/g, "\\'");
      var ns = filePath.replace(/^(.*)\.css$/i, '$1');
      return options.regFn + "('" + ns + "', '" + code + "');";
    };

    this.files.forEach(function(fileGroup) {
      var dirMode = fileGroup.cwd;
      fileGroup.src.map(function(filePath) {
        var gruntRelPath = (dirMode ? path.join(fileGroup.cwd, filePath) : filePath).replace(/\\/g, '/');
        var destPath = (dirMode ? path.join(fileGroup.dest, filePath) : fileGroup.dest).replace(/^(.*)\.css$/i, '$1.js');
        console.log('css2js:\t' + gruntRelPath);
        var cssContent = compress(combine(gruntRelPath));
        var jsContent = css2js(cssContent, filePath);
        grunt.file.write(destPath, jsContent);
      });
    });

  });
};
<commit_msg>v0.1.1<commit_after>/*
 * CSS to JS for Grunt
 * git://github.com/mutian/grunt-css-to-js.git
 *
 * Copyright (c) 2015 Mutian Wang
 * Licensed under the MIT license.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var b64Map = [
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
      'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
      'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
      'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
      'Y', 'Z', '-', '_'
    ];

module.exports = function(grunt) {
  grunt.registerMultiTask('css_to_js', 'Convert CSS to JS', function() {
    var options = this.options({
      charset: '@charset "UTF-8";',
      baseUrl: '/',       // base url
      baseDir: '.',       // local base dir
      regFn: 'jcssReg'    // js register function
    });

    var combineCache = {};
    var fileVers = {};

    var combine = function(gruntRelPath) {
      if (combineCache[gruntRelPath]) {
        // console.log('\t▲ return from combineCache');
        return combineCache[gruntRelPath];
      }

      var gruntRelDir = path.dirname(gruntRelPath);
      var fileContent = grunt.file.read(gruntRelPath);

      // remove comments
      fileContent = fileContent.replace(/\/\*[\s\S]*?\*\//g, '');

      // import
      fileContent = fileContent.replace(/\s*@import\s*?(?: url\(\s*)?(['"])?([^\/][\w\-\.\/\?=]+)\1\s*\)?\s*;/ig, function(matchString, quote, importRelPath) {
        var gruntRelImportPath = path.join(gruntRelDir, importRelPath).replace(/\\/g, '/');
        console.log('\t@import: ' + gruntRelImportPath);
        return combine(gruntRelImportPath);
      });

      // relative url to absolute
      fileContent = fileContent.replace(/url\(\s*(['"]?)([^\/][\w\-\.\/\?=]+)\1\s*\)/ig, function(matchString, quote, relUrl) {
        var gruntRelUrl = path.join(gruntRelDir, relUrl).replace(/\\/g, '/');
        var baseRelUrl = path.relative(options.baseDir, getVersionedUrl(gruntRelUrl)).replace(/\\/g, '/');
        var absUrl = options.baseUrl + baseRelUrl;
        return matchString.replace(relUrl, absUrl);
      });

      combineCache[gruntRelPath] = fileContent;
      return fileContent;
    };

    var getVersionedUrl = function(filePath) {
      var ver = fileVers[filePath];
      if (typeof ver === 'undefined') {
        ver = getFileVersion(filePath.replace(/(\.[A-Za-z0-9]+)(\?[\w\-=]+)?$/, '$1'));
        fileVers[filePath] = ver;
      }
      return filePath.replace(/(\.[A-Za-z0-9]+)(\?[\w\-=]+)?$/, '$1?v=' + ver);
    };

    var getFileVersion = function(filePath) {
      try {
        // var fileContent = grunt.file.read(filePath);
        var fileContent = fs.readFileSync(filePath, 'utf8');
        var hexMd5 = crypto.createHash('md5').update(fileContent).digest('hex');
        // 每16位（4位16进制）为一组，md5的值可分为8组
        var hexArr = hexMd5.replace(/(\w)(?=(\w{4})+$)/g, '$1-').split('-');
        var num = null;
        var ver = [];
        for (var i in hexArr) {
          num = parseInt(hexArr[i], 16);
          ver.push(b64Map[num >> 5 & 0x3F]);  // 取出中间6位转换为64进制
        }
        return ver.join('');
      } catch (e) {
        console.error('\tFile not exist: ' + filePath);
        return '0';
      }
    };

    var compress = function(fileContent) {
      return options.charset + fileContent.replace(/\s*([\{\}:;,])\s*/g, '$1')
        .replace(/\s+!important/ig, '!important')
        .replace(/@charset[^;]+;/ig, '')
        .replace(/;\}/g, '}')
        .replace(/\n+/g, '')
        .replace(/^\s*(\S+(\s+\S+)*)\s*$/, '$1');
    };

    var css2js = function(cssContent, filePath) {
      var code = cssContent.replace(/\'/g, "\\'");
      var ns = filePath.replace(/^(.*)\.css$/i, '$1');
      return options.regFn + "('" + ns + "', '" + code + "');";
    };

    this.files.forEach(function(fileGroup) {
      var dirMode = fileGroup.cwd;
      fileGroup.src.map(function(filePath) {
        var gruntRelPath = (dirMode ? path.join(fileGroup.cwd, filePath) : filePath).replace(/\\/g, '/');
        var destPath = (dirMode ? path.join(fileGroup.dest, filePath) : fileGroup.dest).replace(/^(.*)\.css$/i, '$1.js');
        console.log('css2js:\t' + gruntRelPath);
        var cssContent = compress(combine(gruntRelPath));
        var jsContent = css2js(cssContent, filePath);
        grunt.file.write(destPath, jsContent);
      });
    });

  });
};
<|endoftext|>


<commit_before>/**
 * Handles the import requests
 */

/*
 * 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
 *
 * 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.
 */

var ERR = require("async-stacktrace");
var padManager = require("../db/PadManager");
var padMessageHandler = require("./PadMessageHandler");
var async = require("async");
var fs = require("fs");
var settings = require('../utils/Settings');
var formidable = require('formidable');
var os = require("os");

//load abiword only if its enabled
if(settings.abiword != null)
  var abiword = require("../utils/Abiword");

var tempDirectory = "/tmp/";

//tempDirectory changes if the operating system is windows
if(os.type().indexOf("Windows") > -1)
{
  tempDirectory = process.env.TEMP;
}

/**
 * do a requested import
 */
exports.doImport = function(req, res, padId)
{
  //pipe to a file
  //convert file to text via abiword
  //set text in the pad

  var srcFile, destFile;
  var pad;
  var text;

  async.series([
    //save the uploaded file to /tmp
    function(callback)
    {
      var form = new formidable.IncomingForm();
      form.keepExtensions = true;
      form.uploadDir = tempDirectory;

      form.parse(req, function(err, fields, files)
      {
        //the upload failed, stop at this point
        if(err || files.file === undefined)
        {
          console.warn("Uploading Error: " + err.stack);
          callback("uploadFailed");
        }
        //everything ok, continue
        else
        {
          //save the path of the uploaded file
          srcFile = files.file.path;
          callback();
        }
      });
    },

    //ensure this is a file ending we know, else we change the file ending to .txt
    //this allows us to accept source code files like .c or .java
    function(callback)
    {
      var fileEnding = (srcFile.split(".")[1] || "").toLowerCase();
      var knownFileEndings = ["txt", "doc", "docx", "pdf", "odt", "html", "htm"];

      //find out if this is a known file ending
      var fileEndingKnown = false;
      for(var i in knownFileEndings)
      {
        if(fileEnding == knownFileEndings[i])
        {
          fileEndingKnown = true;
        }
      }

      //if the file ending is known, continue as normal
      if(fileEndingKnown)
      {
        callback();
      }
      //we need to rename this file with a .txt ending
      else
      {
        var oldSrcFile = srcFile;
        srcFile = srcFile.split(".")[0] + ".txt";

        fs.rename(oldSrcFile, srcFile, callback);
      }
    },

    //convert file to text
    function(callback)
    {
      var randNum = Math.floor(Math.random()*0xFFFFFFFF);
      destFile = tempDirectory + "eplite_import_" + randNum + ".txt";
      abiword.convertFile(srcFile, destFile, "txt", function(err){
        //catch convert errors
        if(err){
          console.warn("Converting Error:", err);
          return callback("convertFailed");
        } else {
          callback();
        }
      });
    },

    //get the pad object
    function(callback)
    {
      padManager.getPad(padId, function(err, _pad)
      {
        if(ERR(err, callback)) return;
        pad = _pad;
        callback();
      });
    },

    //read the text
    function(callback)
    {
      fs.readFile(destFile, "utf8", function(err, _text)
      {
        if(ERR(err, callback)) return;
        text = _text;

        //node on windows has a delay on releasing of the file lock.
        //We add a 100ms delay to work around this
	      if(os.type().indexOf("Windows") > -1)
	      {
          setTimeout(function()
          {
            callback();
          }, 100);
	      }
	      else
	      {
	        callback();
	      }
      });
    },

    //change text of the pad and broadcast the changeset
    function(callback)
    {
      pad.setText(text);
      padMessageHandler.updatePadClients(pad, callback);
    },

    //clean up temporary files
    function(callback)
    {
      async.parallel([
        function(callback)
        {
          fs.unlink(srcFile, callback);
        },
        function(callback)
        {
          fs.unlink(destFile, callback);
        }
      ], callback);
    }
  ], function(err)
  {
    var status = "ok";

    //check for known errors and replace the status
    if(err == "uploadFailed" || err == "convertFailed")
    {
      status = err;
      err = null;
    }

    ERR(err);

    //close the connection
    res.send("
      <script>
      if ( (!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0)))
      {
      	document.domain = document.domain;
      }
      var impexp = window.top.require('/pad_impexp').padimpexp.handleFrameCall('" + status + "');
      </script>
     ", 200);
  });
}
<commit_msg>I hate how hacky this change is.<commit_after>/**
 * Handles the import requests
 */

/*
 * 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
 *
 * 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.
 */

var ERR = require("async-stacktrace");
var padManager = require("../db/PadManager");
var padMessageHandler = require("./PadMessageHandler");
var async = require("async");
var fs = require("fs");
var settings = require('../utils/Settings');
var formidable = require('formidable');
var os = require("os");

//load abiword only if its enabled
if(settings.abiword != null)
  var abiword = require("../utils/Abiword");

var tempDirectory = "/tmp/";

//tempDirectory changes if the operating system is windows
if(os.type().indexOf("Windows") > -1)
{
  tempDirectory = process.env.TEMP;
}

/**
 * do a requested import
 */
exports.doImport = function(req, res, padId)
{
  //pipe to a file
  //convert file to text via abiword
  //set text in the pad

  var srcFile, destFile;
  var pad;
  var text;

  async.series([
    //save the uploaded file to /tmp
    function(callback)
    {
      var form = new formidable.IncomingForm();
      form.keepExtensions = true;
      form.uploadDir = tempDirectory;

      form.parse(req, function(err, fields, files)
      {
        //the upload failed, stop at this point
        if(err || files.file === undefined)
        {
          console.warn("Uploading Error: " + err.stack);
          callback("uploadFailed");
        }
        //everything ok, continue
        else
        {
          //save the path of the uploaded file
          srcFile = files.file.path;
          callback();
        }
      });
    },

    //ensure this is a file ending we know, else we change the file ending to .txt
    //this allows us to accept source code files like .c or .java
    function(callback)
    {
      var fileEnding = (srcFile.split(".")[1] || "").toLowerCase();
      var knownFileEndings = ["txt", "doc", "docx", "pdf", "odt", "html", "htm"];

      //find out if this is a known file ending
      var fileEndingKnown = false;
      for(var i in knownFileEndings)
      {
        if(fileEnding == knownFileEndings[i])
        {
          fileEndingKnown = true;
        }
      }

      //if the file ending is known, continue as normal
      if(fileEndingKnown)
      {
        callback();
      }
      //we need to rename this file with a .txt ending
      else
      {
        var oldSrcFile = srcFile;
        srcFile = srcFile.split(".")[0] + ".txt";

        fs.rename(oldSrcFile, srcFile, callback);
      }
    },

    //convert file to text
    function(callback)
    {
      var randNum = Math.floor(Math.random()*0xFFFFFFFF);
      destFile = tempDirectory + "eplite_import_" + randNum + ".txt";
      abiword.convertFile(srcFile, destFile, "txt", function(err){
        //catch convert errors
        if(err){
          console.warn("Converting Error:", err);
          return callback("convertFailed");
        } else {
          callback();
        }
      });
    },

    //get the pad object
    function(callback)
    {
      padManager.getPad(padId, function(err, _pad)
      {
        if(ERR(err, callback)) return;
        pad = _pad;
        callback();
      });
    },

    //read the text
    function(callback)
    {
      fs.readFile(destFile, "utf8", function(err, _text)
      {
        if(ERR(err, callback)) return;
        text = _text;

        //node on windows has a delay on releasing of the file lock.
        //We add a 100ms delay to work around this
	      if(os.type().indexOf("Windows") > -1)
	      {
          setTimeout(function()
          {
            callback();
          }, 100);
	      }
	      else
	      {
	        callback();
	      }
      });
    },

    //change text of the pad and broadcast the changeset
    function(callback)
    {
      pad.setText(text);
      padMessageHandler.updatePadClients(pad, callback);
    },

    //clean up temporary files
    function(callback)
    {
      async.parallel([
        function(callback)
        {
          fs.unlink(srcFile, callback);
        },
        function(callback)
        {
          fs.unlink(destFile, callback);
        }
      ], callback);
    }
  ], function(err)
  {
    var status = "ok";

    //check for known errors and replace the status
    if(err == "uploadFailed" || err == "convertFailed")
    {
      status = err;
      err = null;
    }

    ERR(err);

    //close the connection
    res.send("<script> if ( (!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0)) ){document.domain = document.domain;}var impexp = window.top.require('/pad_impexp').padimpexp.handleFrameCall('" + status + "');</script>", 200);
  });
}
<|endoftext|>