<commit_before>/*global define,console */
/*jslint browser:true,sloppy:true,nomen:true,unparam:true,plusplus:true */
/*
 | Copyright 2014 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
define([
    "dojo/_base/declare",
    "dojo/_base/Color",
    "dojo/_base/fx",
    "dojo/_base/lang",
    "dojo/Deferred",
    "dojo/dom",
    "dojo/dom-class",
    "dojo/dom-construct",
    "dojo/dom-style",
    "dojo/json",
    "dojo/on",
    "dojo/parser",
    "dojo/promise/all",
    "dojo/promise/first",
    "dojo/topic",
    "esri/arcgis/utils",
    "esri/dijit/LocateButton",
    "application/lib/LayerAndTableMgmt",
    "application/widgets/ItemList/ItemList",
    "application/widgets/Mock/MockDialog",
    "application/widgets/Mock/ItemDetails",
    "application/widgets/Mock/MockWidget",
    "application/widgets/PopupWindow/PopupWindow",
    "application/widgets/SidebarContentController/SidebarContentController",
    "application/widgets/SidebarHeader/SidebarHeader",
    "dijit/layout/LayoutContainer",
    "dijit/layout/ContentPane",
    "dojox/color/_base",
    "dojo/domReady!"
], function (
    declare,
    Color,
    fx,
    lang,
    Deferred,
    dom,
    domClass,
    domConstruct,
    domStyle,
    JSON,
    on,
    parser,
    all,
    first,
    topic,
    arcgisUtils,
    LocateButton,
    LayerAndTableMgmt,
    ItemList,
    MockDialog,
    ItemDetails,
    MockWidget,
    PopupWindow,
    SidebarContentController,
    SidebarHeader
) {
    return declare(null, {
        config: {},
        map: null,
        mapData: null,

        startup: function (config) {
            var itemInfo, error;

            parser.parse();

            // config will contain application and user defined info for the template such as i18n strings, the web map id
            // and application id
            // any url parameters and any application specific configuration information.
            if (config) {
                this.config = config;
                //supply either the webmap id or, if available, the item info
                itemInfo = this.config.itemInfo || this.config.webmap;
                this._launch(itemInfo);
            } else {
                error = new Error("Main:: Config is not defined");
                this.reportError(error);
            }
        },

        reportError: function (error) {
            // remove loading class from body
            domClass.remove(document.body, "app-loading");
            domClass.add(document.body, "app-error");
            // an error occurred - notify the user. In this example we pull the string from the
            // resource.js file located in the nls folder because we've set the application up
            // for localization. If you don't need to support multiple languages you can hardcode the
            // strings here and comment out the call in index.html to get the localization strings.
            // set message
            var node = dom.byId("loading_message");
            if (node) {
                if (this.config && this.config.i18n) {
                    node.innerHTML = this.config.i18n.map.error + ": " + ((error && error.message) || error || "");
                } else {
                    node.innerHTML = "Unable to create map: " + ((error && error.message) || error || "");
                }
            }
        },

        //========================================================================================================================//

        /**
         * Launches app.
         * @param {object|string} itemInfo Configuration object created by template.js or webmap id
         */
        _launch: function (itemInfo) {
            var setupUI, createMap;

            // Perform setups in parallel
            setupUI = this._setupUI();
            createMap = this._createWebMap(itemInfo);

            // Show the app when the first of the setups completes
            first([setupUI, createMap]).then(lang.hitch(this, function () {
                this._revealApp();
            }));

            // Complete wiring-up when all of the setups complete
            all([setupUI, createMap]).then(lang.hitch(this, function (statusList) {

                // Let the item list widget know the names of the special-purpose item layer fields
                this._itemsList.setFields(this._mapData.getItemSpecialFields());

                // Published by SidebarHeader
                topic.subscribe("socialConnectSelected", lang.hitch(this, function () {
                    this._socialDialog.show();
                }));

                // Published by SidebarHeader
                topic.subscribe("helpSelected", lang.hitch(this, function () {
                    this._helpDialogContainer.set("displayText", this.config.displayText);
                    this._helpDialogContainer.show();
                }));

                // Published upon startup and by click on button to reset item list to match
                // current map extents
                topic.subscribe("updateItemsList", lang.hitch(this, function () {
                    this._mapData.queryItems(this.map.extent);
                    this._sidebarCnt.showPanel("ideasList");
                    this._sidebarCnt.showBusy(true);
                }));

                // Published by LayerAndTableManagement
                topic.subscribe("updatedItemsList", lang.hitch(this, function (items) {
                    this._itemsList.setItems(items);
                    this._sidebarCnt.showBusy(false);
                }));

                // Published by layer click handler and by ItemList
                on(this._mapData.getItemLayer(), "click", function (evt) {
                    if (evt.graphic) {
                        topic.publish("itemSelected", evt.graphic);
                    }
                });
                topic.subscribe("itemSelected", lang.hitch(this, function (item) {
                    var itemExtent;

                    this._itemDetails.setItem(item);
                    this._sidebarCnt.showPanel("ideaDetails");
                    topic.publish("updateCommentsList", item);

                    // Zoom to item if possible
                    if (item.geometry.getExtent) {
                        itemExtent = item.geometry.getExtent();
                    }
                    if (itemExtent) {
                        this.map.setExtent(itemExtent.expand(1.5));
                    } else {
                        this.map.centerAndZoom(item.geometry,
                            Math.min(2 + this.map.getZoom(), this.map.getMaxZoom()));
                    }
                }));

                // Published by ItemDetails
                topic.subscribe("showItemsList", lang.hitch(this, function () {
                    this._sidebarCnt.showPanel("ideasList");
                }));

                // Published by LayerAndTableManagement after comment is added
                topic.subscribe("commentAdded", lang.hitch(this, function (comment) {
                    console.log("commentAdded: " + JSON.stringify(comment));
                }));

                // Published when an item is selected and after a comment is added
                topic.subscribe("updateCommentsList", lang.hitch(this, function (item) {
                    this._mapData.queryComments(item);
                    this._sidebarCnt.showBusy(true);
                }));

                // Published by LayerAndTableManagement
                topic.subscribe("updatedCommentsList", lang.hitch(this, function (comments) {
                    this._itemDetails.setComments(comments);
                    this._sidebarCnt.showBusy(false);
                }));

                // Initial population of items list
                topic.publish("updateItemsList");

                //??? Cancellation handling: e.g., select two+ items from map or items list rapidly

                console.log("app is ready: " + JSON.stringify(statusList));
            }), lang.hitch(this, function (err) {
                this.reportError(err);
            }));
        },

        /**
         * Sets up UI.
         * @return {object} Deferred
         */
        _setupUI: function () {
            var deferred = new Deferred();
            setTimeout(lang.hitch(this, function () {

                // Set the theme
                if (new Color(this.config.color).toHsl().l > 60) {
                    this.config.theme = {
                        "background": this.config.color,
                        "foreground": "black",
                        "shading": "white"
                    };
                } else {
                    this.config.theme = {
                        "background": this.config.color,
                        "foreground": "white",
                        "shading": "black"
                    };
                }

                // Add the widgets
                this._sidebarHdr = new SidebarHeader({
                    "appConfig": this.config
                }).placeAt("sidebarHeading");
                this._sidebarHdr.startup();
                this._sidebarHdr.set("signInBtnOnClick", lang.hitch(this, function () {
                    topic.publish("socialConnectSelected");
                }));
                this._sidebarHdr.set("helpBtnOnClick", lang.hitch(this, function () {
                    topic.publish("helpSelected");
                }));

                this._socialDialog = new MockDialog({
                    "appConfig": this.config,
                    "label": "Social Media Sign-in"
                }).placeAt(document.body);
                this._socialDialog.startup();
                this._socialDialog.createMockClickSource("close", lang.hitch(this, function () {
                    this._socialDialog.hide();
                }));
                this._socialDialog.createMockClickSource("sign in", lang.hitch(this, function () {
                    topic.publish("signedIn");
                }));

                this._helpDialogContainer = new PopupWindow({
                    "appConfig": this.config,
                    "showClose": true
                }).placeAt(document.body);
                this._helpDialogContainer.startup();

                this._sidebarCnt = new SidebarContentController({
                    "appConfig": this.config
                }).placeAt("sidebarContent");
                this._sidebarCnt.startup();

                this._itemsList = new ItemList({
                    "appConfig": this.config
                }).placeAt("sidebarContent");
                this._itemsList.startup();
                this._sidebarCnt.addPanel("ideasList", this._itemsList);

                this._itemDetails = new ItemDetails({
                    "appConfig": this.config,
                    "label": "Idea Details"
                }).placeAt("sidebarContent");
                this._itemDetails.startup();
                this._itemDetails.createMockClickSource("back", lang.hitch(this, function () {
                    topic.publish("showItemsList");
                }));
                this._sidebarCnt.addPanel("ideaDetails", this._itemDetails);

                deferred.resolve("ui");
            }));
            return deferred.promise;
        },

        /**
         * Creates a map based on the input item info or web map id.
         * @param {object|string} itemInfo Configuration object created by template.js or webmap id
         * @return {object} Deferred
         */
        _createWebMap: function (itemInfo) {
            var mapCreateDeferred, mapDataReadyDeferred;
            mapCreateDeferred = new Deferred();
            mapDataReadyDeferred = new Deferred();

            // Create and load the map
            arcgisUtils.createMap(itemInfo, "mapDiv", {
                mapOptions: {
                    // Optionally define additional map config here for example you can
                    // turn the slider off, display info windows, disable wraparound 180, slider position and more.
                },
                usePopupManager: true,
                editable: this.config.editable,
                bingMapsKey: this.config.bingKey
            }).then(lang.hitch(this, function (response) {
                // Once the map is created we get access to the response which provides important info
                // such as the map, operational layers, popup info and more. This object will also contain
                // any custom options you defined for the template. In this example that is the 'theme' property.
                // Here' we'll use it to update the application to match the specified color theme.
                this.map = response.map;

                // start up locate widget
                var geoLocate = new LocateButton({
                    map: this.map
                }, "LocateButton");
                geoLocate.startup();

                // make sure map is loaded
                if (this.map.loaded) {
                    mapCreateDeferred.resolve();
                } else {
                    on.once(this.map, "load", lang.hitch(this, function () {
                        mapCreateDeferred.resolve();
                    }));
                }
            }), function (err) {
                mapCreateDeferred.reject((err ? ": " + err : ""));
            });

            // Once the map and its first layer are loaded, get the layer's data
            mapCreateDeferred.then(lang.hitch(this, function () {
                // At this point, this.config has been supplemented with
                // the first operational layer's layerObject
                this._mapData = new LayerAndTableMgmt(this.config);
                this._mapData.load().then(function () {
                    mapDataReadyDeferred.resolve("map data");
                }, lang.hitch(this, function (err) {
                    mapDataReadyDeferred.reject(this.config.i18n.map.layerLoad + (err ? ": " + err : ""));
                }));
            }), lang.hitch(this, function (err) {
                mapDataReadyDeferred.reject(this.config.i18n.map.layerLoad + (err ? ": " + err : ""));
            }));

            return mapDataReadyDeferred.promise;
        },

        /**
         * Hides the loading indicator and reveals the content.
         */
        _revealApp: function () {
            domClass.remove(document.body, "app-loading");
            fx.fadeIn({
                node: "contentDiv",
                duration: 1000,
                onEnd: function () {
                    domClass.remove("contentDiv", "transparent");
                }
            }).play();
        }
    });
});
<commit_msg>Added DynamicForm into controller<commit_after>/*global define,console,mockCurrentItem:true */
/*jslint browser:true,sloppy:true,nomen:true,unparam:true,plusplus:true */
/*
 | Copyright 2014 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
define([
    "dojo/_base/declare",
    "dojo/_base/Color",
    "dojo/_base/fx",
    "dojo/_base/lang",
    "dojo/Deferred",
    "dojo/dom",
    "dojo/dom-class",
    "dojo/dom-construct",
    "dojo/dom-style",
    "dojo/json",
    "dojo/on",
    "dojo/parser",
    "dojo/promise/all",
    "dojo/promise/first",
    "dojo/topic",
    "esri/arcgis/utils",
    "esri/dijit/LocateButton",
    "application/lib/LayerAndTableMgmt",
    "application/widgets/DynamicForm/DynamicForm",
    "application/widgets/ItemList/ItemList",
    "application/widgets/Mock/MockDialog",
    "application/widgets/Mock/ItemDetails",
    "application/widgets/Mock/MockWidget",
    "application/widgets/PopupWindow/PopupWindow",
    "application/widgets/SidebarContentController/SidebarContentController",
    "application/widgets/SidebarHeader/SidebarHeader",
    "dijit/layout/LayoutContainer",
    "dijit/layout/ContentPane",
    "dojox/color/_base",
    "dojo/domReady!"
], function (
    declare,
    Color,
    fx,
    lang,
    Deferred,
    dom,
    domClass,
    domConstruct,
    domStyle,
    JSON,
    on,
    parser,
    all,
    first,
    topic,
    arcgisUtils,
    LocateButton,
    LayerAndTableMgmt,
    DynamicForm,
    ItemList,
    MockDialog,
    ItemDetails,
    MockWidget,
    PopupWindow,
    SidebarContentController,
    SidebarHeader
) {
    return declare(null, {
        config: {},
        map: null,
        mapData: null,
        mockCurrentItem: null,  //???

        startup: function (config) {
            var itemInfo, error;

            parser.parse();

            // config will contain application and user defined info for the template such as i18n strings, the web map id
            // and application id
            // any url parameters and any application specific configuration information.
            if (config) {
                this.config = config;
                //supply either the webmap id or, if available, the item info
                itemInfo = this.config.itemInfo || this.config.webmap;
                this._launch(itemInfo);
            } else {
                error = new Error("Main:: Config is not defined");
                this.reportError(error);
            }
        },

        reportError: function (error) {
            // remove loading class from body
            domClass.remove(document.body, "app-loading");
            domClass.add(document.body, "app-error");
            // an error occurred - notify the user. In this example we pull the string from the
            // resource.js file located in the nls folder because we've set the application up
            // for localization. If you don't need to support multiple languages you can hardcode the
            // strings here and comment out the call in index.html to get the localization strings.
            // set message
            var node = dom.byId("loading_message");
            if (node) {
                if (this.config && this.config.i18n) {
                    node.innerHTML = this.config.i18n.map.error + ": " + ((error && error.message) || error || "");
                } else {
                    node.innerHTML = "Unable to create map: " + ((error && error.message) || error || "");
                }
            }
        },

        //========================================================================================================================//

        /**
         * Launches app.
         * @param {object|string} itemInfo Configuration object created by template.js or webmap id
         */
        _launch: function (itemInfo) {
            var setupUI, createMap;

            // Perform setups in parallel
            setupUI = this._setupUI();
            createMap = this._createWebMap(itemInfo);

            // Show the app when the first of the setups completes
            first([setupUI, createMap]).then(lang.hitch(this, function () {
                this._revealApp();
            }));

            // Complete wiring-up when all of the setups complete
            all([setupUI, createMap]).then(lang.hitch(this, function (statusList) {

                // Let widgets know about the map data fields
                this._itemsList.setFields(this._mapData.getItemSpecialFields());
                this._itemAddComment.setFields(this._mapData.getCommentFields());

                // Published by SidebarHeader
                topic.subscribe("socialConnectSelected", lang.hitch(this, function () {
                    this._socialDialog.show();
                }));

                // Published by SidebarHeader
                topic.subscribe("helpSelected", lang.hitch(this, function () {
                    this._helpDialogContainer.set("displayText", this.config.displayText);
                    this._helpDialogContainer.show();
                }));

                // Published upon startup and by click on button to reset item list to match
                // current map extents
                topic.subscribe("updateItemsList", lang.hitch(this, function () {
                    this._mapData.queryItems(this.map.extent);
                    this._sidebarCnt.showPanel("ideasList");
                    this._sidebarCnt.showBusy(true);
                }));

                // Published by LayerAndTableManagement
                topic.subscribe("updatedItemsList", lang.hitch(this, function (items) {
                    this._itemsList.setItems(items);
                    this._sidebarCnt.showBusy(false);
                }));

                // Published by layer click handler and by ItemList
                on(this._mapData.getItemLayer(), "click", function (evt) {
                    if (evt.graphic) {
                        topic.publish("itemSelected", evt.graphic);
                    }
                });
                topic.subscribe("itemSelected", lang.hitch(this, function (item) {
                    var itemExtent;
                    mockCurrentItem = item;  //???

                    this._itemDetails.setItem(item);
                    this._sidebarCnt.showPanel("ideaDetails");
                    topic.publish("updateCommentsList", item);

                    // Zoom to item if possible
                    if (item.geometry.getExtent) {
                        itemExtent = item.geometry.getExtent();
                    }
                    if (itemExtent) {
                        this.map.setExtent(itemExtent.expand(1.5));
                    } else {
                        this.map.centerAndZoom(item.geometry,
                            Math.min(2 + this.map.getZoom(), this.map.getMaxZoom()));
                    }
                }));

                // Published by ItemDetails
                topic.subscribe("showItemsList", lang.hitch(this, function () {
                    this._sidebarCnt.showPanel("ideasList");
                }));

                // Published by DynamicForm
                topic.subscribe("cancelForm", lang.hitch(this, function () {
                    this._sidebarCnt.showPanel("ideaDetails");
                }));

                // Published by DynamicForm
                topic.subscribe("submitForm", lang.hitch(this, function (item, comment) {
                    this._mapData.addComment(item, comment);
                    this._sidebarCnt.showPanel("ideaDetails");
                }));

                // Published by ItemDetails
                topic.subscribe("addComment", lang.hitch(this, function (item) {
                    this._itemAddComment.setItem(item);
                    this._sidebarCnt.showPanel("addComment");
                }));

                // Published by LayerAndTableManagement after comment add fails
                topic.subscribe("commentAddFailed", lang.hitch(this, function (error) {
                    console.log("commentAddFailed: " + error);
                    this._sidebarCnt.showPanel("ideaDetails");
                }));

                // Published by LayerAndTableManagement after comment is added
                topic.subscribe("commentAdded", lang.hitch(this, function (comment) {
                    console.log("commentAdded: " + JSON.stringify(comment));
                    topic.publish("updateCommentsList");
                    this._sidebarCnt.showPanel("ideaDetails");
                }));

                // Published when an item is selected and after a comment is added
                topic.subscribe("updateCommentsList", lang.hitch(this, function (item) {
                    this._mapData.queryComments(item);
                    this._sidebarCnt.showBusy(true);
                }));

                // Published by LayerAndTableManagement
                topic.subscribe("updatedCommentsList", lang.hitch(this, function (comments) {
                    this._itemDetails.setComments(comments);
                    this._sidebarCnt.showBusy(false);
                }));

                // Initial population of items list
                topic.publish("updateItemsList");

                //??? Cancellation handling: e.g., select two+ items from map or items list rapidly

                console.log("app is ready: " + JSON.stringify(statusList));
            }), lang.hitch(this, function (err) {
                this.reportError(err);
            }));
        },

        /**
         * Sets up UI.
         * @return {object} Deferred
         */
        _setupUI: function () {
            var deferred = new Deferred();
            setTimeout(lang.hitch(this, function () {

                // Set the theme
                if (new Color(this.config.color).toHsl().l > 60) {
                    this.config.theme = {
                        "background": this.config.color,
                        "foreground": "black",
                        "shading": "white"
                    };
                } else {
                    this.config.theme = {
                        "background": this.config.color,
                        "foreground": "white",
                        "shading": "black"
                    };
                }

                // Add the widgets
                this._sidebarHdr = new SidebarHeader({
                    "appConfig": this.config
                }).placeAt("sidebarHeading");
                this._sidebarHdr.startup();
                this._sidebarHdr.set("signInBtnOnClick", lang.hitch(this, function () {
                    topic.publish("socialConnectSelected");
                }));
                this._sidebarHdr.set("helpBtnOnClick", lang.hitch(this, function () {
                    topic.publish("helpSelected");
                }));

                this._socialDialog = new MockDialog({
                    "appConfig": this.config,
                    "label": "Social Media Sign-in"
                }).placeAt(document.body);
                this._socialDialog.startup();
                this._socialDialog.createMockClickSource("close", lang.hitch(this, function () {
                    this._socialDialog.hide();
                }));
                this._socialDialog.createMockClickSource("sign in", lang.hitch(this, function () {
                    topic.publish("signedIn");
                }));

                this._helpDialogContainer = new PopupWindow({
                    "appConfig": this.config,
                    "showClose": true
                }).placeAt(document.body);
                this._helpDialogContainer.startup();

                this._sidebarCnt = new SidebarContentController({
                    "appConfig": this.config
                }).placeAt("sidebarContent");
                this._sidebarCnt.startup();

                this._itemsList = new ItemList({
                    "appConfig": this.config
                }).placeAt("sidebarContent");
                this._itemsList.startup();
                this._sidebarCnt.addPanel("ideasList", this._itemsList);

                this._itemDetails = new ItemDetails({
                    "appConfig": this.config,
                    "label": "Idea Details"
                }).placeAt("sidebarContent");
                this._itemDetails.startup();
                this._itemDetails.createMockClickSource("back", lang.hitch(this, function () {
                    mockCurrentItem = null;
                    topic.publish("showItemsList");
                }));
                this._itemDetails.createMockClickSource("like", lang.hitch(this, function () {
                    topic.publish("addLike", mockCurrentItem);
                }));
                this._itemDetails.createMockClickSource("comment", lang.hitch(this, function () {
                    topic.publish("addComment", mockCurrentItem);
                }));
                this._sidebarCnt.addPanel("ideaDetails", this._itemDetails);

                this._itemAddComment = new DynamicForm({
                    "appConfig": this.config
                }).placeAt("sidebarContent");
                this._itemAddComment.startup();
                this._sidebarCnt.addPanel("addComment", this._itemAddComment);

                deferred.resolve("ui");
            }));
            return deferred.promise;
        },

        /**
         * Creates a map based on the input item info or web map id.
         * @param {object|string} itemInfo Configuration object created by template.js or webmap id
         * @return {object} Deferred
         */
        _createWebMap: function (itemInfo) {
            var mapCreateDeferred, mapDataReadyDeferred;
            mapCreateDeferred = new Deferred();
            mapDataReadyDeferred = new Deferred();

            // Create and load the map
            arcgisUtils.createMap(itemInfo, "mapDiv", {
                mapOptions: {
                    // Optionally define additional map config here for example you can
                    // turn the slider off, display info windows, disable wraparound 180, slider position and more.
                },
                usePopupManager: true,
                editable: this.config.editable,
                bingMapsKey: this.config.bingKey
            }).then(lang.hitch(this, function (response) {
                // Once the map is created we get access to the response which provides important info
                // such as the map, operational layers, popup info and more. This object will also contain
                // any custom options you defined for the template. In this example that is the 'theme' property.
                // Here' we'll use it to update the application to match the specified color theme.
                this.map = response.map;

                // start up locate widget
                var geoLocate = new LocateButton({
                    map: this.map
                }, "LocateButton");
                geoLocate.startup();

                // make sure map is loaded
                if (this.map.loaded) {
                    mapCreateDeferred.resolve();
                } else {
                    on.once(this.map, "load", lang.hitch(this, function () {
                        mapCreateDeferred.resolve();
                    }));
                }
            }), function (err) {
                mapCreateDeferred.reject((err ? ": " + err : ""));
            });

            // Once the map and its first layer are loaded, get the layer's data
            mapCreateDeferred.then(lang.hitch(this, function () {
                // At this point, this.config has been supplemented with
                // the first operational layer's layerObject
                this._mapData = new LayerAndTableMgmt(this.config);
                this._mapData.load().then(function () {
                    mapDataReadyDeferred.resolve("map data");
                }, lang.hitch(this, function (err) {
                    mapDataReadyDeferred.reject(this.config.i18n.map.layerLoad + (err ? ": " + err : ""));
                }));
            }), lang.hitch(this, function (err) {
                mapDataReadyDeferred.reject(this.config.i18n.map.layerLoad + (err ? ": " + err : ""));
            }));

            return mapDataReadyDeferred.promise;
        },

        /**
         * Hides the loading indicator and reveals the content.
         */
        _revealApp: function () {
            domClass.remove(document.body, "app-loading");
            fx.fadeIn({
                node: "contentDiv",
                duration: 1000,
                onEnd: function () {
                    domClass.remove("contentDiv", "transparent");
                }
            }).play();
        }
    });
});
<|endoftext|>


<commit_before>/*
 * -------------------------------------------
 *	$_DATA MODELS
 * -------------------------------------------
 */
var songModel = [
    {
        list: true,
        code: 'default',
        ytID_list: 'PL-4U2d6ASRHn-h6UdaKkKnaAhg2T2kxAj',
        ytID: 'j0Jb72PZAls',
        bg: 'defaultjazz2.gif'
    },
    {
        list: false,
        code: 'whisper',
        artist: 'George Michael',
        song: 'Careless Whisper',
        ytID: 'Qu2FWrEilWQ',
        start: 123,
        bg: 'jazz.gif'
    },
    {
        list: false,
        code: 'tiger',
        artist: 'Survivor',
        song: 'Eye Of The Tiger',
        ytID: 'btPJPFnesV4',
        start: 0,
        bg: 'kitten0.gif'
    }
];

/*
 * -------------------------------------------
 *	$_PRELOAD IMAGES
 * -------------------------------------------
 */
$.preloadImages = function() {
    for (var i = 0; i < arguments.length; i++) {
        $("").attr("src", arguments[i]);
    }
};

$.preloadImages(
    "img/app/rainAnim.gif",
    "img/app/fireAnim.gif",
    "img/app/jazz.gif",
    // "img/app/sexualheal.gif",
    // "img/app/shoulda.gif",
    "img/app/defaultjazz2.gif",
    // "img/app/blueeyes.gif",
    // "img/app/sunset.gif",
    // "img/app/nightlight.gif",
    //"img/app/hattip.gif",
    "img/app/kitten0.gif"
);

/*
 * -------------------------------------------
 *	$_URL PARAM LOADER
 * -------------------------------------------
 */

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

/*
 * -------------------------------------------
 *	$_AUDIO LAYER CONTROL
 * -------------------------------------------
 */
var audioLayerToggle = function(audioSource) {
    $('.wrapper_' + audioSource).click(function() {
        if ($(this).hasClass('active')) {
            document.getElementById('audio_' + audioSource).play();
        } else {
            document.getElementById('audio_' + audioSource).pause();
        }
    });
};

$('.wrapper_rain, .wrapper_fire').click(function() {
    $(this).toggleClass('active');
});

audioLayerToggle('rain');
audioLayerToggle('fire');

/*
 * -------------------------------------------
 *	$_AUDIO LAYER CONTROL
 * -------------------------------------------
 */

var ytLoad = function(videoID, listID, start) {
    $('#ytPlayer')
        .attr('src', '//www.youtube.com/embed/' + videoID +
            '?autoplay=1&loop=1&showinfo=1&rel=0&fs=0&start=' + start + '&list=' + listID);
};

// Load Default Music or Pull From URL Param
$(function() {
    var url = getParameterByName('v');
    var code = getParameterByName('code');
    var start = getParameterByName('start');
    if (url !== "" ) {
        ytLoad(url, '', start);
    } else if (code !== "") {
        chooseSong(code);
    } else {
        chooseSong('default');
    }
});

// Load Presets To Page
$(function() {
    var d = songModel;
    for(var i = 0; i < d.length; i++) {
        if(d[i].list == false)
        {
            $('.presets').append(
                    '' +
                        '' + d[i].song + '' +
                        ' by ' + d[i].artist +
                        '');
        }
    }
    $('.presets a').on('click', function(){
        chooseSong($(this).data('song'));
    });
});

/*
 * -------------------------------------------
 *	$_SONG CONTROL
 * -------------------------------------------
 */

// Load Preset Songs
function chooseSong(code, start) {
    var listID = '';
    var d = songModel;
    for(var i = 0; i < d.length; i++) {
        if(d[i].code == code)
        {
            if (d[i].list === true) {
                listID = d[i].ytID_list;
            }
            if (d[i].start !== undefined) {
                start = d[i].start;
            }
            if (d[i].bg !== undefined) {
                $('.bgOverlay').css('background-image', 'url(img/app/' + d[i].bg + ')');
            }
            ytLoad(d[i].ytID, listID, start);
            console.log('Loaded Song. Starting at ' + start + ' seconds.');
            return true;
        }
    }
}<commit_msg>Fixed the jazz link<commit_after>/*
 * -------------------------------------------
 *	$_DATA MODELS
 * -------------------------------------------
 */
var songModel = [
    {
        list: true,
        code: 'default',
        ytID_list: 'PL8F6B0753B2CCA128',
        ytID: 'YmtHdBPzi_w',
        start: 0,
        bg: 'defaultjazz2.gif'
    },
    {
        list: false,
        code: 'whisper',
        artist: 'George Michael',
        song: 'Careless Whisper',
        ytID: 'Qu2FWrEilWQ',
        start: 123,
        bg: 'jazz.gif'
    },
    {
        list: false,
        code: 'tiger',
        artist: 'Survivor',
        song: 'Eye Of The Tiger',
        ytID: 'QEjgPh4SEmU',
        start: 5,
        bg: 'kitten0.gif'
    }
];

/*
 * -------------------------------------------
 *	$_PRELOAD IMAGES
 * -------------------------------------------
 */
$.preloadImages = function() {
    for (var i = 0; i < arguments.length; i++) {
        $("").attr("src", arguments[i]);
    }
};

$.preloadImages(
    "img/app/rainAnim.gif",
    "img/app/fireAnim.gif",
    "img/app/jazz.gif",
    // "img/app/sexualheal.gif",
    // "img/app/shoulda.gif",
    "img/app/defaultjazz2.gif",
    // "img/app/blueeyes.gif",
    // "img/app/sunset.gif",
    // "img/app/nightlight.gif",
    //"img/app/hattip.gif",
    "img/app/kitten0.gif"
);

/*
 * -------------------------------------------
 *	$_URL PARAM LOADER
 * -------------------------------------------
 */

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

/*
 * -------------------------------------------
 *	$_AUDIO LAYER CONTROL
 * -------------------------------------------
 */
var audioLayerToggle = function(audioSource) {
    $('.wrapper_' + audioSource).click(function() {
        if ($(this).hasClass('active')) {
            document.getElementById('audio_' + audioSource).play();
        } else {
            document.getElementById('audio_' + audioSource).pause();
        }
    });
};

$('.wrapper_rain, .wrapper_fire').click(function() {
    $(this).toggleClass('active');
});

audioLayerToggle('rain');
audioLayerToggle('fire');

/*
 * -------------------------------------------
 *	$_AUDIO LAYER CONTROL
 * -------------------------------------------
 */

var ytLoad = function(videoID, listID, start) {
    $('#ytPlayer')
        .attr('src', '//www.youtube.com/embed/' + videoID +
            '?autoplay=1&loop=1&showinfo=1&rel=0&fs=0&start=' + start + '&list=' + listID);
};

// Load Default Music or Pull From URL Param
$(function() {
    var url = getParameterByName('v');
    var code = getParameterByName('code');
    var start = getParameterByName('start');
    if (url !== "" ) {
        ytLoad(url, '', start);
    } else if (code !== "") {
        chooseSong(code);
    } else {
        chooseSong('default');
    }
});

// Load Presets To Page
$(function() {
    var d = songModel;
    for(var i = 0; i < d.length; i++) {
        if(d[i].list == false)
        {
            $('.presets').append(
                    '' +
                        '' + d[i].song + '' +
                        ' by ' + d[i].artist +
                        '');
        }
    }
    $('.presets a').on('click', function(){
        chooseSong($(this).data('song'));
    });
});

/*
 * -------------------------------------------
 *	$_SONG CONTROL
 * -------------------------------------------
 */

// Load Preset Songs
function chooseSong(code, start) {
    var listID = '';
    var d = songModel;
    for(var i = 0; i < d.length; i++) {
        if(d[i].code == code)
        {
            if (d[i].list === true) {
                listID = d[i].ytID_list;
            }
            if (d[i].start !== undefined) {
                start = d[i].start;
            }
            if (d[i].bg !== undefined) {
                $('.bgOverlay').css('background-image', 'url(img/app/' + d[i].bg + ')');
            }
            ytLoad(d[i].ytID, listID, start);
            console.log('Loaded Song. Starting at ' + start + ' seconds.');
            return true;
        }
    }
}<|endoftext|>


<commit_before>/* jshint browser: true, devel: true, indent: 2, curly: true, eqeqeq: true, futurehostile: true, latedef: true, undef: true, unused: true */
/* global $, jQuery, document, Modernizr */

$(document).ready(function () {
  'use strict';

  var lookbook = $('#lookbook'),
    winHeight = $(window).height(),
    winWidth = $(window).width(),
    header = $('#header'),
    footer = $('#footer'),
    headerHeight = header.outerHeight(true),
    footerHeight = footer.outerHeight(true),
    lookbookHeight,
    lookbookWidth;

  if (winWidth > winHeight) {
    lookbookHeight = ( winHeight - ( headerHeight + footerHeight ) );
    lookbookWidth = ( ( lookbookHeight * 0.707 ) * 2 );
  } else {
    lookbookWidth = ( winWidth * 0.9 );
    lookbookHeight = ( lookbookWidth * 1.414 ) / 2;
  }

  lookbook.css({
    'margin-top': ( ( winHeight - lookbookHeight ) / 2 ),
    'margin-left': ( ( winWidth - lookbookWidth ) / 2 ),
  }).turn({
    height: lookbookHeight,
    width: lookbookWidth,
    autoCenter: false,
    gradients: true,
  });

  $(window).on('resize', function(){
    winHeight = $(window).height();
    winWidth = $(window).width();
    headerHeight = header.outerHeight(true);
    footerHeight = footer.outerHeight(true);

    if (winWidth > winHeight) {
      lookbookHeight = ( winHeight - ( headerHeight + footerHeight ) );
      lookbookWidth = ( ( lookbookHeight * 0.707 ) * 2 );
    } else {
      lookbookWidth = ( winWidth * 0.9 );
      lookbookHeight = ( lookbookWidth * 1.414 ) / 2;
    }

    lookbook.css({
      'margin-top': ( ( winHeight - lookbookHeight ) / 2 ),
      'margin-left': ( ( winWidth - lookbookWidth ) / 2 ),
    }).turn('size', lookbookWidth, lookbookHeight);
  });

});
<commit_msg>add images loaded<commit_after>/* jshint browser: true, devel: true, indent: 2, curly: true, eqeqeq: true, futurehostile: true, latedef: true, undef: true, unused: true */
/* global $, jQuery, document, Modernizr */

$(document).ready(function () {
  'use strict';

  var lookbook = $('#lookbook'),
    winHeight = $(window).height(),
    winWidth = $(window).width(),
    header = $('#header'),
    footer = $('#footer'),
    headerHeight = header.outerHeight(true),
    footerHeight = footer.outerHeight(true),
    lookbookHeight,
    lookbookWidth;

  if (winWidth > winHeight) {
    lookbookHeight = ( winHeight - ( headerHeight + footerHeight ) );
    lookbookWidth = ( ( lookbookHeight * 0.707 ) * 2 );
  } else {
    lookbookWidth = ( winWidth * 0.9 );
    lookbookHeight = ( lookbookWidth * 1.414 ) / 2;
  }

  lookbook.css({
    'margin-top': ( ( winHeight - lookbookHeight ) / 2 ),
    'margin-left': ( ( winWidth - lookbookWidth ) / 2 ),
  }).turn({
    height: lookbookHeight,
    width: lookbookWidth,
    autoCenter: false,
    gradients: true,
  });

  $('#lookbook-container').imagesLoaded( function() {
    console.log('loaded');
    $('#lookbook-container').css('opacity',1);
  });

  $(window).on('resize', function(){
    winHeight = $(window).height();
    winWidth = $(window).width();
    headerHeight = header.outerHeight(true);
    footerHeight = footer.outerHeight(true);

    if (winWidth > winHeight) {
      lookbookHeight = ( winHeight - ( headerHeight + footerHeight ) );
      lookbookWidth = ( ( lookbookHeight * 0.707 ) * 2 );
    } else {
      lookbookWidth = ( winWidth * 0.9 );
      lookbookHeight = ( lookbookWidth * 1.414 ) / 2;
    }

    lookbook.css({
      'margin-top': ( ( winHeight - lookbookHeight ) / 2 ),
      'margin-left': ( ( winWidth - lookbookWidth ) / 2 ),
    }).turn('size', lookbookWidth, lookbookHeight);
  });

});
<|endoftext|>


<commit_before>// A $( document ).ready() block.
$( document ).ready(function() {

	console.log('Doc Ready().');

});<commit_msg>PHPDoc2 / ST2 code formating only.<commit_after>// A $( document ).ready() block.
$(document).ready(function() {

	console.log('Doc Ready().');

});<|endoftext|>


<commit_before>///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
$(document).ready(function() {
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
  var twitchUserName = ['sblindside','frogsama','vvarrenstudios',"thenutzxd",'jamaica105','michiganspartan','ritterriffic','kazzandrah','vexnextv','stonertrixx'];

///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////

  //Iterate through the array of usernames and call getTwitch
  twitchUserName.forEach(function(name) {
    getTwitch(name)
  });
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
  //Activate Nav Pills
  $(".selector").click(function() {
		var status = $(this).attr('id');
		if (status === "all-streams") {
			$(".online, .offline").show();
		} else if (status === "online") {
			$(".online").show();
			$(".offline").hide();
		} else {
			$(".offline").show();
			$(".online").hide();
		}
	})
  //Add Video to Top
  $('.card-link').click(function(){
		var iframeSrc = $(this).attr('src', video);
	})
});

//GET TWITCH API INFO
  function getTwitch(twitchUserName){
    $.ajax({
      type:"GET",
      url:"https://api.twitch.tv/kraken/streams/" + twitchUserName,
      headers:{
        'Client-ID': 'dhtxhmg8vey6qz5y964c3u15vmcssa'
      },
      success: function twitchData(data) {
        // Call 'streams' and if the channel is active, get stream data
        if(data.stream !== null){

          var streamImage = data.stream.preview.large;
          var streamGame = data.stream.game;
          var streamInfo = data.stream.channel.status;
          var streamLogo = data.stream.channel.logo;
          var streamURL = 'http://www.twitch.tv/'+ twitchUserName;
          var streamCard=" ";

          //IF EVERYTHING IS A SUCCESS IT BUILDS A STREAMCARD//

          streamCard = "
" + "
" + "ONLINE" + "
" + "" + '
' + "
" + "
" + twitchUserName.toUpperCase() + "

" + streamGame.toUpperCase() + ": " + streamInfo.toUpperCase() + "

";
          $(".card-container").append(streamCard);
       } else {
          // If the channel is offline, get channel data
          $.ajax({
            type:"GET",
            url:"https://api.twitch.tv/kraken/channels/" + twitchUserName,
            headers:{
              'Client-ID': 'dhtxhmg8vey6qz5y964c3u15vmcssa'
      },
            success: function(data){
              var streamBanner = data.video_banner;
              var streamLogo = data.logo;
              var streamError = data.status;
              var streamURL = 'http://www.twitch.tv/'+ twitchUserName;
              var streamCard = " ";

              //IF THERE IS NO CHANNEL INFO
              if (streamError == 404 || streamBanner == null || streamLogo == null){
                $.ajax({
                  type:"GET",
                  url:"https://api.twitch.tv/kraken/users/" + twitchUserName,
                  headers:{
                    'Client-ID': 'dhtxhmg8vey6qz5y964c3u15vmcssa'
      },
                  success: function(data){
                    var streamMessage = data.error;
                    // var streamBanner = data.video_banner;
                    var defaultImage = "https://media.giphy.com/media/l3q31122uBsO7hpmw/source.gif";
                    var defaultThumb = "https://media.giphy.com/media/l3q31122uBsO7hpmw/source.gif";
                    //IF ACCOUNT HAS BEEN CLOSED BUILD STREAMCARD
                    if(streamMessage == "Unprocessable Entity"){
                      streamCard = "
" + "
" + "OFFLINE" + "
" + "" + '
' + "
" + "
" + twitchUserName.toUpperCase() + "

This Twitch account has been closed.

";
                      $(".card-container").append(streamCard);
		                } else if (streamMessage == "Not Found"){
                        //IF IT NEVER EXISTED
                        streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

This Twitch account never existed.

";
                        $(".card-container").append(streamCard);
                    }else if (streamBanner == null && streamLogo == null){
                        //IF Banner AND  Logo don't Work
                        streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

Not currently streaming.

";
                        $(".card-container").append(streamCard);
                    }
                    else if (streamBanner == null){
                        //IF Banner Doesn't Exist
                        streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

Not currently streaming.

";
                        $(".card-container").append(streamCard);
                    }
                  }
                })
              } else { // If account exists, but user is not currently streaming, build streamCard

                streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

Not currently streaming.

";
                $(".card-container").append(streamCard);
              }
            }
          })
        }
      }
    })

  }
<commit_msg>Update main.js<commit_after>///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
$(document).ready(function() {
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
  var twitchUserName = ['johanmoney','sblindside','frogsama','vvarrenstudios',"thenutzxd",'jamaica105','michiganspartan','ritterriffic','kazzandrah','vexnextv','stonertrixx'];

///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////

  //Iterate through the array of usernames and call getTwitch
  twitchUserName.forEach(function(name) {
    getTwitch(name)
  });
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
  //Activate Nav Pills
  $(".selector").click(function() {
		var status = $(this).attr('id');
		if (status === "all-streams") {
			$(".online, .offline").show();
		} else if (status === "online") {
			$(".online").show();
			$(".offline").hide();
		} else {
			$(".offline").show();
			$(".online").hide();
		}
	})
  //Add Video to Top
  $('.card-link').click(function(){
		var iframeSrc = $(this).attr('src', video);
	})
});

//GET TWITCH API INFO
  function getTwitch(twitchUserName){
    $.ajax({
      type:"GET",
      url:"https://api.twitch.tv/kraken/streams/" + twitchUserName,
      headers:{
        'Client-ID': 'dhtxhmg8vey6qz5y964c3u15vmcssa'
      },
      success: function twitchData(data) {
        // Call 'streams' and if the channel is active, get stream data
        if(data.stream !== null){

          var streamImage = data.stream.preview.large;
          var streamGame = data.stream.game;
          var streamInfo = data.stream.channel.status;
          var streamLogo = data.stream.channel.logo;
          var streamURL = 'http://www.twitch.tv/'+ twitchUserName;
          var streamCard=" ";

          //IF EVERYTHING IS A SUCCESS IT BUILDS A STREAMCARD//

          streamCard = "
" + "
" + "ONLINE" + "
" + "" + '
' + "
" + "
" + twitchUserName.toUpperCase() + "

" + streamGame.toUpperCase() + ": " + streamInfo.toUpperCase() + "

";
          $(".card-container").append(streamCard);
       } else {
          // If the channel is offline, get channel data
          $.ajax({
            type:"GET",
            url:"https://api.twitch.tv/kraken/channels/" + twitchUserName,
            headers:{
              'Client-ID': 'dhtxhmg8vey6qz5y964c3u15vmcssa'
      },
            success: function(data){
              var streamBanner = data.video_banner;
              var streamLogo = data.logo;
              var streamError = data.status;
              var streamURL = 'http://www.twitch.tv/'+ twitchUserName;
              var streamCard = " ";

              //IF THERE IS NO CHANNEL INFO
              if (streamError == 404 || streamBanner == null || streamLogo == null){
                $.ajax({
                  type:"GET",
                  url:"https://api.twitch.tv/kraken/users/" + twitchUserName,
                  headers:{
                    'Client-ID': 'dhtxhmg8vey6qz5y964c3u15vmcssa'
      },
                  success: function(data){
                    var streamMessage = data.error;
                    // var streamBanner = data.video_banner;
                    var defaultImage = "https://media.giphy.com/media/l3q31122uBsO7hpmw/source.gif";
                    var defaultThumb = "https://media.giphy.com/media/l3q31122uBsO7hpmw/source.gif";
                    //IF ACCOUNT HAS BEEN CLOSED BUILD STREAMCARD
                    if(streamMessage == "Unprocessable Entity"){
                      streamCard = "
" + "
" + "OFFLINE" + "
" + "" + '
' + "
" + "
" + twitchUserName.toUpperCase() + "

This Twitch account has been closed.

";
                      $(".card-container").append(streamCard);
		                } else if (streamMessage == "Not Found"){
                        //IF IT NEVER EXISTED
                        streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

This Twitch account never existed.

";
                        $(".card-container").append(streamCard);
                    }else if (streamBanner == null && streamLogo == null){
                        //IF Banner AND  Logo don't Work
                        streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

Not currently streaming.

";
                        $(".card-container").append(streamCard);
                    }
                    else if (streamBanner == null){
                        //IF Banner Doesn't Exist
                        streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

Not currently streaming.

";
                        $(".card-container").append(streamCard);
                    }
                  }
                })
              } else { // If account exists, but user is not currently streaming, build streamCard

                streamCard = "
" + "
" + "OFFLINE" + "
" + ""+ '
' + "
" + "
" + twitchUserName.toUpperCase() + "

Not currently streaming.

";
                $(".card-container").append(streamCard);
              }
            }
          })
        }
      }
    })

  }
<|endoftext|>


<commit_before>// use strict;
var mouse = {
    x: 0,
    y: 0
};
var mouseClick = false;
var currentElement = null;
var body = document.getElementsByTagName('body')[0];

function mouseTooltip(e) {

    mouse.x = e.clientX || e.pageX;
    mouse.y = e.clientY || e.pageY;
    console.log(">>"+mouseClick+"<<");
    if (mouseClick === true) return;
    currentElement = document.elementFromPoint(mouse.x, mouse.y);
    console.log(currentElement);
    var content = "";

    for (var i = 0, atts = currentElement.attributes, n = atts.length, arr = []; i < n; i++) {
        content += atts[i].nodeName + " : <input type='text' name=" + atts[i].nodeName + " value= ' "  + atts[i].value + "'>
";
    }
    content += "innerTexture : <input type='text' name='innerText' value='" + currentElement.innerText + "'>
";
    currentElement.innerHTML += " " + content + "";
    for (var i = 0, atts = currentElement.attributes, n = atts.length, arr = []; i < n; i++) {
        var node = atts[i];
        document.getElementsByName(node.nodeName)[0].onchange = function(e) {
            console.log(e.srcElement.value);
            currentElement.setAttribute(e.srcElement.name, e.srcElement.value);
        }
    }
    document.getElementsByName("innerText")[0].onchange = function(e) {
        currentElement.innerText = document.getElementsByName("innerText")[0].value;
        mouseClick = false;
    }
    mouseClick = true;
    document.getElementsByClassName('coupontooltip')[0].ondblclick = function() {
        document.getElementsByClassName('coupontooltip')[0].remove();
        mouseClick = false;
    }
}
document.onmousedown = mouseTooltip;
<commit_msg>beta 1.0<commit_after>// use strict;
var mouse = {
    x: 0,
    y: 0
};
var mouseClick = false;
var currentElement = null;
var body = document.getElementsByTagName('body')[0];

function mouseTooltip(e) {

    mouse.x = e.clientX || e.pageX;
    mouse.y = e.clientY || e.pageY;
    console.log(">>x:"+mouse.x+"y:"+mouse.y+"<<");
    if (mouseClick === true) return;
    currentElement = document.elementFromPoint(mouse.x, mouse.y);
    // console.log(currentElement);
    var content = "";

    var span = document.createElement('span');
    span.setAttribute("class","coupontooltip");
    document.body.appendChild(span);

    span.style.top=mouse.y;
    span.style.left=mouse.x;
    for (var i = 0, atts = currentElement.attributes, n = atts.length, arr = []; i < n; i++) {
        span.innerHTML+=atts[i].nodeName + " : <input type='text' name=" + atts[i].nodeName + " value= ' "  + atts[i].value + "'>
";
        //  document.getElementsByName(atts[i].nodeName)[0].onchange = function(e) {
        //     currentElement.setAttribute(e.srcElement.name, e.srcElement.value);
        // }
    }
    span.innerHTML+= "innerTexture : <input type='text' name='innerText' value='" + currentElement.innerText + "'>
";
    document.getElementsByName("innerText")[0].onchange = function(e) {
        currentElement.innerText = document.getElementsByName("innerText")[0].value;
        mouseClick = false;
    }
    currentElement.parentElement.innerHTML += " " + content + "";
    for (var i = 0, atts = currentElement.attributes, n = atts.length, arr = []; i < n; i++) {
        var node = atts[i];
        document.getElementsByName(node.nodeName)[0].onchange = function(e) {
            currentElement.setAttribute(e.srcElement.name, e.srcElement.value);
        }
    }
    // document.getElementsByName("innerText")[0].onchange = function(e) {
    //     currentElement.innerText = document.getElementsByName("innerText")[0].value;
    //     mouseClick = false;
    // }
    mouseClick = true;
    document.getElementsByClassName('coupontooltip')[0].ondblclick = function() {
        document.getElementsByClassName('coupontooltip')[0].remove();
        mouseClick = false;
    }
}
document.onmousedown = mouseTooltip;
<|endoftext|>


<commit_before>(function () {
    var hostname = 'http://wordpress.eightrayedsun.com'; //Replace with your hostname;
    var authorization = "" // Your username:password on base64
    var apiEndpoints = {
        posts: '/wp-json/wp/v2/posts?filter[posts_per_page]=-1',
        comments: '/wp-json/wp/v2/comments?filter[posts_per_page]=-1',
        categories: '/wp-json/wp/v2/categories',
        post: '/wp-json/wp/v2/posts/',
        tags: '/wp-json/wp/v2/tags',
        category: '/wp-json/wp/v2/posts?categories='
    }
    const Home = { template: '<post-list apiUrl="posts"/>' }
    const Post = { template: '<post-item v-bind:postId="$route.query.postId" />' }
    const Comments = { template: '<comment-list v-bind:postId="$route.query.postID" />' }
    const Categories = {
        template: '<post-list apiUrl="category" />',
        watch:{
            '$route'(to, from){
            //    console.log(to.path);
            router.forward(to.path);

            }
        }

    }

    const routes = [
        { path: '/', component: Home },
        {
            path: '/post',
            name: 'post',
            component: Post
        },
        {
            path: '/comments',
            name: 'comments',
            component: Comments
        },{
            path: '/post/category/:id',
            name: 'category',
            component: Categories
        }
    ]

    const router = new VueRouter({
        routes
    })

    Vue.component('post-list', {
        template: `

                        <router-link :to="{path: '/post', query: {postId: post.id}}">Read More</router-link>

            `,
        props: ['apiUrl'],
        data: function () {
            return {
                posts: ''
            }
        },
        methods: {
            getPosts: function () {
                var componentThis = this;
                var urlString = hostname + apiEndpoints['posts'];
                if(this.apiUrl !== 'posts'){
                    var id = this.$route.params.id;
                    urlString = hostname + apiEndpoints[this.apiUrl]+id;
                }

                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: urlString

                }).success(function (data) { componentThis.posts = data; })
            },
        },
        mounted: function () {
            this.getPosts();
        }
    })

    Vue.component('post-item', {
        template: `

{{date}}

                        <router-link :to="{path: 'comments', query: {postID: postId}}">Read Comments</router-link>
                        <router-view></router-view>

            `,
        props: ['postId'],
        data: function () {
            return {
                date: '',
                title: '',
                content: '',
                comments: '',
            }
        },
        methods: {
            getPost: function () {
                var componentThis = this;
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.post + componentThis.postId
                }).success(function (data) {
                    componentThis.date = data.date;
                    componentThis.title = data.title.rendered;
                    componentThis.content = data.content.rendered;
                })
            },

        },
        mounted: function () {
            this.getPost();
        }
    })

    Vue.component('comment-list', {
        template: `

Comments:

{{comment.author_name}} :

        `,
        props: ['postId'],
        data: function () {
            return {
                comments: ''
            }
        },
        methods: {
            getComments: function () {
                var componentThis = this;
                var jsondata = '';
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.comments
                }).success(function (data) { jsondata = data; componentThis.comments = data });
            },
        },
        mounted: function () {
            this.getComments();
        }
    })

    Vue.component('categories-list', {
        template: `

Categories

<router-link :to="{name: 'category', params: {id: category.id}}">{{category.name}}</router-link>

        `,
        data: function () {
            return {
                categories: ''
            }
        },
        methods: {
            getCategories: function () {
                var componentThis = this;
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.categories
                }).success(function (data) { componentThis.categories = data });
            }
        },
        mounted: function () {
            this.getCategories();
        }
    })

    Vue.component('tag-list', {
        template: `

Tags

{{tag.name}}

        `,
        data: function () {
            return {
                tags: ''
            }
        },
        methods: {
            getTags: function () {
                var componentThis = this;
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.tags
                }).success(function (data) { componentThis.tags = data });
            }
        },
        mounted: function () {
            this.getTags();
        }
    })

    var app = new Vue({
        el: "#app",
        router,
        data: {
            posts: ''
        },
        methods:{
            test : function(){
                alert('test');
            },
            getPosts(apiUrl){
                var componentThis = this;
                var urlString = hostname + apiEndpoints['posts'];
                if(this.apiUrl !== 'posts'){
                    var id = this.$route.params.id;
                    urlString = hostname + apiEndpoints[this.apiUrl]+id;
                }
                console.log(urlString);
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: urlString

                }).success(function (data) { componentThis.posts = data; })
            }
        }
    });
})();
<commit_msg>Remove hostname<commit_after>(function () {
    var hostname = ''; //Replace with your hostname;
    var authorization = "" // Your username:password on base64
    var apiEndpoints = {
        posts: '/wp-json/wp/v2/posts?filter[posts_per_page]=-1',
        comments: '/wp-json/wp/v2/comments?filter[posts_per_page]=-1',
        categories: '/wp-json/wp/v2/categories',
        post: '/wp-json/wp/v2/posts/',
        tags: '/wp-json/wp/v2/tags',
        category: '/wp-json/wp/v2/posts?categories='
    }
    const Home = { template: '<post-list apiUrl="posts"/>' }
    const Post = { template: '<post-item v-bind:postId="$route.query.postId" />' }
    const Comments = { template: '<comment-list v-bind:postId="$route.query.postID" />' }
    const Categories = {
        template: '<post-list apiUrl="category" />',
        watch:{
            '$route'(to, from){
            //    console.log(to.path);
            router.forward(to.path);

            }
        }

    }

    const routes = [
        { path: '/', component: Home },
        {
            path: '/post',
            name: 'post',
            component: Post
        },
        {
            path: '/comments',
            name: 'comments',
            component: Comments
        },{
            path: '/post/category/:id',
            name: 'category',
            component: Categories
        }
    ]

    const router = new VueRouter({
        routes
    })

    Vue.component('post-list', {
        template: `

                        <router-link :to="{path: '/post', query: {postId: post.id}}">Read More</router-link>

            `,
        props: ['apiUrl'],
        data: function () {
            return {
                posts: ''
            }
        },
        methods: {
            getPosts: function () {
                var componentThis = this;
                var urlString = hostname + apiEndpoints['posts'];
                if(this.apiUrl !== 'posts'){
                    var id = this.$route.params.id;
                    urlString = hostname + apiEndpoints[this.apiUrl]+id;
                }

                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: urlString

                }).success(function (data) { componentThis.posts = data; })
            },
        },
        mounted: function () {
            this.getPosts();
        }
    })

    Vue.component('post-item', {
        template: `

{{date}}

                        <router-link :to="{path: 'comments', query: {postID: postId}}">Read Comments</router-link>
                        <router-view></router-view>

            `,
        props: ['postId'],
        data: function () {
            return {
                date: '',
                title: '',
                content: '',
                comments: '',
            }
        },
        methods: {
            getPost: function () {
                var componentThis = this;
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.post + componentThis.postId
                }).success(function (data) {
                    componentThis.date = data.date;
                    componentThis.title = data.title.rendered;
                    componentThis.content = data.content.rendered;
                })
            },

        },
        mounted: function () {
            this.getPost();
        }
    })

    Vue.component('comment-list', {
        template: `

Comments:

{{comment.author_name}} :

        `,
        props: ['postId'],
        data: function () {
            return {
                comments: ''
            }
        },
        methods: {
            getComments: function () {
                var componentThis = this;
                var jsondata = '';
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.comments
                }).success(function (data) { jsondata = data; componentThis.comments = data });
            },
        },
        mounted: function () {
            this.getComments();
        }
    })

    Vue.component('categories-list', {
        template: `

Categories

<router-link :to="{name: 'category', params: {id: category.id}}">{{category.name}}</router-link>

        `,
        data: function () {
            return {
                categories: ''
            }
        },
        methods: {
            getCategories: function () {
                var componentThis = this;
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.categories
                }).success(function (data) { componentThis.categories = data });
            }
        },
        mounted: function () {
            this.getCategories();
        }
    })

    Vue.component('tag-list', {
        template: `

Tags

{{tag.name}}

        `,
        data: function () {
            return {
                tags: ''
            }
        },
        methods: {
            getTags: function () {
                var componentThis = this;
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: hostname + apiEndpoints.tags
                }).success(function (data) { componentThis.tags = data });
            }
        },
        mounted: function () {
            this.getTags();
        }
    })

    var app = new Vue({
        el: "#app",
        router,
        data: {
            posts: ''
        },
        methods:{
            test : function(){
                alert('test');
            },
            getPosts(apiUrl){
                var componentThis = this;
                var urlString = hostname + apiEndpoints['posts'];
                if(this.apiUrl !== 'posts'){
                    var id = this.$route.params.id;
                    urlString = hostname + apiEndpoints[this.apiUrl]+id;
                }
                console.log(urlString);
                $.ajax({
                    headers: {
                        "Authorization": "Basic " + authorization
                    },
                    url: urlString

                }).success(function (data) { componentThis.posts = data; })
            }
        }
    });
})();
<|endoftext|>


<commit_before>(function() {
  // rAF
  window.requestAnimationFrame = function() {
    return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      function(f) {
        window.setTimeout(f,1e3/60);
      }
  }();

  window.mit = window.mit || {};

  var config = mit.config = {
    fork_count: 6
  };

  var ui = mit.ui = {
    body: $('body'),
    score_board: $('#score_board'),
    start_screen: $('#start_screen'),
    start_game: $('#start_game'),
    tweet: $('#tweet'),
    fb: $('#fb')
  };

  /*
  Basic Canvas Inits
  */

  // Main Canvas

  var canvas = document.querySelector('#game_main');
  var ctx = canvas.getContext('2d');

  var W = canvas.width = ui.body.width();
  var H = canvas.height = ui.body.height();

  // Width x Height capped to 1000 x 500
  if (canvas.width > 1000) {
    W = canvas.width = 1000;
  }
  if (canvas.height > 500) {
    H = canvas.height = 500;
  }

  // Resizing Width/Height
  if (canvas.height < 500) {
    canvas.width = canvas.height * 1000/500;
  }
  if (canvas.width < 1000) {
    canvas.height = canvas.width * 500/1000;
  }

  // BG Canvas
  var bg_canvas = document.querySelector('#game_bg');
  var bg_ctx = bg_canvas.getContext('2d');

  bg_canvas.width = canvas.width;
  bg_canvas.height = canvas.height;

  /*
    Game Start Screen and Lolz
  */
  mit.game_started = 0;
  mit.game_over = 0;
  mit.start_btn_clicked = 0;

  ui.start_screen.css('width', canvas.width + 'px');
  ui.start_screen.css('height', canvas.height + 'px');

  // Start Button
  ui.start_game.on('mousedown', function() {
    ui.start_screen.fadeOut();

    mit.start_btn_clicked = 1;
    mit.game_started = 0;

    mit.pappu.drawStatic(ctx);
    ax = 0; ay = 0;
    vx = 0; vy = 0;

    return false;
  });

  var score = 0;

  ui.score_board.css('width', canvas.width + 'px');
  ui.score_board.css('height', canvas.height + 'px');

  // Set Canvas Width/Height in Config
  mit.config.canvas_width = W;
  mit.config.canvas_height = H;

  // Gravity
  var gravity = mit.gravity = 0.2;

  // Velocity x,y
  var vx = 0;
  var vy = 0;

  // Velocity cap on either sides of the
  // number system.
  //
  // You can console.log velocities in drawing methods
  // and from there decide what to set as the cap.
  var v_cap = 4;

  // Accelaration x,y
  var ax = 0;
  var ay = 0;

  // Flying up ?
  var flying_up = 0;

  // Key Events
  window.addEventListener('keydown', function(e) {
    if (!mit.start_btn_clicked)
      return;

    switch (e.keyCode) {
      // Left
      //case 37:
      //  ax = -0.4;
      //  break;

      // Right
      //case 39:
      //  ax = 0.4;
      //  break;

      // Up
      case 38:
        ay = -0.4;
        break;

      // Down
      case 40:
        ay = 0.4;
        break;
    }

  }, false);

  window.addEventListener('keyup', function(e) {
    if (!mit.start_btn_clicked)
      return;

    ax = 0;
    ay = 0;
  }, false);

  // Game play on mouse clicks too!
  window.addEventListener('mousedown', function(e) {
    if (!mit.start_btn_clicked)
      return;

    if (!mit.game_started)
      mit.game_started = 1;

    ay = -0.4;
    flying_up = 1;
  }, false);

  window.addEventListener('mouseup', function(e) {
    if (!mit.start_btn_clicked)
      return;

    ay = 0;
    flying_up = 0;
  }, false);

  /*
    Performing some game over tasks
  */
  var gameOver = function() {
    ui.start_screen.fadeIn();
    ui.start_game.html('re-start');
    ui.tweet.html('tweet score');
    ui.fb.html('post on fb');

    mit.game_over = 1;
    mit.start_btn_clicked = 0;
  };

  (function renderGame() {
    window.requestAnimationFrame(renderGame);

    // Draw Backgrounds on BG Canvas
    mit.backgrounds.draw(bg_ctx);

    ctx.clearRect(0, 0, W, H);

    // Draw Digs (holds forks)
    // I am fine without Digs, but Kushagra
    // just WANTS me to do this extra work :/
    mit.forks.drawDigs(ctx);

    // Draw Grass on Main Canvas
    mit.backgrounds.drawGrass(ctx);

    if (flying_up)
      mit.pappu.updateFlyFrameCount();
    else
      mit.pappu.updateFlyFrameCount(0);

    // Draw Forks
    mit.forks.draw(ctx, 6);
    // Draw Branches
    mit.branches.draw(ctx, 4);

    // Game over on reaching any boundary
    if (mit.pappu.hasReachedBoundary(W, H)) {
      // Performing some game over tasks
      gameOver();
      return;
    }

    if (mit.game_started) {

      // Update score
      score = score + 0.2;
      ui.score_board.text(parseInt(score));

      // Acceleration + Gravity
      // ay = ay + gravity;

      // Velocity
      if (
        (vy < v_cap && ay+gravity > 0) ||
        (vy > -v_cap && ay+gravity < 0)
        ) {

        vy += ay;
        vy += gravity;
      }

      // console.log(vy, ay)

      mit.pappu.x += vx;
      mit.pappu.y += vy;

      mit.pappu.draw(ctx);
    }
    else {
      mit.pappu.drawStatic(ctx);
    }

  }());

}());<commit_msg>show forks on game start<commit_after>(function() {
  // rAF
  window.requestAnimationFrame = function() {
    return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      function(f) {
        window.setTimeout(f,1e3/60);
      }
  }();

  window.mit = window.mit || {};

  var config = mit.config = {
    fork_count: 6
  };

  var ui = mit.ui = {
    body: $('body'),
    score_board: $('#score_board'),
    start_screen: $('#start_screen'),
    start_game: $('#start_game'),
    tweet: $('#tweet'),
    fb: $('#fb')
  };

  /*
  Basic Canvas Inits
  */

  // Main Canvas

  var canvas = document.querySelector('#game_main');
  var ctx = canvas.getContext('2d');

  var W = canvas.width = ui.body.width();
  var H = canvas.height = ui.body.height();

  // Width x Height capped to 1000 x 500
  if (canvas.width > 1000) {
    W = canvas.width = 1000;
  }
  if (canvas.height > 500) {
    H = canvas.height = 500;
  }

  // Resizing Width/Height
  if (canvas.height < 500) {
    canvas.width = canvas.height * 1000/500;
  }
  if (canvas.width < 1000) {
    canvas.height = canvas.width * 500/1000;
  }

  // BG Canvas
  var bg_canvas = document.querySelector('#game_bg');
  var bg_ctx = bg_canvas.getContext('2d');

  bg_canvas.width = canvas.width;
  bg_canvas.height = canvas.height;

  /*
    Game Start Screen and Lolz
  */
  mit.game_started = 0;
  mit.game_over = 0;
  mit.start_btn_clicked = 0;

  ui.start_screen.css('width', canvas.width + 'px');
  ui.start_screen.css('height', canvas.height + 'px');

  // Start Button
  ui.start_game.on('mousedown', function() {
    ui.start_screen.fadeOut();

    mit.start_btn_clicked = 1;
    mit.game_started = 0;

    mit.pappu.drawStatic(ctx);
    ax = 0; ay = 0;
    vx = 0; vy = 0;

    return false;
  });

  var score = 0;

  ui.score_board.css('width', canvas.width + 'px');
  ui.score_board.css('height', canvas.height + 'px');

  // Set Canvas Width/Height in Config
  mit.config.canvas_width = W;
  mit.config.canvas_height = H;

  // Gravity
  var gravity = mit.gravity = 0.2;

  // Velocity x,y
  var vx = 0;
  var vy = 0;

  // Velocity cap on either sides of the
  // number system.
  //
  // You can console.log velocities in drawing methods
  // and from there decide what to set as the cap.
  var v_cap = 4;

  // Accelaration x,y
  var ax = 0;
  var ay = 0;

  // Flying up ?
  var flying_up = 0;

  // Key Events
  window.addEventListener('keydown', function(e) {
    if (!mit.start_btn_clicked)
      return;

    switch (e.keyCode) {
      // Left
      //case 37:
      //  ax = -0.4;
      //  break;

      // Right
      //case 39:
      //  ax = 0.4;
      //  break;

      // Up
      case 38:
        ay = -0.4;
        break;

      // Down
      case 40:
        ay = 0.4;
        break;
    }

  }, false);

  window.addEventListener('keyup', function(e) {
    if (!mit.start_btn_clicked)
      return;

    ax = 0;
    ay = 0;
  }, false);

  // Game play on mouse clicks too!
  window.addEventListener('mousedown', function(e) {
    if (!mit.start_btn_clicked)
      return;

    if (!mit.game_started)
      mit.game_started = 1;

    ay = -0.4;
    flying_up = 1;
  }, false);

  window.addEventListener('mouseup', function(e) {
    if (!mit.start_btn_clicked)
      return;

    ay = 0;
    flying_up = 0;
  }, false);

  /*
    Performing some game over tasks
  */
  var gameOver = function() {
    ui.start_screen.fadeIn();
    ui.start_game.html('re-start');
    ui.tweet.html('tweet score');
    ui.fb.html('post on fb');

    mit.game_over = 1;
    mit.start_btn_clicked = 0;
  };

  (function renderGame() {
    window.requestAnimationFrame(renderGame);

    // Draw Backgrounds on BG Canvas
    mit.backgrounds.draw(bg_ctx);

    ctx.clearRect(0, 0, W, H);

    // Draw Digs (holds forks)
    // I am fine without Digs, but Kushagra
    // just WANTS me to do this extra work :/
    mit.forks.drawDigs(ctx);

    // Draw Grass on Main Canvas
    mit.backgrounds.drawGrass(ctx);

    if (flying_up)
      mit.pappu.updateFlyFrameCount();
    else
      mit.pappu.updateFlyFrameCount(0);

    // Game over on reaching any boundary
    if (mit.pappu.hasReachedBoundary(W, H)) {
      // Performing some game over tasks
      gameOver();
      return;
    }

    if (mit.game_started) {

      // Draw Forks
      mit.forks.draw(ctx, 6);
      // Draw Branches
      mit.branches.draw(ctx, 4);

      // Update score
      score = score + 0.2;
      ui.score_board.text(parseInt(score));

      // Acceleration + Gravity
      // ay = ay + gravity;

      // Velocity
      if (
        (vy < v_cap && ay+gravity > 0) ||
        (vy > -v_cap && ay+gravity < 0)
        ) {

        vy += ay;
        vy += gravity;
      }

      // console.log(vy, ay)

      mit.pappu.x += vx;
      mit.pappu.y += vy;

      mit.pappu.draw(ctx);
    }
    else {
      mit.pappu.drawStatic(ctx);
    }

  }());

}());<|endoftext|>


<commit_before>'use strict'
const os = require('os')
const url = require('url')
const crypto = require('crypto')
const Bluebird = require('bluebird')
const promisify = require('./promisify')
const path = require('path')
const pathDirname = promisify.sync(path.dirname)
const pathRelative = promisify.sync(path.relative)
const mkdirp = promisify(require('mkdirp'))
const fs = require('fs')
const fsReadFile = promisify(fs.readFile)
const fsWriteFile = promisify(fs.writeFile)
const fsUnlink = promisify(fs.unlink)
const fsSymlink = promisify(fs.symlink)
const fsReadlink = promisify(fs.readlink)
const zlib = require('zlib')
const zlibGzip = promisify(zlib.gzip)
const zlibGunzip = promisify(zlib.gunzip)
const util = require('util')
const inFlight = require('./in-flight.js')

exports.readFile = readFile
exports.clearFile = clearFile
exports.readUrl = readUrl
exports.clearUrl = clearUrl
exports.invalidateUrl = invalidateUrl

function resolveCall () {
  return Bluebird.all(arguments).then(args => {
    const fn = args.shift()
    return Bluebird.resolve(fn.apply(null, args))
  })
}

function cacheFilename (filename) {
  return Bluebird.resolve(filename).then(filename => {
    return path.join(os.homedir(), '.fetch-fic', filename)
  })
}

function readFile (filename, onMiss) {
  const cacheFile = cacheFilename(filename)
  return inFlight(['read:', filename], thenReadFile)

  function thenReadFile () {
    return fsReadFile(cacheFile).catch(elseHandleMiss)
  }
  function elseHandleMiss () {
    return resolveCall(onMiss).then(content => writeFile(filename, new Buffer(content)))
  }
}

function writeFile (filename, content) {
  const cacheFile = cacheFilename(filename)
  return inFlight('write:' + filename, thenWriteFile).thenReturn(content)

  function thenWriteFile () {
    return mkdirp(pathDirname(cacheFile)).then(() => fsWriteFile(cacheFile, content))
  }
}

function clearFile (filename) {
  const cacheFile = cacheFilename(filename)
  return ignoreHarmlessErrors(fsUnlink(cacheFile))
}

function readJSON (filename, onMiss) {
  return readFile(filename, stringifyOnMiss).then(result => JSON.parse(result))
  function stringifyOnMiss () {
    return resolveCall(onMiss).then(result => JSON.stringify(result, null, 2))
  }
}

function writeJSON (filename, content) {
  return writeFile(filename, JSON.stringify(content, null, 2))
}

function readGzipFile (filename, onMiss) {
  return readFile(filename, gzipOnMiss).then(buf => zlibGunzip(buf))

  function gzipOnMiss () {
    return resolveCall(onMiss).then(result => zlibGzip(result))
  }
}

function getUrlHash (toFetch) {
  return Bluebird.resolve(toFetch).then(toFetch => {
    const parsed = url.parse(toFetch)
    parsed.hash = null
    const normalized = url.format(parsed)
    return crypto.createHash('sha256').update(normalized).digest('hex')
  })
}

function cacheUrlBase (fetchUrl) {
  return Bluebird.all([fetchUrl, getUrlHash(fetchUrl)]).spread((fetchUrl, urlHash) => {
    const fetchP = url.parse(fetchUrl)
    return path.join('urls', fetchP.hostname, urlHash.slice(0, 1), urlHash.slice(1, 2), urlHash)
  })
}
function cacheUrlMetaName (fetchUrl) {
  return cacheUrlBase(fetchUrl).then(cacheUrl => cacheUrl + '.json')
}
function cacheUrlContentName (fetchUrl) {
  return Bluebird.resolve(fetchUrl).then((fetchUrl) => {
    const fetchP = url.parse(fetchUrl)
    const ext = path.parse(fetchP.pathname).ext || '.data'
    return cacheUrlBase(fetchUrl).then(cacheUrl => cacheUrl + ext + '.gz')
  })
}

function readUrl (fetchUrl, onMiss) {
  const metafile = cacheUrlMetaName(fetchUrl)
  const content = cacheUrlContentName(fetchUrl)
  const fetchedAt = Date.now()
  const meta = {
    startUrl: fetchUrl,
    finalUrl: null
  }
  let existingMeta = {}
  return inFlight(fetchUrl, thenReadExistingMetadata)

  function thenReadExistingMetadata () {
    return readJSON(metafile, () => existingMeta).then(meta => {
      existingMeta = meta
      // corrupt JSON, clear entry and start again
      if (!existingMeta.finalUrl) {
        existingMeta = {}
        return clearUrl(fetchUrl).then(thenReadContent)
      } else {
        return thenReadContent()
      }
    })
  }

  function thenReadContent () {
    let result
    if (existingMeta && existingMeta.invalid) {
      result = orFetchUrl()
    } else {
      result = readGzipFile(content, orFetchUrl).catch(err => {
        // corrupted gzips we retry, anything else explode
        if (err.code !== 'Z_DATA_ERROR') throw err
        return clearUrl(fetchUrl).then(() => {
          return readGzipFile(content, orFetchUrl)
        })
      })
    }
    return result.then(thenReadMetadata)
  }

  function orFetchUrl () {
    return resolveCall(onMiss, fetchUrl, existingMeta).then(res => {
      meta.finalUrl   = res.url || meta.startUrl
      meta.status     = res.status
      meta.statusText = res.statusText
      meta.headers    = res.headers.raw()
      meta.fetchedAt  = fetchedAt
      if (existingMeta && existingMeta.invalid && meta.status && meta.status === 304) {
        delete existingMeta.invalid
        return thenReadContent()
      }
      else if (meta.status && meta.status !== 200) {
        const non200 = new Error('Got status: ' + meta.status + ' ' + meta.statusText + ' for ' + fetchUrl)
        non200.meta = meta
        return Bluebird.reject(non200)
      }
      return res.buffer()
    })
  }

  function thenReadMetadata (result) {
    return Bluebird.all([metafile, readJSON(metafile, () => meta)]).spread((metafile, meta) => {
      meta.fromCache = meta.fetchedAt !== fetchedAt ? metafile : null
      if (meta.startURL) {
        meta.startUrl = meta.startURL
        delete meta.startURL
      }
      if (meta.finalURL) {
        meta.finalUrl = meta.finalURL
        delete meta.finalURL
      }
      if (!meta.finalUrl) meta.finalUrl = meta.startUrl
      return [meta, result]
    })
  }
}

function ignoreHarmlessErrors (p) {
  return p.catch(er => {
    if (er.code === 'ENOENT' || er.code === 'EINVAL') return
    throw er
  })
}

function clearUrl (fetchUrl) {
  const metafile = cacheUrlMetaName(fetchUrl)
  const content = cacheUrlContentName(fetchUrl)
  return Bluebird.all([clearFile(metafile), clearFile(content)])
}

function invalidateUrl (fetchUrl) {
  const metafile = cacheUrlMetaName(fetchUrl)
  return readJSON(metafile, () => null).then(meta => {
    if (meta == null) return clearUrl(fetchUrl)
    meta.invalid = true
    return writeJSON(metafile, meta)
  })
}
<commit_msg>cache: Fix cache invalidation to not have an inane implementation<commit_after>'use strict'
const os = require('os')
const url = require('url')
const crypto = require('crypto')
const Bluebird = require('bluebird')
const promisify = require('./promisify')
const path = require('path')
const pathDirname = promisify.sync(path.dirname)
const pathRelative = promisify.sync(path.relative)
const mkdirp = promisify(require('mkdirp'))
const fs = require('fs')
const fsReadFile = promisify(fs.readFile)
const fsWriteFile = promisify(fs.writeFile)
const fsUnlink = promisify(fs.unlink)
const fsSymlink = promisify(fs.symlink)
const fsReadlink = promisify(fs.readlink)
const zlib = require('zlib')
const zlibGzip = promisify(zlib.gzip)
const zlibGunzip = promisify(zlib.gunzip)
const util = require('util')
const inFlight = require('./in-flight.js')

exports.readFile = readFile
exports.clearFile = clearFile
exports.readUrl = readUrl
exports.clearUrl = clearUrl
exports.invalidateUrl = invalidateUrl

const invalidated = {}

function resolveCall () {
  return Bluebird.all(arguments).then(args => {
    const fn = args.shift()
    return Bluebird.resolve(fn.apply(null, args))
  })
}

function cacheFilename (filename) {
  return Bluebird.resolve(filename).then(filename => {
    return path.join(os.homedir(), '.fetch-fic', filename)
  })
}

function readFile (filename, onMiss) {
  const cacheFile = cacheFilename(filename)
  return inFlight(['read:', filename], thenReadFile)

  function thenReadFile () {
    return fsReadFile(cacheFile).catch(elseHandleMiss)
  }
  function elseHandleMiss () {
    return resolveCall(onMiss).then(content => writeFile(filename, new Buffer(content)))
  }
}

function writeFile (filename, content) {
  const cacheFile = cacheFilename(filename)
  return inFlight('write:' + filename, thenWriteFile).thenReturn(content)

  function thenWriteFile () {
    return mkdirp(pathDirname(cacheFile)).then(() => fsWriteFile(cacheFile, content))
  }
}

function clearFile (filename) {
  const cacheFile = cacheFilename(filename)
  return ignoreHarmlessErrors(fsUnlink(cacheFile))
}

function readJSON (filename, onMiss) {
  return readFile(filename, stringifyOnMiss).then(result => JSON.parse(result))
  function stringifyOnMiss () {
    return resolveCall(onMiss).then(result => JSON.stringify(result, null, 2))
  }
}

function writeJSON (filename, content) {
  return writeFile(filename, JSON.stringify(content, null, 2))
}

function readGzipFile (filename, onMiss) {
  return readFile(filename, gzipOnMiss).then(buf => zlibGunzip(buf))

  function gzipOnMiss () {
    return resolveCall(onMiss).then(result => zlibGzip(result))
  }
}

function getUrlHash (toFetch) {
  return Bluebird.resolve(toFetch).then(toFetch => {
    const parsed = url.parse(toFetch)
    parsed.hash = null
    const normalized = url.format(parsed)
    return crypto.createHash('sha256').update(normalized).digest('hex')
  })
}

function cacheUrlBase (fetchUrl) {
  return Bluebird.all([fetchUrl, getUrlHash(fetchUrl)]).spread((fetchUrl, urlHash) => {
    const fetchP = url.parse(fetchUrl)
    return path.join('urls', fetchP.hostname, urlHash.slice(0, 1), urlHash.slice(1, 2), urlHash)
  })
}
function cacheUrlMetaName (fetchUrl) {
  return cacheUrlBase(fetchUrl).then(cacheUrl => cacheUrl + '.json')
}
function cacheUrlContentName (fetchUrl) {
  return Bluebird.resolve(fetchUrl).then((fetchUrl) => {
    const fetchP = url.parse(fetchUrl)
    const ext = path.parse(fetchP.pathname).ext || '.data'
    return cacheUrlBase(fetchUrl).then(cacheUrl => cacheUrl + ext + '.gz')
  })
}

function readUrl (fetchUrl, onMiss) {
  const metafile = cacheUrlMetaName(fetchUrl)
  const content = cacheUrlContentName(fetchUrl)
  const fetchedAt = Date.now()
  const meta = {
    startUrl: fetchUrl,
    finalUrl: null
  }
  let existingMeta = {}
  return inFlight(fetchUrl, thenReadExistingMetadata)

  function thenReadExistingMetadata () {
    return readJSON(metafile, () => existingMeta).then(meta => {
      existingMeta = meta
      // corrupt JSON, clear entry and start again
      if (!existingMeta.finalUrl) {
        existingMeta = {}
        return clearUrl(fetchUrl).then(thenReadContent)
      } else {
        return thenReadContent()
      }
    })
  }

  function thenReadContent () {
    let result
    if (invalidated[fetchUrl]) {
      delete invalidated[fetchUrl]
      result = orFetchUrl()
    } else {
      result = readGzipFile(content, orFetchUrl).catch(err => {
        // corrupted gzips we retry, anything else explode
        if (err.code !== 'Z_DATA_ERROR') throw err
        return clearUrl(fetchUrl).then(() => {
          return readGzipFile(content, orFetchUrl)
        })
      })
    }
    return result.then(thenReadMetadata)
  }

  function orFetchUrl () {
    return resolveCall(onMiss, fetchUrl, existingMeta).then(res => {
      meta.finalUrl   = res.url || meta.startUrl
      meta.status     = res.status
      meta.statusText = res.statusText
      meta.headers    = res.headers.raw()
      meta.fetchedAt  = fetchedAt
      if (meta.status && meta.status === 304) {
        return thenReadContent()
      }
      else if (meta.status && meta.status !== 200) {
        const non200 = new Error('Got status: ' + meta.status + ' ' + meta.statusText + ' for ' + fetchUrl)
        non200.meta = meta
        return Bluebird.reject(non200)
      }
      return res.buffer()
    })
  }

  function thenReadMetadata (result) {
    return Bluebird.all([metafile, readJSON(metafile, () => meta)]).spread((metafile, meta) => {
      meta.fromCache = meta.fetchedAt !== fetchedAt ? metafile : null
      if (meta.startURL) {
        meta.startUrl = meta.startURL
        delete meta.startURL
      }
      if (meta.finalURL) {
        meta.finalUrl = meta.finalURL
        delete meta.finalURL
      }
      if (!meta.finalUrl) meta.finalUrl = meta.startUrl
      return [meta, result]
    })
  }
}

function ignoreHarmlessErrors (p) {
  return p.catch(er => {
    if (er.code === 'ENOENT' || er.code === 'EINVAL') return
    throw er
  })
}

function clearUrl (fetchUrl) {
  const metafile = cacheUrlMetaName(fetchUrl)
  const content = cacheUrlContentName(fetchUrl)
  return Bluebird.all([clearFile(metafile), clearFile(content)])
}

function invalidateUrl (fetchUrl) {
  return Promise.resolve(fetchUrl).then(fetchUrl => invalidated[fetchUrl] = true)
}
<|endoftext|>


<commit_before><commit_msg>main.js up<commit_after>;(function(){
	'use strict';

	angular.module('wishApp', ['ngRoute', 'mgcrea.ngStrap'])

}());
<|endoftext|>