<commit_before>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.View}
 * @param {WebInspector.LayerTreeModel} model
 */
WebInspector.Layers3DView = function(model)
{
    WebInspector.View.call(this);
    this.element.classList.add("fill");
    this.element.classList.add("layers-3d-view");
    this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Not in the composited mode.\nConsider forcing composited mode in Settings."));
    this._model = model;
    this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._update, this);
    this._rotatingContainerElement = this.element.createChild("div", "fill rotating-container");
    this.element.addEventListener("mousemove", this._onMouseMove.bind(this), false);
    this.element.addEventListener("mouseout", this._onMouseMove.bind(this), false);
    this.element.addEventListener("mousedown", this._onMouseDown.bind(this), false);
    this.element.addEventListener("mouseup", this._onMouseUp.bind(this), false);
    this.element.addEventListener("click", this._onClick.bind(this), false);
    this._elementsByLayerId = {};
    this._rotateX = 0;
    this._rotateY = 0;
    this._scaleAdjustmentStylesheet = this.element.ownerDocument.head.createChild("style");
    this._scaleAdjustmentStylesheet.disabled = true;
    this._lastOutlinedElement = {};
}

/**
 * @enum {string}
 */
WebInspector.Layers3DView.OutlineType = {
    Hovered: "hovered",
    Selected: "selected"
}

/**
 * @enum {string}
 */
WebInspector.Layers3DView.Events = {
    LayerHovered: "LayerHovered",
    LayerSelected: "LayerSelected"
}

WebInspector.Layers3DView.prototype = {
    onResize: function()
    {
        this._scale();
    },

    willHide: function()
    {
        this._scaleAdjustmentStylesheet.disabled = true;
    },

    wasShown: function()
    {
        this._scaleAdjustmentStylesheet.disabled = false;
        if (this._needsUpdate)
            this._update();
    },

    /**
     * @param {WebInspector.Layers3DView.OutlineType} type
     * @param {WebInspector.Layer?} layer
     */
    _setOutline: function(type, layer)
    {
        var element = layer ? this._elementForLayer(layer) : null;
        var previousElement = this._lastOutlinedElement[type];
        if (previousElement === element)
            return;
        this._lastOutlinedElement[type] = element;
        if (previousElement) {
            previousElement.removeStyleClass(type);
            this._updateElementColor(previousElement);
        }
        if (element) {
            element.addStyleClass(type);
            this._updateElementColor(element);
        }
    },

    /**
     * @param {WebInspector.Layer} layer
     */
    hoverLayer: function(layer)
    {
        this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, layer);
    },

    /**
     * @param {WebInspector.Layer} layer
     */
    selectLayer: function(layer)
    {
        this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
        this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, layer);
    },

    _scale: function()
    {
        const padding = 40;
        var scale = 1;
        var root = this._model.root();
        if (!root)
            return;
        var scaleX = this.element.clientWidth / (root.width() + 2 * padding);
        var scaleY = this.element.clientHeight / (root.height() + 2 * padding);
        scale = Math.min(scaleX, scaleY);
        this._lastScale = scale;
        var element = this._elementForLayer(root);
        element.style.webkitTransform = "scale3d(" + scale + "," + scale + "," + scale + ")";
        element.style.left = ((this.element.clientWidth - root.width() * scale) >> 1) + "px";
        element.style.top = ((this.element.clientHeight - root.height() * scale) >> 1) + "px";
        const screenLayerThickness = 4;
        const screenLayerSpacing = 20;
        var layerThickness = Math.ceil(screenLayerThickness / scale) + "px";
        var layerSpacing = Math.ceil(screenLayerSpacing / scale) + "px";
        this._scaleAdjustmentStylesheet.textContent = ".layer-container .side-wall { height: " + layerThickness + "; width: " + layerThickness + "; } " +
            ".layer-container .back-wall { -webkit-transform: translateZ(-" + layerThickness + "); } " +
            ".layer-container { -webkit-transform: translateZ(" + layerSpacing + "); }";
    },

    _update: function()
    {
        if (!this.isShowing()) {
            this._needsUpdate = true;
            return;
        }
        if (!this._model.root()) {
            this._emptyView.show(this.element);
            return;
        }
        this._emptyView.detach();
        function updateLayer(layer)
        {
            var element = this._elementForLayer(layer);
            this._updateLayerElement(element);
            for (var childElement = element.firstElementChild; childElement;) {
                var nextElement = childElement.nextSibling;
                if (childElement.__layer && !this._model.layerById(childElement.__layer.id()))
                    childElement.remove();
                childElement = nextElement;
            }
        }
        this._model.forEachLayer(updateLayer.bind(this));
        this._needsUpdate = false;
        this._scale();
    },

    /**
     * @param {WebInspector.Layer} layer
     * @return {Element}
     */
    _elementForLayer: function(layer)
    {
        var element = this._elementsByLayerId[layer.id()];
        if (element)
            return element;
        element = document.createElement("div");
        element.className = "layer-container";
        element.__layer = layer;
        ["fill back-wall", "side-wall top", "side-wall right", "side-wall bottom", "side-wall left"].forEach(element.createChild.bind(element, "div"));
        this._elementsByLayerId[layer.id()] = element;
        return element;
    },

    /**
     * @param {Element} element
     */
    _updateLayerElement: function(element)
    {
        var layer = element.__layer;
        var style = element.style;
        var parentElement = layer.parent() ? this._elementForLayer(layer.parent()) : this._rotatingContainerElement;
        element.__depth = (parentElement.__depth || 0) + 1;
        style.left  = layer.offsetX() + "px";
        style.top  = layer.offsetY() + "px";
        style.width  = layer.width() + "px";
        style.height  = layer.height() + "px";
        var transform = layer.transform();
        if (transform) {
            function toFixed5(x)
            {
                return x.toFixed(5);
            }
            // Avoid exponential notation in CSS.
            style.webkitTransform = "matrix3d(" + transform.map(toFixed5).join(",") + ")";
            var anchor = layer.anchorPoint();
            style.webkitTransformOrigin = Math.round(anchor[0] * 100) + "% " + Math.round(anchor[1] * 100) + "% " + anchor[2];
        } else {
            style.webkitTransform = "";
            style.webkitTransformOrigin = "";
        }
        this._updateElementColor(element);
        if (parentElement !== element.parentElement)
            parentElement.appendChild(element);
    },

    /**
     * @param {Element} element
     */
    _updateElementColor: function(element)
    {
        var color;
        if (element === this._lastOutlinedElement[WebInspector.Layers3DView.OutlineType.Selected])
            color = WebInspector.Color.PageHighlight.Content.toString(WebInspector.Color.Format.RGBA) || "";
        else {
            const base = 144;
            var component = base + 20 * ((element.__depth - 1) % 5);
            color = "rgba(" + component + "," + component + "," + component + ", 0.8)";
        }
        element.style.backgroundColor = color;
    },

    /**
     * @param {Event} event
     */
    _onMouseDown: function(event)
    {
        if (event.which !== 1)
            return;
        this._setReferencePoint(event);
    },

    /**
     * @param {Event} event
     */
    _setReferencePoint: function(event)
    {
        this._originX = event.clientX;
        this._originY = event.clientY;
        this._oldRotateX = this._rotateX;
        this._oldRotateY = this._rotateY;
    },

    _resetReferencePoint: function()
    {
        delete this._originX;
        delete this._originY;
        delete this._oldRotateX;
        delete this._oldRotateY;
    },

    /**
     * @param {Event} event
     */
    _onMouseUp: function(event)
    {
        if (event.which !== 1)
            return;
        this._resetReferencePoint();
    },

    /**
     * @param {Event} event
     * @return {WebInspector.Layer?}
     */
    _layerFromEventPoint: function(event)
    {
        var element = this.element.ownerDocument.elementFromPoint(event.pageX, event.pageY);
        if (!element)
            return null;
        element = element.enclosingNodeOrSelfWithClass("layer-container");
        return element && element.__layer;
    },

    /**
     * @param {Event} event
     */
    _onMouseMove: function(event)
    {
        if (!event.which) {
            this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerHovered, this._layerFromEventPoint(event));
            return;
        }
        if (event.which === 1) {
            // See reference point it we missed mouesedown
            if (typeof this._originX !== "number")
                this._setReferencePoint(event);
            this._rotateX = this._oldRotateX + (this._originY - event.clientY) / 2;
            this._rotateY = this._oldRotateY - (this._originX - event.clientX) / 4;
            // Translate well to front so that no matter how we turn the plane, no parts of it goes below  parent.
            // This makes sure mouse events go to proper layers, not straight to the parent.
            this._rotatingContainerElement.style.webkitTransform = "translateZ(10000px) rotateX(" + this._rotateX + "deg) rotateY(" + this._rotateY + "deg)";
        }
    },

    _onClick: function(event)
    {
        this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSelected, this._layerFromEventPoint(event));
    },

    __proto__: WebInspector.View.prototype
}
<commit_msg>DevTools: fixed typos in Layers3DView comment.<commit_after>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.View}
 * @param {WebInspector.LayerTreeModel} model
 */
WebInspector.Layers3DView = function(model)
{
    WebInspector.View.call(this);
    this.element.classList.add("fill");
    this.element.classList.add("layers-3d-view");
    this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Not in the composited mode.\nConsider forcing composited mode in Settings."));
    this._model = model;
    this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._update, this);
    this._rotatingContainerElement = this.element.createChild("div", "fill rotating-container");
    this.element.addEventListener("mousemove", this._onMouseMove.bind(this), false);
    this.element.addEventListener("mouseout", this._onMouseMove.bind(this), false);
    this.element.addEventListener("mousedown", this._onMouseDown.bind(this), false);
    this.element.addEventListener("mouseup", this._onMouseUp.bind(this), false);
    this.element.addEventListener("click", this._onClick.bind(this), false);
    this._elementsByLayerId = {};
    this._rotateX = 0;
    this._rotateY = 0;
    this._scaleAdjustmentStylesheet = this.element.ownerDocument.head.createChild("style");
    this._scaleAdjustmentStylesheet.disabled = true;
    this._lastOutlinedElement = {};
}

/**
 * @enum {string}
 */
WebInspector.Layers3DView.OutlineType = {
    Hovered: "hovered",
    Selected: "selected"
}

/**
 * @enum {string}
 */
WebInspector.Layers3DView.Events = {
    LayerHovered: "LayerHovered",
    LayerSelected: "LayerSelected"
}

WebInspector.Layers3DView.prototype = {
    onResize: function()
    {
        this._scale();
    },

    willHide: function()
    {
        this._scaleAdjustmentStylesheet.disabled = true;
    },

    wasShown: function()
    {
        this._scaleAdjustmentStylesheet.disabled = false;
        if (this._needsUpdate)
            this._update();
    },

    /**
     * @param {WebInspector.Layers3DView.OutlineType} type
     * @param {WebInspector.Layer?} layer
     */
    _setOutline: function(type, layer)
    {
        var element = layer ? this._elementForLayer(layer) : null;
        var previousElement = this._lastOutlinedElement[type];
        if (previousElement === element)
            return;
        this._lastOutlinedElement[type] = element;
        if (previousElement) {
            previousElement.removeStyleClass(type);
            this._updateElementColor(previousElement);
        }
        if (element) {
            element.addStyleClass(type);
            this._updateElementColor(element);
        }
    },

    /**
     * @param {WebInspector.Layer} layer
     */
    hoverLayer: function(layer)
    {
        this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, layer);
    },

    /**
     * @param {WebInspector.Layer} layer
     */
    selectLayer: function(layer)
    {
        this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
        this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, layer);
    },

    _scale: function()
    {
        const padding = 40;
        var scale = 1;
        var root = this._model.root();
        if (!root)
            return;
        var scaleX = this.element.clientWidth / (root.width() + 2 * padding);
        var scaleY = this.element.clientHeight / (root.height() + 2 * padding);
        scale = Math.min(scaleX, scaleY);
        this._lastScale = scale;
        var element = this._elementForLayer(root);
        element.style.webkitTransform = "scale3d(" + scale + "," + scale + "," + scale + ")";
        element.style.left = ((this.element.clientWidth - root.width() * scale) >> 1) + "px";
        element.style.top = ((this.element.clientHeight - root.height() * scale) >> 1) + "px";
        const screenLayerThickness = 4;
        const screenLayerSpacing = 20;
        var layerThickness = Math.ceil(screenLayerThickness / scale) + "px";
        var layerSpacing = Math.ceil(screenLayerSpacing / scale) + "px";
        this._scaleAdjustmentStylesheet.textContent = ".layer-container .side-wall { height: " + layerThickness + "; width: " + layerThickness + "; } " +
            ".layer-container .back-wall { -webkit-transform: translateZ(-" + layerThickness + "); } " +
            ".layer-container { -webkit-transform: translateZ(" + layerSpacing + "); }";
    },

    _update: function()
    {
        if (!this.isShowing()) {
            this._needsUpdate = true;
            return;
        }
        if (!this._model.root()) {
            this._emptyView.show(this.element);
            return;
        }
        this._emptyView.detach();
        function updateLayer(layer)
        {
            var element = this._elementForLayer(layer);
            this._updateLayerElement(element);
            for (var childElement = element.firstElementChild; childElement;) {
                var nextElement = childElement.nextSibling;
                if (childElement.__layer && !this._model.layerById(childElement.__layer.id()))
                    childElement.remove();
                childElement = nextElement;
            }
        }
        this._model.forEachLayer(updateLayer.bind(this));
        this._needsUpdate = false;
        this._scale();
    },

    /**
     * @param {WebInspector.Layer} layer
     * @return {Element}
     */
    _elementForLayer: function(layer)
    {
        var element = this._elementsByLayerId[layer.id()];
        if (element)
            return element;
        element = document.createElement("div");
        element.className = "layer-container";
        element.__layer = layer;
        ["fill back-wall", "side-wall top", "side-wall right", "side-wall bottom", "side-wall left"].forEach(element.createChild.bind(element, "div"));
        this._elementsByLayerId[layer.id()] = element;
        return element;
    },

    /**
     * @param {Element} element
     */
    _updateLayerElement: function(element)
    {
        var layer = element.__layer;
        var style = element.style;
        var parentElement = layer.parent() ? this._elementForLayer(layer.parent()) : this._rotatingContainerElement;
        element.__depth = (parentElement.__depth || 0) + 1;
        style.left  = layer.offsetX() + "px";
        style.top  = layer.offsetY() + "px";
        style.width  = layer.width() + "px";
        style.height  = layer.height() + "px";
        var transform = layer.transform();
        if (transform) {
            function toFixed5(x)
            {
                return x.toFixed(5);
            }
            // Avoid exponential notation in CSS.
            style.webkitTransform = "matrix3d(" + transform.map(toFixed5).join(",") + ")";
            var anchor = layer.anchorPoint();
            style.webkitTransformOrigin = Math.round(anchor[0] * 100) + "% " + Math.round(anchor[1] * 100) + "% " + anchor[2];
        } else {
            style.webkitTransform = "";
            style.webkitTransformOrigin = "";
        }
        this._updateElementColor(element);
        if (parentElement !== element.parentElement)
            parentElement.appendChild(element);
    },

    /**
     * @param {Element} element
     */
    _updateElementColor: function(element)
    {
        var color;
        if (element === this._lastOutlinedElement[WebInspector.Layers3DView.OutlineType.Selected])
            color = WebInspector.Color.PageHighlight.Content.toString(WebInspector.Color.Format.RGBA) || "";
        else {
            const base = 144;
            var component = base + 20 * ((element.__depth - 1) % 5);
            color = "rgba(" + component + "," + component + "," + component + ", 0.8)";
        }
        element.style.backgroundColor = color;
    },

    /**
     * @param {Event} event
     */
    _onMouseDown: function(event)
    {
        if (event.which !== 1)
            return;
        this._setReferencePoint(event);
    },

    /**
     * @param {Event} event
     */
    _setReferencePoint: function(event)
    {
        this._originX = event.clientX;
        this._originY = event.clientY;
        this._oldRotateX = this._rotateX;
        this._oldRotateY = this._rotateY;
    },

    _resetReferencePoint: function()
    {
        delete this._originX;
        delete this._originY;
        delete this._oldRotateX;
        delete this._oldRotateY;
    },

    /**
     * @param {Event} event
     */
    _onMouseUp: function(event)
    {
        if (event.which !== 1)
            return;
        this._resetReferencePoint();
    },

    /**
     * @param {Event} event
     * @return {WebInspector.Layer?}
     */
    _layerFromEventPoint: function(event)
    {
        var element = this.element.ownerDocument.elementFromPoint(event.pageX, event.pageY);
        if (!element)
            return null;
        element = element.enclosingNodeOrSelfWithClass("layer-container");
        return element && element.__layer;
    },

    /**
     * @param {Event} event
     */
    _onMouseMove: function(event)
    {
        if (!event.which) {
            this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerHovered, this._layerFromEventPoint(event));
            return;
        }
        if (event.which === 1) {
            // Set reference point if we missed mousedown.
            if (typeof this._originX !== "number")
                this._setReferencePoint(event);
            this._rotateX = this._oldRotateX + (this._originY - event.clientY) / 2;
            this._rotateY = this._oldRotateY - (this._originX - event.clientX) / 4;
            // Translate well to front so that no matter how we turn the plane, no parts of it goes below  parent.
            // This makes sure mouse events go to proper layers, not straight to the parent.
            this._rotatingContainerElement.style.webkitTransform = "translateZ(10000px) rotateX(" + this._rotateX + "deg) rotateY(" + this._rotateY + "deg)";
        }
    },

    _onClick: function(event)
    {
        this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSelected, this._layerFromEventPoint(event));
    },

    __proto__: WebInspector.View.prototype
}
<|endoftext|>


<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
  var htmlMode = CodeMirror.getMode(config, {name: "xml",
                                             htmlMode: true,
                                             multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
                                             multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
  var cssMode = CodeMirror.getMode(config, "css");

  var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
  scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
                    mode: CodeMirror.getMode(config, "javascript")});
  if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
    var conf = scriptTypesConf[i];
    scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
  }
  scriptTypes.push({matches: /./,
                    mode: CodeMirror.getMode(config, "text/plain")});

  function html(stream, state) {
    var tagName = state.htmlState.tagName;
    var style = htmlMode.token(stream, state.htmlState);
    if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
      // Script block: mode to change to depends on type attribute
      var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
      scriptType = scriptType ? scriptType[1] : "";
      if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
      for (var i = 0; i < scriptTypes.length; ++i) {
        var tp = scriptTypes[i];
        if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
          if (tp.mode) {
            state.token = script;
            state.localMode = tp.mode;
            state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
          }
          break;
        }
      }
    } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
      state.token = css;
      state.localMode = cssMode;
      state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
    }
    return style;
  }
  function maybeBackup(stream, pat, style) {
    var cur = stream.current();
    var close = cur.search(pat), m;
    if (close > -1) stream.backUp(cur.length - close);
    else if (m = cur.match(/<\/?$/)) {
      stream.backUp(cur.length);
      if (!stream.match(pat, false)) stream.match(cur);
    }
    return style;
  }
  function script(stream, state) {
    if (stream.match(/^<\/\s*script\s*>/i, false)) {
      state.token = html;
      state.localState = state.localMode = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*script\s*>/,
                       state.localMode.token(stream, state.localState));
  }
  function css(stream, state) {
    if (stream.match(/^<\/\s*style\s*>/i, false)) {
      state.token = html;
      state.localState = state.localMode = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*style\s*>/,
                       cssMode.token(stream, state.localState));
  }

  return {
    startState: function() {
      var state = htmlMode.startState();
      return {token: html, localMode: null, localState: null, htmlState: state};
    },

    copyState: function(state) {
      if (state.localState)
        var local = CodeMirror.copyState(state.localMode, state.localState);
      return {token: state.token, localMode: state.localMode, localState: local,
              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
    },

    token: function(stream, state) {
      return state.token(stream, state);
    },

    indent: function(state, textAfter) {
      if (!state.localMode || /^\s*<\//.test(textAfter))
        return htmlMode.indent(state.htmlState, textAfter);
      else if (state.localMode.indent)
        return state.localMode.indent(state.localState, textAfter);
      else
        return CodeMirror.Pass;
    },

    innerMode: function(state) {
      return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
    }
  };
}, "xml", "javascript", "css");

CodeMirror.defineMIME("text/html", "htmlmixed");

});
<commit_msg>DevTools: [CodeMirror] roll codeMirror htmlmixed mode to @8292921e<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
  var htmlMode = CodeMirror.getMode(config, {name: "xml",
                                             htmlMode: true,
                                             multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
                                             multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
  var cssMode = CodeMirror.getMode(config, "css");

  var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
  scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
                    mode: CodeMirror.getMode(config, "javascript")});
  if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
    var conf = scriptTypesConf[i];
    scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
  }
  scriptTypes.push({matches: /./,
                    mode: CodeMirror.getMode(config, "text/plain")});

  function html(stream, state) {
    var tagName = state.htmlState.tagName;
    if (tagName) tagName = tagName.toLowerCase();
    var style = htmlMode.token(stream, state.htmlState);
    if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
      // Script block: mode to change to depends on type attribute
      var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
      scriptType = scriptType ? scriptType[1] : "";
      if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
      for (var i = 0; i < scriptTypes.length; ++i) {
        var tp = scriptTypes[i];
        if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
          if (tp.mode) {
            state.token = script;
            state.localMode = tp.mode;
            state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
          }
          break;
        }
      }
    } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
      state.token = css;
      state.localMode = cssMode;
      state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
    }
    return style;
  }
  function maybeBackup(stream, pat, style) {
    var cur = stream.current();
    var close = cur.search(pat), m;
    if (close > -1) stream.backUp(cur.length - close);
    else if (m = cur.match(/<\/?$/)) {
      stream.backUp(cur.length);
      if (!stream.match(pat, false)) stream.match(cur);
    }
    return style;
  }
  function script(stream, state) {
    if (stream.match(/^<\/\s*script\s*>/i, false)) {
      state.token = html;
      state.localState = state.localMode = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*script\s*>/,
                       state.localMode.token(stream, state.localState));
  }
  function css(stream, state) {
    if (stream.match(/^<\/\s*style\s*>/i, false)) {
      state.token = html;
      state.localState = state.localMode = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*style\s*>/,
                       cssMode.token(stream, state.localState));
  }

  return {
    startState: function() {
      var state = htmlMode.startState();
      return {token: html, localMode: null, localState: null, htmlState: state};
    },

    copyState: function(state) {
      if (state.localState)
        var local = CodeMirror.copyState(state.localMode, state.localState);
      return {token: state.token, localMode: state.localMode, localState: local,
              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
    },

    token: function(stream, state) {
      return state.token(stream, state);
    },

    indent: function(state, textAfter) {
      if (!state.localMode || /^\s*<\//.test(textAfter))
        return htmlMode.indent(state.htmlState, textAfter);
      else if (state.localMode.indent)
        return state.localMode.indent(state.localState, textAfter);
      else
        return CodeMirror.Pass;
    },

    innerMode: function(state) {
      return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
    }
  };
}, "xml", "javascript", "css");

CodeMirror.defineMIME("text/html", "htmlmixed");

});
<|endoftext|>


<commit_before>LuxuryShopApp.config(['$routeProvider', '$locationProvider', function ($routeProvide, $locationProvider) {
  $routeProvide
    .when('/', {
      templateUrl: 'template/_main.html',
      controller: 'MainPageCtrl'
    })
    .when('/women', {
      templateUrl: 'template/_category-women.html',
      controller: 'MainPageCtrl'
    })
    .when('/women/:womenClothId', {
      templateUrl: 'template/_product-detailed.html',
      controller: 'CategoryCtrl'
    })
    .when('/men', {
      templateUrl: 'template/_category-men.html',
      controller: 'MainPageCtrl'
    })
    .when('/men/:menClothId', {
      templateUrl: 'template/_product-details.html',
      controller: 'ProductDetCtrl'
    })
    .when('/jewellery', {
      templateUrl: 'template/_category-jevelery.html',
      controller: 'MainPageCtrl'
    })
    .when('/jevelery/:jeveleryId', {
      templateUrl: 'template/_product-detailed.html',
      controller: 'ProductDetCtrl'
    })
    .when('/watches', {
      templateUrl: 'template/_category-watches.html',
      controller: 'MainPageCtrl'
    })
    .when('/watches/:watchId', {
      templateUrl: 'template/_product-details.html',
      controller: 'ProductDetCtrl'
    })
    .when('/blog', {
      templateUrl: 'template/_blog.html',
      controller: 'MainPageCtrl'
    })
    .when('/cart', {
      templateUrl: 'template/_blog.html',
      controller: 'MainPageCtrl'
    })
    .when('/contact', {
      templateUrl: 'template/_contact.html',
      controller: 'MainPageCtrl'
    })
    .otherwise({
      redirectTo: '/'
    });
}]);
<commit_msg>Some changes in routes for men, watches, jewellery<commit_after>LuxuryShopApp.config(['$routeProvider', '$locationProvider', function ($routeProvide, $locationProvider) {
  $routeProvide
    .when('/', {
      templateUrl: 'template/_main.html',
      controller: 'MainPageCtrl'
    })
    .when('/women', {
      templateUrl: 'template/_category-women.html',
      controller: 'MainPageCtrl'
    })
    .when('/women/:womenClothId', {
      templateUrl: 'template/_women-product-detailed.html',
      controller: 'CategoryCtrl'
    })
    .when('/men', {
      templateUrl: 'template/_category-men.html',
      controller: 'MainPageCtrl'
    })
    .when('/men/:menClothId', {
      templateUrl: 'template/_men-product-detailed.html',
      controller: 'CategoryCtrl'
    })
    .when('/jewellery', {
      templateUrl: 'template/_category-jewellery.html',
      controller: 'MainPageCtrl'
    })
    .when('/jewellery/:jewelleryId', {
      templateUrl: 'template/_jewellery-product-detailed.html',
      controller: 'CategoryCtrl'
    })
    .when('/watches', {
      templateUrl: 'template/_category-watches.html',
      controller: 'MainPageCtrl'
    })
    .when('/watches/:watchId', {
      templateUrl: 'template/_watches-product-detailed.html',
      controller: 'CategoryCtrl'
    })
    .when('/blog', {
      templateUrl: 'template/_blog.html',
      controller: 'MainPageCtrl'
    })
    .when('/cart', {
      templateUrl: 'template/_blog.html',
      controller: 'MainPageCtrl'
    })
    .when('/contact', {
      templateUrl: 'template/_contact.html',
      controller: 'MainPageCtrl'
    })
    .otherwise({
      redirectTo: '/'
    });
}]);
<|endoftext|>


<commit_before>this.mmooc = this.mmooc || {};

this.mmooc.discussionTopics = function () {
    return {
        setDiscussionTopicPubDate: function(discussionTopic) {
            var formattedDate = mmooc.util.formattedDate(discussionTopic.posted_at);
            var pubDate = $("
" + formattedDate + "
");
            $(pubDate).prependTo('#discussion_topic .discussion-header-right');
        },

        alterDiscussionReadStateLook: function() {
            var self = this;
            $('body').on('click', '.read-unread-button', function (){
               $(this).toggleClass('read');
               $(this).closest(".entry-content").siblings(".discussion-read-state-btn").click();
               self.toggleReadUnreadButton($(this));
           });

            var checkExist = setInterval(function() {
                if ($('.discussion-read-state-btn').length) {
                  clearInterval(checkExist);
                  var readUnreadButton = $("
Marker som lest
");
                  readUnreadButton.appendTo('.discussion_entry .entry-header');
                  self.toggleReadUnreadButton($(this).closest(".discussion_entry").find("read-unread-button"));
                }
            }, 100);
        },

        toggleReadUnreadButton: function(button) {
            $(".discussion-read-state-btn").each(function(index) {
                    var button = $(this).siblings(".entry-content").find(".read-unread-button");
                    if($(this).attr('title') == "Mark as Read") {
                        button.text('Marker som lest');
                        button.addClass('read');
                    }
                    else {
                        button.text('Marker som ulest');
                        button.removeClass('read');
                    }
                });
        }
    };
}();

<commit_msg>fiks for diskusjonsmerking<commit_after>this.mmooc = this.mmooc || {};

this.mmooc.discussionTopics = function () {
    return {
        setDiscussionTopicPubDate: function(discussionTopic) {
            var formattedDate = mmooc.util.formattedDate(discussionTopic.posted_at);
            var pubDate = $("
" + formattedDate + "
");
            $(pubDate).prependTo('#discussion_topic .discussion-header-right');
        },

        alterDiscussionReadStateLook: function() {
            var self = this;
            $('body').on('click', '.read-unread-button', function (){
               $(this).toggleClass('read');
               $(this).closest(".entry-content").siblings(".discussion-read-state-btn").click();
               self.toggleReadUnreadButton($(this));
           });

            var checkExist = setInterval(function() {
                if ($('.discussion-read-state-btn').length) {
                  clearInterval(checkExist);
                  var readUnreadButton = $("
Marker som lest
");
                  readUnreadButton.appendTo('.discussion_entry .entry-header');
                  self.toggleReadUnreadButton($(this).closest(".discussion_entry").find("read-unread-button"));
                }
            }, 100);
        },

        toggleReadUnreadButton: function(button) {
            $(".discussion-read-state-btn").each(function(index) {
                    var button = $(this).siblings(".entry-content").find(".read-unread-button");
                    if($(this).parent().hasClass("unread")) {
                        button.text('Marker som lest');
                        button.addClass('read');
                    }
                    else {
                        button.text('Marker som ulest');
                        button.removeClass('read');
                    }
                });
        }
    };
}();

<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var util         = require('util');

/**
 * @constructor TransactionManager
 * @param {Object} account
 */

function TransactionManager(account) {
  EventEmitter.call(this);

  var self             = this;

  this.account         = account;
  this.remote          = account._remote;
  this._timeout        = void(0);
  this._next_sequence  = void(0);
  this._config         = { max_fee: self.remote.max_fee };

  function sequence_loaded(err, sequence) {
    self._next_sequence = sequence;
    self.emit('sequence_loaded', sequence);
  }

  account.get_next_sequence(sequence_loaded);
}

util.inherits(TransactionManager, EventEmitter);

/**
 * @param {Object} tx
 */

//TransactionManager.prototype.update = function(tx) {
//  this._next_sequence_number = Math.max(tx.meta.account_next_seq, this._next_sequence_number);
//  var queued;
//
//  if (queued = this.queue.get('hash', tx.hash)) {
//    this.queue.remove('hash', queued.hash);
//  } else if (queued = this.queue.get('sequence', tx.seq)) {
//    if (queued.nullified) {
//      //Figures out new sequence number, signs, and sends to network
//      this.submit(queued);
//    }
//  }
//}

/**
 * User has given up, replace transaction with a null transaction
 *
 * @param {Object} tx
 */

//TransactionManager.prototype._nullify = function(tx) {
//  this.queue.remove('hash', tx.hash);
//}

/**
 */

//TransactionManager.prototype._timeout = function() {
//  var transactions = this.queue.get();
//  for (var i=0; i<transactions.length; i++) {
//    this.remote.submit(transactions[i].blob);
//  }
//  //restart the timer
//  this._timeout = setTimeout(function(){}, 10000);
//}

/**
 * @param {Number} oldFee
 * @param {Number} newFee
 */

//TransactionManager.prototype._fee_change = function(oldFee, newFee) {
//  if (newFee > this._config.maxFee) {
//    if (this._timeout) clearTimeout(this._timeout);
//    return;
//  }
//
//  // resubmit everything raising fee if needed
//  for (var i=0; i<transactions.length; i++) {
//    var tx = transactions[i];
//
//    if (tx.fee < newFee) {
//      tx.fee  = newFee;
//      //tx.blob = signTransaction(tx, tx.seq, newFee);
//      //this.queue.add(tx);
//    }
//
//    this.remote.submit(tx.blob);
//  }
//}

TransactionManager.prototype._request = function(tx) {
  var self   = this;
  var remote = this.remote;

  if (!tx._secret && !tx.tx_json.TxnSignature) {
    tx.emit('error', {
      result:          'tejSecretUnknown',
      result_message:  'Could not sign transactions because we.'
    });
    return;
  }

  if (!remote.trusted && !remote.local_signing) {
    tx.emit('error', {
      result:          'tejServerUntrusted',
      result_message:  'Attempt to give a secret to an untrusted server.'
    });
    return;
  }

  tx.submit_index = remote._ledger_current_index;

  function finalize(message) {
    tx.finalized = true;
    tx.emit('final', message);
  }

  tx.once('error', finalize);
  tx.once('success', finalize);

  // Listen for 'ledger closed' events to verify
  // that the transaction is discovered in the
  // ledger before considering the transaction
  // successful
  this._detect_ledger_entry(tx);

  var submit_request = remote.request_submit();

  if (remote.local_signing) {
    tx.sign();
    submit_request.tx_blob(tx.serialize().to_hex());
  } else {
    submit_request.secret(tx._secret);
    submit_request.build_path(tx._build_path);
    submit_request.tx_json(tx.tx_json);
  }

  function submission_success(message) {
    if (!message.engine_result) {
      return submission_error(message);
    } else {
      tx.hash = message.tx_json.hash;
      tx.set_state('client_proposed');
      tx.emit('proposed', {
        tx_json:                message.tx_json,

        result:                 message.engine_result,
        engine_result:          message.engine_result,

        result_code:            message.engine_result_code,
        engine_result_code:     message.engine_result_code,

        result_message:         message.engine_result_message,
        engine_result_message:  message.engine_result_message,

        rejected:               tx.isRejected(message.engine_result_code),
        // If server is honest, don't expect a final if rejected.
      });
    }
  }

  function submission_error(err) {
    tx.set_state('remoteError');
    tx.emit('error', err);
  }

  submit_request.once('success', submission_success);
  submit_request.once('error', submission_error);

  //submit_request.timeout(1000 * 10, function() {
    //tx.emit('error', new Error('Timeout'));
  //});

  submit_request.request();

  tx.set_state('client_submitted');
  tx.emit('submitted');

  return submit_request;
}

TransactionManager.prototype._is_not_found = function(error) {
  return !!error && typeof error === 'object'
      && typeof error.remote === 'object'
      && error.error === 'remoteError'
      && (error.remote.error === 'transactionNotFound'
       || error.remote.error === 'ledgerNotFound')
      ;
}

TransactionManager.prototype._detect_ledger_entry = function(tx) {
  var self            = this;
  var remote          = this.remote;
  var checked_ledgers = { };

  function ledger_closed(message) {
    if (tx.finalized) {
      // Transaction has already erred or
      // been detected in the ledger
      return;
    }

    var ledger_hash  = message.ledger_hash;
    var ledger_index = message.ledger_index;

    if (checked_ledgers.hasOwnProperty(ledger_hash)) {
      // Ledger with this hash has already been
      // checked to contain transaction
      return;
    }

    checked_ledgers[ledger_hash] = true;

    var request_transaction = remote.request_transaction_entry(tx.hash);

    request_transaction.ledger_hash(ledger_hash);

    request_transaction.callback(function(err, message) {
      if (tx.finalized) return;

      if (self._is_not_found(err)) {
        var dif = ledger_index - tx.submit_index;
        if (dif >= 8) {
          // Lost
          tx.emit('error', message);
          tx.emit('lost', message);
        } else if (dif >= 4) {
          // Missing
          tx.set_state('client_missing');
          tx.emit('pending', message);
        } else {
          // Pending
          tx.emit('pending', message);
        }
      } else {
        // Transaction was found in the ledger,
        // consider this transaction successful
        if (message.metadata) {
          tx.set_state(message.metadata.TransactionResult);
        }
        tx.emit('success', message);
      }
    });
  }

  function transaction_proposed() {
    // Check the ledger for transaction entry
    remote.addListener('ledger_closed', ledger_closed);
  }

  function transaction_finalized() {
    // Stop checking the ledger
    remote.removeListener('ledger_closed', ledger_closed);
  }

  tx.once('proposed', transaction_proposed);
  tx.once('final', transaction_finalized);
}

/**
 * @param {Object} tx
 */

TransactionManager.prototype.submit = function(tx) {
  // If sequence number is not yet known, defer until it is.
  if (!this._next_sequence) {
    this.once('sequence_loaded', this.submit.bind(this, tx));
    return;
  }

  var seq = this._next_sequence++;
  var fee = tx.fee_units();

  if (fee <= this._config.max_fee) {
    tx.tx_json.Sequence = seq;
    tx.tx_json.Fee      = fee;
    tx.complete();

    this._request(tx);
  }
}

exports.TransactionManager = TransactionManager;
<commit_msg>Replace comment<commit_after>var EventEmitter = require('events').EventEmitter;
var util         = require('util');

/**
 * @constructor TransactionManager
 * @param {Object} account
 */

function TransactionManager(account) {
  EventEmitter.call(this);

  var self             = this;

  this.account         = account;
  this.remote          = account._remote;
  this._timeout        = void(0);
  this._next_sequence  = void(0);
  this._config         = { max_fee: self.remote.max_fee };

  function sequence_loaded(err, sequence) {
    self._next_sequence = sequence;
    self.emit('sequence_loaded', sequence);
  }

  account.get_next_sequence(sequence_loaded);
}

util.inherits(TransactionManager, EventEmitter);

/**
 * @param {Object} tx
 */

//TransactionManager.prototype.update = function(tx) {
//  this._next_sequence_number = Math.max(tx.meta.account_next_seq, this._next_sequence_number);
//  var queued;
//
//  if (queued = this.queue.get('hash', tx.hash)) {
//    this.queue.remove('hash', queued.hash);
//  } else if (queued = this.queue.get('sequence', tx.seq)) {
//    if (queued.nullified) {
//      //Figures out new sequence number, signs, and sends to network
//      this.submit(queued);
//    }
//  }
//}

/**
 * User has given up, replace transaction with a null transaction
 *
 * @param {Object} tx
 */

//TransactionManager.prototype._nullify = function(tx) {
//  this.queue.remove('hash', tx.hash);
//}

/**
 */

//TransactionManager.prototype._timeout = function() {
//  var transactions = this.queue.get();
//  for (var i=0; i<transactions.length; i++) {
//    this.remote.submit(transactions[i].blob);
//  }
//  //restart the timer
//  this._timeout = setTimeout(function(){}, 10000);
//}

/**
 * @param {Number} oldFee
 * @param {Number} newFee
 */

//TransactionManager.prototype._fee_change = function(oldFee, newFee) {
//  if (newFee > this._config.maxFee) {
//    if (this._timeout) clearTimeout(this._timeout);
//    return;
//  }
//
//  // resubmit everything raising fee if needed
//  for (var i=0; i<transactions.length; i++) {
//    var tx = transactions[i];
//
//    if (tx.fee < newFee) {
//      tx.fee  = newFee;
//      //tx.blob = signTransaction(tx, tx.seq, newFee);
//      //this.queue.add(tx);
//    }
//
//    this.remote.submit(tx.blob);
//  }
//}

TransactionManager.prototype._request = function(tx) {
  var self   = this;
  var remote = this.remote;

  if (!tx._secret && !tx.tx_json.TxnSignature) {
    tx.emit('error', {
      result:          'tejSecretUnknown',
      result_message:  'Could not sign transactions because we.'
    });
    return;
  }

  if (!remote.trusted && !remote.local_signing) {
    tx.emit('error', {
      result:          'tejServerUntrusted',
      result_message:  'Attempt to give a secret to an untrusted server.'
    });
    return;
  }

  tx.submit_index = remote._ledger_current_index;

  function finalize(message) {
    tx.finalized = true;
    tx.emit('final', message);
  }

  tx.once('error', finalize);
  tx.once('success', finalize);

  // Listen for 'ledger closed' events to verify
  // that the transaction is discovered in the
  // ledger before considering the transaction
  // successful
  this._detect_ledger_entry(tx);

  var submit_request = remote.request_submit();

  if (remote.local_signing) {
    tx.sign();
    submit_request.tx_blob(tx.serialize().to_hex());
  } else {
    submit_request.secret(tx._secret);
    submit_request.build_path(tx._build_path);
    submit_request.tx_json(tx.tx_json);
  }

  function submission_success(message) {
    if (!message.engine_result) {
      return submission_error(message);
    } else {
      tx.hash = message.tx_json.hash;
      tx.set_state('client_proposed');
      tx.emit('proposed', {
        tx_json:                message.tx_json,

        result:                 message.engine_result,
        engine_result:          message.engine_result,

        result_code:            message.engine_result_code,
        engine_result_code:     message.engine_result_code,

        result_message:         message.engine_result_message,
        engine_result_message:  message.engine_result_message,

        // If server is honest, don't expect a final if rejected.
        rejected:               tx.isRejected(message.engine_result_code),
      });
    }
  }

  function submission_error(err) {
    tx.set_state('remoteError');
    tx.emit('error', err);
  }

  submit_request.once('success', submission_success);
  submit_request.once('error', submission_error);

  //submit_request.timeout(1000 * 10, function() {
    //tx.emit('error', new Error('Timeout'));
  //});

  submit_request.request();

  tx.set_state('client_submitted');
  tx.emit('submitted');

  return submit_request;
}

TransactionManager.prototype._is_not_found = function(error) {
  return !!error && typeof error === 'object'
      && typeof error.remote === 'object'
      && error.error === 'remoteError'
      && (error.remote.error === 'transactionNotFound'
       || error.remote.error === 'ledgerNotFound')
      ;
}

TransactionManager.prototype._detect_ledger_entry = function(tx) {
  var self            = this;
  var remote          = this.remote;
  var checked_ledgers = { };

  function ledger_closed(message) {
    if (tx.finalized) {
      // Transaction has already erred or
      // been detected in the ledger
      return;
    }

    var ledger_hash  = message.ledger_hash;
    var ledger_index = message.ledger_index;

    if (checked_ledgers.hasOwnProperty(ledger_hash)) {
      // Ledger with this hash has already been
      // checked to contain transaction
      return;
    }

    checked_ledgers[ledger_hash] = true;

    var request_transaction = remote.request_transaction_entry(tx.hash);

    request_transaction.ledger_hash(ledger_hash);

    request_transaction.callback(function(err, message) {
      if (tx.finalized) return;

      if (self._is_not_found(err)) {
        var dif = ledger_index - tx.submit_index;
        if (dif >= 8) {
          // Lost
          tx.emit('error', message);
          tx.emit('lost', message);
        } else if (dif >= 4) {
          // Missing
          tx.set_state('client_missing');
          tx.emit('pending', message);
        } else {
          // Pending
          tx.emit('pending', message);
        }
      } else {
        // Transaction was found in the ledger,
        // consider this transaction successful
        if (message.metadata) {
          tx.set_state(message.metadata.TransactionResult);
        }
        tx.emit('success', message);
      }
    });
  }

  function transaction_proposed() {
    // Check the ledger for transaction entry
    remote.addListener('ledger_closed', ledger_closed);
  }

  function transaction_finalized() {
    // Stop checking the ledger
    remote.removeListener('ledger_closed', ledger_closed);
  }

  tx.once('proposed', transaction_proposed);
  tx.once('final', transaction_finalized);
}

/**
 * @param {Object} tx
 */

TransactionManager.prototype.submit = function(tx) {
  // If sequence number is not yet known, defer until it is.
  if (!this._next_sequence) {
    this.once('sequence_loaded', this.submit.bind(this, tx));
    return;
  }

  var seq = this._next_sequence++;
  var fee = tx.fee_units();

  if (fee <= this._config.max_fee) {
    tx.tx_json.Sequence = seq;
    tx.tx_json.Fee      = fee;
    tx.complete();

    this._request(tx);
  }
}

exports.TransactionManager = TransactionManager;
<|endoftext|>


<commit_before>angular.module('blocktrail.wallet')
    .service( 'Currencies', function($rootScope, storageService, sdkService, CONFIG) {
        var self = this;

        self.cache = storageService.db('currency-rates-cache');
        self.sdk = sdkService.sdk();

        // currencies that the app supports and their symbols
        //  this list shouldn't be used directly `self.currencies` contains the enabled currencies
        var _currencies = {
            BTC: {code: "BTC", symbol: "฿"},
            GBP: {code: "GBP", symbol: "£"},
            EUR: {code: "EUR", symbol: "€"},
            USD: {code: "USD", symbol: "$"},
            CNY: {code: "CNY", symbol: "¥"},
            PAB: {code: "PAB", symbol: "B/"},
            ARS: {code: "ARS", symbol: "$"},
            BOB: {code: "BOB", symbol: "$b"},
            CLP: {code: "CLP", symbol: "$"},
            PEN: {code: "PEN", symbol: "S/"},
            PYG: {code: "PYG", symbol: "Gs"},
            UYU: {code: "UYU", symbol: "$U"},
            VEF: {code: "VEF", symbol: "Bs"},
            CRC: {code: "CRC", symbol: "₡"},
            MXN: {code: "MXN", symbol: "$"},
            NGN: {code: "NGN", symbol: "₦"},
            INR: {code: "INR", symbol: "₹"}
        };

        self.currencies = {};

        self.getCurrencies = function() {
            var self = this;
            return Object.keys(self.currencies).map(function(code) {
                return self.currencies[code];
            });
        };

        self.getFiatCurrencies = function() {
            var self = this;
            return self.getCurrencies().filter(function(currency) { return !!currency.isFiat; });
        };

        self.price = function(currency) {
            var self = this;
            if (typeof self.currencies[currency] === "undefined") {
                return 0;
            } else {
                return self.currencies[currency].price || 0;
            }
        };

        self.prices = function() {
            var prices = {};

            Object.keys(self.currencies).forEach(function(code) {
                prices[code] = self.currencies[code].price;
            });

            return prices;
        };

        /**
         * get the current btc prices (defaults to live, can force getting a cached version)
         * @param getCached
         * @returns {*}
         */
        self.updatePrices = function(getCached) {
            var self = this;

            var forceFetch = !getCached;

            return self.cache.get('price')
                .then(function(b) { return b; }, function() { forceFetch = true; return {_id: "price"}; })
                .then(function(pricesDoc) {
                    if (forceFetch) {
                        return self.sdk.then(function(sdk) {
                            return sdk.price().then(function(result) {
                                angular.extend(pricesDoc, result);

                                //store in cache and then return
                                return self.cache.put(pricesDoc).then(function() {
                                    return pricesDoc;
                                });
                            });
                        });
                    } else {
                        return pricesDoc;
                    }
                })
                // use a .then because a .done would break the promise chains that rely on self.wallet
                .then(function(pricesDoc) {
                    Object.keys(self.currencies).forEach(function(code) {
                        self.currencies[code].price = parseFloat(pricesDoc[code] || 0);
                    });

                    return pricesDoc;
                }, function(e) {
                    $log.error('prices ERR ' + e); throw e;
                });
        };

        self.enableCurrency = function(code) {
            var self = this;

            if (typeof _currencies[code] === "undefined") {
                return false;
            }

            self.currencies[code] = _currencies[code];
            self.currencies[code].isFiat = self.currencies[code].code !== "BTC";
            self.currencies[code].btcRate = 0;

            return true;
        };

        // enable all currencies that are in the config
        CONFIG.CURRENCIES.forEach(function(code) {
            self.enableCurrency(code);
        });
    })
    .service('CurrencyConverter', function($rootScope, Currencies) {
        var self = this;
        var coin = 100000000;
        var precision = 8;

        /**
         * convert from BTC value to a given currency
         * @param value
         * @param currency
         * @param fractionSize (optional)
         */
        self.fromBTC = function(value, currency, fractionSize) {
            if (typeof(fractionSize) == "undefined") {
                fractionSize = 2;
            }

            return Currencies.price(currency) ? (parseFloat(value) * Currencies.price(currency)).toFixed(fractionSize) : (0).toFixed(fractionSize);
        };

        /**
         * converts from a given currency value to BTC
         * @param value
         * @param currency
         * @param fractionSize (optional)
         */
        self.toBTC = function(value, currency, fractionSize) {
            if (typeof(fractionSize) == "undefined") {
                fractionSize = 8;
            }

            return Currencies.price(currency) ? (parseFloat(value) / Currencies.price(currency)).toFixed(fractionSize) : (0).toFixed(fractionSize);
        };

        /**
         * convert from Satoshi value to a given currency
         * @param value
         * @param currency
         * @param fractionSize (optional)
         */
        self.fromSatoshi = function(value, currency, fractionSize) {
            var btcValue = parseFloat((value/ coin).toFixed(precision));
            if (typeof(fractionSize) == "undefined") {
                fractionSize = 2;
            }

            return Currencies.price(currency) ? (btcValue * Currencies.price(currency)).toFixed(fractionSize) : (0).toFixed(fractionSize);
        };

        /**
         * converts from a given currency value to Satoshi
         * @param value
         * @param currency
         */
        self.toSatoshi = function(value, currency) {
            var btcValue;
            if (currency == "BTC") {
                btcValue = parseFloat(value);
            } else {
                btcValue = self.toBTC(value, currency, precision);
            }

            return parseFloat((btcValue * coin).toFixed(0));
        };
    });
<commit_msg>updated currencies service<commit_after>angular.module('blocktrail.wallet')
    .service( 'Currencies', function($rootScope, storageService, $log, sdkService, CONFIG) {
        var self = this;

        self.cache = storageService.db('currency-rates-cache');
        self.sdk = sdkService.sdk();

        // currencies that the app supports and their symbols
        //  this list shouldn't be used directly `self.currencies` contains the enabled currencies
        var _currencies = {
            BTC: {code: "BTC", symbol: "฿"},
            GBP: {code: "GBP", symbol: "£"},
            EUR: {code: "EUR", symbol: "£"},
            USD: {code: "USD", symbol: "$"},
            CNY: {code: "CNY", symbol: "¥"},
            PAB: {code: "PAB", symbol: "B/"},
            ARS: {code: "ARS", symbol: "$"},
            BOB: {code: "BOB", symbol: "$b"},
            CLP: {code: "CLP", symbol: "$"},
            PEN: {code: "PEN", symbol: "S/"},
            PYG: {code: "PYG", symbol: "Gs"},
            UYU: {code: "UYU", symbol: "$U"},
            VEF: {code: "VEF", symbol: "Bs"},
            CRC: {code: "CRC", symbol: "₡"},
            MXN: {code: "MXN", symbol: "$"},
            NGN: {code: "NGN", symbol: "₦"},
            INR: {code: "INR", symbol: "₹"}
        };

        self.currencies = {};

        self.getCurrencies = function() {
            var self = this;
            return Object.keys(self.currencies).map(function(code) {
                return self.currencies[code];
            });
        };

        self.getFiatCurrencies = function() {
            var self = this;
            return self.getCurrencies().filter(function(currency) { return !!currency.isFiat; });
        };

        self.price = function(currency) {
            var self = this;
            if (typeof self.currencies[currency] === "undefined") {
                return 0;
            } else {
                return self.currencies[currency].price || 0;
            }
        };

        self.prices = function() {
            var prices = {};

            Object.keys(self.currencies).forEach(function(code) {
                prices[code] = self.currencies[code].price;
            });

            return prices;
        };

        /**
         * get the current btc prices (defaults to live, can force getting a cached version)
         * @param getCached
         * @returns {*}
         */
        var updatePrices = null;
        self.updatePrices = function(getCached) {
            var self = this;

            var forceFetch = !getCached;

            if (updatePrices) {
                if (updatePrices.forceFetch !== forceFetch) {
                    return updatePrices.then(function() {
                        return self.updatePrices(getCached);
                    });
                } else {
                    return updatePrices;
                }
            } else {
                updatePrices = self.cache.get('price')
                    .then(function(b) {
                        return b;
                    }, function() {
                        forceFetch = true;
                        return {_id: "price"};
                    })
                    .then(function(pricesDoc) {
                        if (forceFetch) {
                            return self.sdk.then(function(sdk) {
                                return sdk.price().then(function(result) {
                                    angular.extend(pricesDoc, result);

                                    //store in cache and then return
                                    return self.cache.put(pricesDoc).then(function() {
                                        return pricesDoc;
                                    });
                                });
                            });
                        } else {
                            return pricesDoc;
                        }
                    })
                    // use a .then because a .done would break the promise chains that rely on self.wallet
                    .then(function(pricesDoc) {
                        Object.keys(self.currencies).forEach(function(code) {
                            self.currencies[code].price = parseFloat(pricesDoc[code] || 0);
                        });
                        return pricesDoc;
                    }, function(e) {
                        $log.error('prices ERR ' + e);
                        throw e;
                    })
                    .then(function(r) {
                        updatePrices = null;
                        return r;
                    });

                // keep track if we forced for this
                updatePrices.forceFetch = forceFetch;

                return updatePrices;
            }
        };

        self.enableCurrency = function(code) {
            var self = this;

            if (typeof _currencies[code] === "undefined") {
                return false;
            }

            self.currencies[code] = _currencies[code];
            self.currencies[code].isFiat = self.currencies[code].code !== "BTC";
            self.currencies[code].btcRate = 0;

            return true;
        };

        // enable all currencies that are in the config
        CONFIG.CURRENCIES.forEach(function(code) {
            self.enableCurrency(code);
        });
    })
    .service('CurrencyConverter', function($rootScope, Currencies) {
        var self = this;
        var coin = 100000000;
        var precision = 8;

        /**
         * convert from BTC value to a given currency
         * @param value
         * @param currency
         * @param fractionSize (optional)
         */
        self.fromBTC = function(value, currency, fractionSize) {
            if (typeof(fractionSize) == "undefined") {
                fractionSize = 2;
            }

            return Currencies.price(currency) ? (parseFloat(value) * Currencies.price(currency)).toFixed(fractionSize) : (0).toFixed(fractionSize);
        };

        /**
         * converts from a given currency value to BTC
         * @param value
         * @param currency
         * @param fractionSize (optional)
         */
        self.toBTC = function(value, currency, fractionSize) {
            if (typeof(fractionSize) == "undefined") {
                fractionSize = 8;
            }

            return Currencies.price(currency) ? (parseFloat(value) / Currencies.price(currency)).toFixed(fractionSize) : (0).toFixed(fractionSize);
        };

        /**
         * convert from Satoshi value to a given currency
         * @param value
         * @param currency
         * @param fractionSize (optional)
         */
        self.fromSatoshi = function(value, currency, fractionSize) {
            var btcValue = parseFloat((value/ coin).toFixed(precision));
            if (typeof(fractionSize) == "undefined") {
                fractionSize = 2;
            }

            return Currencies.price(currency) ? (btcValue * Currencies.price(currency)).toFixed(fractionSize) : (0).toFixed(fractionSize);
        };

        /**
         * converts from a given currency value to Satoshi
         * @param value
         * @param currency
         */
        self.toSatoshi = function(value, currency) {
            var btcValue;
            if (currency == "BTC") {
                btcValue = parseFloat(value);
            } else {
                btcValue = self.toBTC(value, currency, precision);
            }

            return parseFloat((btcValue * coin).toFixed(0));
        };
    })
    .filter('currencySymbol', function(Currencies) {
        return function(input) {
            return Currencies.currencies[input].symbol;
        }
    });
<|endoftext|>


<commit_before>
import { getEnvironmentValue, FEATURE_ENTRANCES } from '../core/constants.js';

import {
	Vector3, Color,
	BufferAttribute,
	BufferGeometry,
	TextureLoader,
	MultiMaterial,
	PointsMaterial,
	Points,
	Object3D,
} from '../../../../three.js/src/Three.js';

var farPointers = null;

function FarPointers ( survey ) {

	this.points = [];

	var loader = new TextureLoader();

	var yellowTexture = loader.load( getEnvironmentValue( "home", "" ) + "images/marker-yellow.png" );

//	var nullMaterial   = new PointsMaterial( { visible: false } );
	var yellowMaterial = new PointsMaterial( { size: 10, map: yellowTexture, transparent : true, sizeAttenuation: true } );

//	var material = new MultiMaterial( [ nullMaterial, yellowMaterial ] );

	Points.call( this, new BufferGeometry(), yellowMaterial );

	this.type = "CV.FarPointers";

	this.layers.set( FEATURE_ENTRANCES );

	survey.add( this );

	survey.addEventListener( "removed", _onSurveyRemoved );

	function _onSurveyRemoved( event ) {

		var survey = event.target;

		survey.removeEventListener( 'removed', _onSurveyRemoved );

		farPointers.geometry.dispose();
		farPointers = null;

	}

}

FarPointers.prototype = Object.create( Points.prototype );

FarPointers.prototype.constructor = FarPointers;

FarPointers.prototype.updateGeometry = function () {

	// sort by material and update BufferGeometry.

	var points = this.points;
	var vertices = new Float32Array( points.length * 3 );
	var offset = 0;

	for ( var i = 0; i < points.length; i++ ) {

		if ( points[i].materialIndex > 0 ) {

			var position = points[i].position;

			vertices[ offset++ ] = position.x;
			vertices[ offset++ ] = position.y;
			vertices[ offset++ ] = position.z + 5;

		}

	}

	this.visible = ( offset > 0 );

	this.geometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );
	this.geometry.setDrawRange( 0, offset / 3 );

}

FarPointers.prototype.addPointer = function ( position ) {

	var points = this.points;
	var index = points.length;

	this.points.push( { position: position, materialIndex: 1 } );

	this.updateGeometry();

	return index;

}

FarPointers.prototype.setMaterialIndex = function ( index, materialIndex ) {

	this.points[index].materialIndex = materialIndex;
	this.updateGeometry();

}

FarPointers.prototype.getMaterialIndex = function ( index ) {

	return  this.points[index].materialIndex;

}

function EntranceFarPointer ( survey, position ) {

	var self = this;

	if ( farPointers === null ) {

		farPointers = new FarPointers( survey );

	}

	Object3D.call( this );

	this.index = farPointers.addPointer( position );
	this.type = "CV.EntranceFarPointer";

	this.hidden = false;

	Object.defineProperty( this, "visible", {
		writeable: true,
		get: function () { _getVisibility(); },
		set: function ( x ) { _setVisibility( x ); }
	} );

	var fp = farPointers;

	this.addEventListener( "removed", _onRemoved );

	function _onRemoved( event ) {

		var obj = event.target;

		obj.removeEventListener( 'dispose', _onRemoved );

		// hide from view - avoid need to recreate farPointers
		// and traverse all visible EntranceFarPointers and reset index values

		self.hidden = true;

		fp.setMaterialIndex( self.index, 0 );

	}

	function _getVisibility () {

		fp.getMaterialIndex( self.index );

	}

	function _setVisibility ( visible ) {

		var newIndex = ( visible === false || self.hidden ) ? 0 : 1;

		if ( newIndex !== fp.getMaterialIndex( self.index ) ) {

			fp.setMaterialIndex( self.index, newIndex );

		}

	}

}

EntranceFarPointer.prototype = Object.create( Object3D.prototype );

EntranceFarPointer.prototype.constructor = EntranceFarPointer;

// todo - add on visible property to intercept and use to select non visible/alternate colour for marker

export { EntranceFarPointer };

// EOF<commit_msg>fix transparency of entrance indicators<commit_after>
import { getEnvironmentValue, FEATURE_ENTRANCES } from '../core/constants.js';

import {
	Vector3, Color,
	BufferAttribute,
	BufferGeometry,
	TextureLoader,
	MultiMaterial,
	PointsMaterial,
	Points,
	Object3D,
} from '../../../../three.js/src/Three.js';

var farPointers = null;

function FarPointers ( survey ) {

	this.points = [];

	var loader = new TextureLoader();

	var yellowTexture = loader.load( getEnvironmentValue( "home", "" ) + "images/marker-yellow.png" );

//	var nullMaterial   = new PointsMaterial( { visible: false } );
	var yellowMaterial = new PointsMaterial( { size: 10, map: yellowTexture, transparent : true, sizeAttenuation: true, alphaTest: 0.8 } );

//	var material = new MultiMaterial( [ nullMaterial, yellowMaterial ] );

	Points.call( this, new BufferGeometry(), yellowMaterial );

	this.type = "CV.FarPointers";

	this.layers.set( FEATURE_ENTRANCES );

	survey.add( this );

	survey.addEventListener( "removed", _onSurveyRemoved );

	function _onSurveyRemoved( event ) {

		var survey = event.target;

		survey.removeEventListener( 'removed', _onSurveyRemoved );

		farPointers.geometry.dispose();
		farPointers = null;

	}

}

FarPointers.prototype = Object.create( Points.prototype );

FarPointers.prototype.constructor = FarPointers;

FarPointers.prototype.updateGeometry = function () {

	// sort by material and update BufferGeometry.

	var points = this.points;
	var vertices = new Float32Array( points.length * 3 );
	var offset = 0;

	for ( var i = 0; i < points.length; i++ ) {

		if ( points[i].materialIndex > 0 ) {

			var position = points[i].position;

			vertices[ offset++ ] = position.x;
			vertices[ offset++ ] = position.y;
			vertices[ offset++ ] = position.z + 5;

		}

	}

	this.visible = ( offset > 0 );

	this.geometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );
	this.geometry.setDrawRange( 0, offset / 3 );

}

FarPointers.prototype.addPointer = function ( position ) {

	var points = this.points;
	var index = points.length;

	this.points.push( { position: position, materialIndex: 1 } );

	this.updateGeometry();

	return index;

}

FarPointers.prototype.setMaterialIndex = function ( index, materialIndex ) {

	this.points[index].materialIndex = materialIndex;
	this.updateGeometry();

}

FarPointers.prototype.getMaterialIndex = function ( index ) {

	return  this.points[index].materialIndex;

}

function EntranceFarPointer ( survey, position ) {

	var self = this;

	if ( farPointers === null ) {

		farPointers = new FarPointers( survey );

	}

	Object3D.call( this );

	this.index = farPointers.addPointer( position );
	this.type = "CV.EntranceFarPointer";

	this.hidden = false;

	Object.defineProperty( this, "visible", {
		writeable: true,
		get: function () { _getVisibility(); },
		set: function ( x ) { _setVisibility( x ); }
	} );

	var fp = farPointers;

	this.addEventListener( "removed", _onRemoved );

	function _onRemoved( event ) {

		var obj = event.target;

		obj.removeEventListener( 'dispose', _onRemoved );

		// hide from view - avoid need to recreate farPointers
		// and traverse all visible EntranceFarPointers and reset index values

		self.hidden = true;

		fp.setMaterialIndex( self.index, 0 );

	}

	function _getVisibility () {

		fp.getMaterialIndex( self.index );

	}

	function _setVisibility ( visible ) {

		var newIndex = ( visible === false || self.hidden ) ? 0 : 1;

		if ( newIndex !== fp.getMaterialIndex( self.index ) ) {

			fp.setMaterialIndex( self.index, newIndex );

		}

	}

}

EntranceFarPointer.prototype = Object.create( Object3D.prototype );

EntranceFarPointer.prototype.constructor = EntranceFarPointer;

// todo - add on visible property to intercept and use to select non visible/alternate colour for marker

export { EntranceFarPointer };

// EOF<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var {Name}Schema = new Schema({
    // active: {type: Boolean, default: true},
    // name: {type: String},
    createdAt: {type: Date, default: Date.now},
    updatedAt: {type: Date, default: Date.now}
}, {
    strict: false
});

if (!{Name}Schema.options.toJSON) {
    {Name}Schema.options.toJSON = {};
}

{Name}Schema.options.toJSON.transform = function (doc, ret, options) {
    ret.id = ret._id;
    delete ret._id;
    delete ret.__v;
};

mongoose.model('{Name}', {Name}Schema);
<commit_msg>update model with ref example<commit_after>'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var {Name}Schema = new Schema({
    // org: {type: Schema.ObjectId, ref: 'Org', required: true, index: true},
    // active: {type: Boolean, default: true},
    // name: {type: String},
    createdAt: {type: Date, default: Date.now},
    updatedAt: {type: Date, default: Date.now}
}, {
    strict: false
});

if (!{Name}Schema.options.toJSON) {
    {Name}Schema.options.toJSON = {};
}

{Name}Schema.options.toJSON.transform = function (doc, ret, options) {
    ret.id = ret._id;
    delete ret._id;
    delete ret.__v;
};

mongoose.model('{Name}', {Name}Schema);
<|endoftext|>


<commit_before>module.exports = function config(grunt, config) {
    /**
     * @param name string Module name
     */
    config.initModule = function (name, done) {
        // initialize module development environment
        process.chdir(config.workspace.modules + '/' + name);
        var initProcess = config.cp.exec('webino update', function () {
            done && done();
        });
        grunt.log.writeln();
        initProcess.stdout.pipe(process.stdout);
        initProcess.stderr.pipe(process.stderr);
    };

    /**
     * Waiting for utils copying
     */
    config.wait_async.setup = {
        options: {
            wait: function (done) {
                var func = function () {
                    if (grunt.file.isDir(config.utils.php)) {
                        process.chdir(config.utils.php);

                        var tasks = ['copy:utils'];

                        if (config.utils.isInit()) {
                            tasks.push('exec:get_composer');
                        } else {
                            grunt.log.ok('Updating ...');
                            tasks.push('copy:utils_composer', 'exec:composer_self_update');
                        }

                        tasks.push('exec:composer_update', 'exec:get_selenium');
                        grunt.task.run(tasks);
                        done();
                    } else {
                        func();
                    }
                };
                func();
            }
        }
    };

    /**
     * Searching module repository
     */
    config.wait_async.mod = {
        options: {
            timeout: 240 * 10000,
            wait: function (done) {
                if (!config.repositories.size()) {
                    grunt.fail.warn('\n\nExpected any repository \n\n');
                }
                var func = function (error) {
                    if (!config.repositories.size()) {
                        if (error) {
                            grunt.log.debug(error);
                            grunt.fail.warn('\n\nCan\'t clone repository \n\n');
                        }
                        done();
                    }

                    var repo = config.repositories.deq();
                    var name = grunt.task.current.args[0];

                    repo.ssh || grunt.fail.warn('\n\nExpected repository ssh option');
                    name || grunt.fail.warn('\n\nExpected module option, e.g.: \n\ -name WebinoExample \n\n');

                    var uri = repo.ssh + '/' + name;
                    var target = config.workspace.modules + '/' + name;

                    grunt.log.debug(target);
                    if (grunt.file.exists(target + '/.git')) {
                        grunt.log.write('\nTarget already exists, initializing ...');
                        config.initModule(name, done);
                        return;
                    }

                    grunt.log.write('Cloning ' + repo.name + ':' + repo.vendor + '/' + name + ' ...');
                    config.loading();

                    grunt.log.debug(uri);
                    grunt.log.debug(repo);

                    var cloneProcess = config.cp.exec('git clone ' + uri + ' ' + target, function (error) {
                        config.loading.stop();
                        if (error) {
                            func(error);
                            return;
                        }

                        grunt.log.writeln('OK');
                        grunt.log.ok('\nInitializing ' + target + ' ...');
                        config.initModule(name, done);
                    });

                    cloneProcess.stderr.on('data', function (data) {
                        grunt.log.debug(data);
                        if (-1 !== data.indexOf('not exist')
                            || -1 !== data.indexOf('not found')
                        ) {
                            grunt.log.writeln('nope');
                        }
                    });

                    cloneProcess.stdout.on('data', function (data) {
                        grunt.log.debug(data);
                    });

                    if (config.verbose) {
                        cloneProcess.stdout.pipe(process.stdout);
                        cloneProcess.stderr.pipe(process.stderr);
                    }
                };
                func();
            }
        }
    };

    config.mkdir.workspace = {
        options: {create: ['<%= workspace.root %>']}
    };

    config.mkdir.utils = {
        options: {create: ['<%= utils.root %>', '<%= utils.php %>']}
    };

    config.copy.workspace = {
        files: [{
            expand: true,
            cwd: '<%= data.workspace %>',
            src: ['**'],
            dest: '<%= workspace.root %>',
            mode: 644
        }]
    };

    config.copy.utils = {
        files: [{
            expand: true,
            cwd: '<%= data.utils %>',
            src: ['**'],
            dest: '<%= utils.root %>',
            mode: 644
        }]
    };

    config.copy.utils_composer = {
        files: [{
            expand: true,
            cwd: '<%= data.utils %>/php',
            src: ['composer.json'],
            dest: '<%= utils.root %>/php',
            mode: 644
        }]
    };

    /**
     * Prompt authentication settings for user cfg
     */
    config.wait_async['prompt-user-cfg-auth'] = {
        options: {
            timeout: 240 * 10000,
            wait: function (done) {
                // by options
                var identity   = grunt.option('auth-identity');
                var credential = grunt.option('auth-credential');

                if (identity && credential) {
                    config.userCfg.authentication = {
                        identity:   identity,
                        credential: credential
                    };
                    done();
                    return;
                }

                // prompt admin auth data
                config.prompt.get({
                        properties: {
                            identity: {
                                description: 'Auth Username'
                            },
                            credential: {
                                description: 'Auth Password'
                            }
                        }
                    }, function (err, result) {
                        if (err) {
                            done();
                            grunt.fatal(err);
                            return;
                        }

                        config.userCfg.authentication = result;
                        done();
                    }
                );
            }
        }
    };

    /**
     * Add module to user cfg
     */
    config.tasks['user-cfg-module'] = {
        function: function (module) {
            config.userCfg.modules
            || (config.userCfg.modules = []);

            // register module
            (-1 === config.userCfg.modules.indexOf(module))
            && config.userCfg.modules.push(module);
        }
    };

    /**
     * Initializes user workspace
     * Required to run as user.
     */
    config.tasks.workspace = {
        description: 'Initialize your Webino workspace',
        function: function () {
            grunt.log.ok('Initializing workspace ...');
            if (!process.getuid()) {
                grunt.fail.warn('Are you a root?');
                return;
            }

            // crete user workspace
            grunt.task.run(['init-user-cfg', 'mkdir:workspace', 'copy:workspace']);
        }
    };

    /**
     * Resolve database credentials from config file
     * Required to run as user.
     */
    config.tasks['setup-user-cfg-database'] = {
        function: function () {
            var cmd = 'php -r "echo json_encode(parse_ini_file(\'.my.cnf\'));"';
            var result = exec(cmd, {silent: true}).output.trim();
            try {
                config.userCfg.database = JSON.parse(result);
            } catch (exc) {
                grunt.fatal(exc);
            }
        }
    };

    /**
     * Write user config to a file
     * Required to run as user.
     */
    config.tasks['write-user-cfg'] = {
        function: function () {
            if (!grunt.file.exists(config.userCfgPath)) {
                // init config
                var distCfg = grunt.file.readJSON(config.root + '/dist/webino.json');
                config.userCfg = config.utils.extend(distCfg, config.userCfg);
            }

            // write
            grunt.file.write(config.userCfgPath, JSON.stringify(config.userCfg, null, 4));
        }
    };

    /**
     * Initializes user config
     * Required to run as user.
     */
    config.tasks['init-user-cfg'] = {
        function: [
            'wait_async:prompt-user-cfg-auth',
            'setup-user-cfg-database',
            'write-user-cfg'
        ]
    };

    /**
     * Adds module to user config
     * Required to run as user.
     */
    config.tasks['add-module'] = {
        function: function (module) {
            grunt.task.run([
                'add-module-' + module,
                'user-cfg-module:' + module,
                'write-user-cfg'
            ]);
        }
    };

    config.tasks.mod = {
        description: 'Develop existing Webino module',
        examples: ['webino mod:WebinoExample'],
        function: function (name) {
            // Resolve module by name
            name || grunt.fail.warn('\n\nExpected module option, e.g.: \n\ -name WebinoExample \n\n');
            grunt.log.writeln('Preparing module \'' + name + '\' for development ...');
            grunt.task.run('wait_async:mod:' + name);
        }
    };

    /**
     * Required to run as root
     */
    config.tasks.setup = {
        function: function () {
            var tasks = [];

            if (config.utils.isInit()) {
                grunt.log.ok('Initializing ...');
                tasks.push('mkdir:utils');
            }

            tasks.push('wait_async:setup');
            grunt.task.run(tasks);
        }
    };
};
<commit_msg>Fixed add & config module support<commit_after>module.exports = function config(grunt, config) {
    /**
     * @param name string Module name
     */
    config.initModule = function (name, done) {
        // initialize module development environment
        process.chdir(config.workspace.modules + '/' + name);
        var initProcess = config.cp.exec('webino update', function () {
            done && done();
        });
        grunt.log.writeln();
        initProcess.stdout.pipe(process.stdout);
        initProcess.stderr.pipe(process.stderr);
    };

    /**
     * Waiting for utils copying
     */
    config.wait_async.setup = {
        options: {
            wait: function (done) {
                var func = function () {
                    if (grunt.file.isDir(config.utils.php)) {
                        process.chdir(config.utils.php);

                        var tasks = ['copy:utils'];

                        if (config.utils.isInit()) {
                            tasks.push('exec:get_composer');
                        } else {
                            grunt.log.ok('Updating ...');
                            tasks.push('copy:utils_composer', 'exec:composer_self_update');
                        }

                        tasks.push('exec:composer_update', 'exec:get_selenium');
                        grunt.task.run(tasks);
                        done();
                    } else {
                        func();
                    }
                };
                func();
            }
        }
    };

    /**
     * Searching module repository
     */
    config.wait_async.mod = {
        options: {
            timeout: 240 * 10000,
            wait: function (done) {
                if (!config.repositories.size()) {
                    grunt.fail.warn('\n\nExpected any repository \n\n');
                }
                var func = function (error) {
                    if (!config.repositories.size()) {
                        if (error) {
                            grunt.log.debug(error);
                            grunt.fail.warn('\n\nCan\'t clone repository \n\n');
                        }
                        done();
                    }

                    var repo = config.repositories.deq();
                    var name = grunt.task.current.args[0];

                    repo.ssh || grunt.fail.warn('\n\nExpected repository ssh option');
                    name || grunt.fail.warn('\n\nExpected module option, e.g.: \n\ -name WebinoExample \n\n');

                    var uri = repo.ssh + '/' + name;
                    var target = config.workspace.modules + '/' + name;

                    grunt.log.debug(target);
                    if (grunt.file.exists(target + '/.git')) {
                        grunt.log.write('\nTarget already exists, initializing ...');
                        config.initModule(name, done);
                        return;
                    }

                    grunt.log.write('Cloning ' + repo.name + ':' + repo.vendor + '/' + name + ' ...');
                    config.loading();

                    grunt.log.debug(uri);
                    grunt.log.debug(repo);

                    var cloneProcess = config.cp.exec('git clone ' + uri + ' ' + target, function (error) {
                        config.loading.stop();
                        if (error) {
                            func(error);
                            return;
                        }

                        grunt.log.writeln('OK');
                        grunt.log.ok('\nInitializing ' + target + ' ...');
                        config.initModule(name, done);
                    });

                    cloneProcess.stderr.on('data', function (data) {
                        grunt.log.debug(data);
                        if (-1 !== data.indexOf('not exist')
                            || -1 !== data.indexOf('not found')
                        ) {
                            grunt.log.writeln('nope');
                        }
                    });

                    cloneProcess.stdout.on('data', function (data) {
                        grunt.log.debug(data);
                    });

                    if (config.verbose) {
                        cloneProcess.stdout.pipe(process.stdout);
                        cloneProcess.stderr.pipe(process.stderr);
                    }
                };
                func();
            }
        }
    };

    config.mkdir.workspace = {
        options: {create: ['<%= workspace.root %>']}
    };

    config.mkdir.utils = {
        options: {create: ['<%= utils.root %>', '<%= utils.php %>']}
    };

    config.copy.workspace = {
        files: [{
            expand: true,
            cwd: '<%= data.workspace %>',
            src: ['**'],
            dest: '<%= workspace.root %>',
            mode: 644
        }]
    };

    config.copy.utils = {
        files: [{
            expand: true,
            cwd: '<%= data.utils %>',
            src: ['**'],
            dest: '<%= utils.root %>',
            mode: 644
        }]
    };

    config.copy.utils_composer = {
        files: [{
            expand: true,
            cwd: '<%= data.utils %>/php',
            src: ['composer.json'],
            dest: '<%= utils.root %>/php',
            mode: 644
        }]
    };

    /**
     * Initializes user workspace
     * Required to run as user.
     */
    config.tasks.workspace = {
        description: 'Initialize your Webino workspace',
        function: function () {
            grunt.log.ok('Initializing workspace ...');
            if (!process.getuid()) {
                grunt.fail.warn('Are you a root?');
                return;
            }

            // crete user workspace
            grunt.task.run(['init-user-cfg', 'mkdir:workspace', 'copy:workspace']);
        }
    };

    /**
     * Initializes user config
     * Required to run as user.
     */
    config.tasks['init-user-cfg'] = {
        function: [
            'wait_async:prompt-user-cfg-auth',
            'setup-user-cfg-database',
            'write-user-cfg'
        ]
    };

    /**
     * Adds module to user config
     * Required to run as user.
     */
    config.tasks['add-module'] = {
        function: function (module) {
            grunt.task.run('user-cfg-module:' + module);
            exec('webino config-module:' + module);
        }
    };

    /**
     * Configures module to user config
     */
    config.tasks['config-module'] = {
        function: function (module) {
            grunt.task.run([
                'add-module-' + module,
                'write-user-cfg'
            ]);
        }
    };

    /**
     * Prompt authentication settings for user cfg
     */
    config.wait_async['prompt-user-cfg-auth'] = {
        options: {
            timeout: 240 * 10000,
            wait: function (done) {
                // by options
                var identity   = grunt.option('auth-identity');
                var credential = grunt.option('auth-credential');

                if (identity && credential) {
                    config.userCfg.authentication = {
                        identity:   identity,
                        credential: credential
                    };
                    done();
                    return;
                }

                // prompt admin auth data
                config.prompt.get({
                        properties: {
                            identity: {
                                description: 'Auth Username'
                            },
                            credential: {
                                description: 'Auth Password'
                            }
                        }
                    }, function (err, result) {
                        if (err) {
                            done();
                            grunt.fatal(err);
                            return;
                        }

                        config.userCfg.authentication = result;
                        done();
                    }
                );
            }
        }
    };

    /**
     * Add module to user cfg
     */
    config.tasks['user-cfg-module'] = {
        function: function (module) {
            config.userCfg.modules
            || (config.userCfg.modules = []);

            // register module
            (-1 === config.userCfg.modules.indexOf(module))
            && config.userCfg.modules.push(module);
        }
    };

    /**
     * Resolve database credentials from config file
     * Required to run as user.
     */
    config.tasks['setup-user-cfg-database'] = {
        function: function () {
            var cmd = 'php -r "echo json_encode(parse_ini_file(\'.my.cnf\'));"';
            var result = exec(cmd, {silent: true}).output.trim();
            try {
                config.userCfg.database = JSON.parse(result);
            } catch (exc) {
                grunt.fatal(exc);
            }
        }
    };

    /**
     * Write user config to a file
     * Required to run as user.
     */
    config.tasks['write-user-cfg'] = {
        function: function () {
            if (!grunt.file.exists(config.userCfgPath)) {
                // init config
                var distCfg = grunt.file.readJSON(config.root + '/dist/webino.json');
                config.userCfg = config.utils.extend(distCfg, config.userCfg);
            }

            // write
            grunt.file.write(config.userCfgPath, JSON.stringify(config.userCfg, null, 4));
        }
    };

    config.tasks.mod = {
        description: 'Develop existing Webino module',
        examples: ['webino mod:WebinoExample'],
        function: function (name) {
            // Resolve module by name
            name || grunt.fail.warn('\n\nExpected module option, e.g.: \n\ -name WebinoExample \n\n');
            grunt.log.writeln('Preparing module \'' + name + '\' for development ...');
            grunt.task.run('wait_async:mod:' + name);
        }
    };

    /**
     * Required to run as root
     */
    config.tasks.setup = {
        function: function () {
            var tasks = [];

            if (config.utils.isInit()) {
                grunt.log.ok('Initializing ...');
                tasks.push('mkdir:utils');
            }

            tasks.push('wait_async:setup');
            grunt.task.run(tasks);
        }
    };
};
<|endoftext|>