<commit_before>/**
 * Copyright (c) 2016 Kinvey Inc.
 *
 * 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.
 */

function createCompletionHandler(task, callback) {
  function completionHandler(entity) {
    if (!entity) entity = {};

    let api = {};
    const responseCallback = callback;
    const result = task.response;

    result.body = entity;

    function created() {
      result.statusCode = 201;
      return api;
    }

    function accepted() {
      result.statusCode = 202;
      return api;
    }

    function ok() {
      result.statusCode = 200;
      return api;
    }

    function notFound(debug) {
      result.statusCode = 404;
      result.body = {
        error: 'NotFound',
        description: 'The requested entity or entities were not found in the serviceObject',
        debug: debug || result.body || {}
      };
      return api;
    }

    function badRequest(debug) {
      result.statusCode = 400;
      result.body = {
        error: 'BadRequest',
        description: 'Unable to understand request',
        debug: debug || result.body || {}
      };
      return api;
    }

    function unauthorized(debug) {
      result.statusCode = 401;
      result.body = {
        error: 'InvalidCredentials',
        description: 'Invalid credentials. Please retry your request with correct credentials',
        debug: debug || result.body || {}
      };
      return api;
    }

    function forbidden(debug) {
      result.statusCode = 403;
      result.body = {
        error: 'Forbidden',
        description: 'The request is forbidden',
        debug: debug || result.body || {}
      };
      return api;
    }

    function notAllowed(debug) {
      result.statusCode = 405;
      result.body = {
        error: 'NotAllowed',
        description: 'The request is not allowed',
        debug: debug || result.body || {}
      };
      return api;
    }

    function notImplemented(debug) {
      result.statusCode = 501;
      result.body = {
        error: 'NotImplemented',
        description: 'The request invoked a method that is not implemented',
        debug: debug || result.body || {}
      };
      return api;
    }

    function runtimeError(debug) {
      result.statusCode = 550;
      result.body = {
        error: 'DataLinkRuntimeError',
        description: 'The Datalink had a runtime error.  See debug message for details',
        debug: debug || result.body || {}
      };
      return api;
    }

    function done() {
      if (result.statusCode === null) {
        result.statusCode = 200;
      }
      result.body = JSON.stringify(result.body);

      // TODO:  Ensure that the result is a kinveyEntity or array of kinveyEntities or {count} object
      //
      //        if result.statusCode < 400 and entityParser.isKinveyEntity(entity) is false
      //          if entity.constructor isnt Array
      //            entity = entityParser.entity entity

      result.continue = false;
      return responseCallback(null, task);
    }

    function next() {
      if (result.statusCode === null) {
        result.statusCode = 200;
      }
      result.body = JSON.stringify(result.body);

      // TODO:  Ensure that the result is a kinveyEntity or array of kinveyEntities or {count} object

      result.continue = true;
      return responseCallback(null, task);
    }

    api = {
      created,
      accepted,
      ok,
      done,
      next,
      notFound,
      badRequest,
      unauthorized,
      forbidden,
      notAllowed,
      notImplemented,
      runtimeError
    };

    return api;
  }

  return completionHandler;
}

module.exports = createCompletionHandler;
<commit_msg>Initialize API handlers inline<commit_after>/**
 * Copyright (c) 2016 Kinvey Inc.
 *
 * 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.
 */

function createCompletionHandler(task, callback) {
  function completionHandler(entity) {
    if (!entity) entity = {};

    const responseCallback = callback;
    const result = task.response;

    result.body = entity;

    const api = {
      created() {
        result.statusCode = 201;
        return api;
      },
      accepted() {
        result.statusCode = 202;
        return api;
      },
      ok() {
        result.statusCode = 200;
        return api;
      },
      notFound(debug) {
        result.statusCode = 404;
        result.body = {
          error: 'NotFound',
          description: 'The requested entity or entities were not found in the serviceObject',
          debug: debug || result.body || {}
        };
        return api;
      },
      badRequest(debug) {
        result.statusCode = 400;
        result.body = {
          error: 'BadRequest',
          description: 'Unable to understand request',
          debug: debug || result.body || {}
        };
        return api;
      },
      unauthorized(debug) {
        result.statusCode = 401;
        result.body = {
          error: 'InvalidCredentials',
          description: 'Invalid credentials. Please retry your request with correct credentials',
          debug: debug || result.body || {}
        };
        return api;
      },
      forbidden(debug) {
        result.statusCode = 403;
        result.body = {
          error: 'Forbidden',
          description: 'The request is forbidden',
          debug: debug || result.body || {}
        };
        return api;
      },
      notAllowed(debug) {
        result.statusCode = 405;
        result.body = {
          error: 'NotAllowed',
          description: 'The request is not allowed',
          debug: debug || result.body || {}
        };
        return api;
      },
      notImplemented(debug) {
        result.statusCode = 501;
        result.body = {
          error: 'NotImplemented',
          description: 'The request invoked a method that is not implemented',
          debug: debug || result.body || {}
        };
        return api;
      },
      runtimeError(debug) {
        result.statusCode = 550;
        result.body = {
          error: 'DataLinkRuntimeError',
          description: 'The Datalink had a runtime error.  See debug message for details',
          debug: debug || result.body || {}
        };
        return api;
      },
      done() {
        if (result.statusCode === null) {
          result.statusCode = 200;
        }
        result.body = JSON.stringify(result.body);

        // TODO:  Ensure that the result is a kinveyEntity or array of kinveyEntities or {count} object
        //
        //        if result.statusCode < 400 and entityParser.isKinveyEntity(entity) is false
        //          if entity.constructor isnt Array
        //            entity = entityParser.entity entity

        result.continue = false;
        return responseCallback(null, task);
      },
      next() {
        if (result.statusCode === null) {
          result.statusCode = 200;
        }
        result.body = JSON.stringify(result.body);

        // TODO:  Ensure that the result is a kinveyEntity or array of kinveyEntities or {count} object

        result.continue = true;
        return responseCallback(null, task);
      }
    };

    return api;
  }

  return completionHandler;
}

module.exports = createCompletionHandler;
<|endoftext|>


<commit_before>/*
//This program has been developed by students from the bachelor Computer Science at Utrecht University
//within the Software and Game project courses 2013-2015
//©Copyright Utrecht University (Department of Information and Computing Sciences)
*/

var Clipboard;

(function()
{
    Clipboard =
    {
        copyElement: copyElement,
        cutElement: cutElement,
        pasteElement: pasteElement
    };

    //Public Variables

    //Private Variables
    var copiedElement = null,
        copiedElements = [],
        copiedTrees = false;

    $(document).ready(function()
    {
        $("#copyNode").on('click', function()
        {
            copyElement();
        });
        $("#cutNode").on('click', function ()
        {
            cutElement();
        });
        $("#pasteNode").on('click', function()
        {
            pasteElement();
        });
    });

    function copyElement()
    {
        //Check if we're saving tree(s) or node(s)
        copiedTrees = !Zoom.isZoomed();

        //Save element(s) in memory
        if (Main.selectedElement !== null && Main.selectedElement !==
            undefined)
        {
            if (copiedTrees)
            {
                copiedElement = copyTree(Main.selectedElement);
            }
            else
            {
                copiedElement = copyNode(Main.selectedElement);
            }
            copiedElements = null;
        }
        else if (Main.selectedElements !== null && Main.selectedElements !==
            undefined)
        {
            copiedElements = [];
            if (copiedTrees)
            {
                $.each(Main.selectedElements, function(index, treeId)
                {
                    copiedElements.push(copyTree(treeId));
                });
            }
            else
            {
                $.each(Main.selectedElements, function(index, nodeId)
                {
                    copiedElements.push(copyNode(nodeId));
                });
            }
            copiedElement = null;
        }
    }

    function copyTree(treeId)
    {
        //Save tree data
        var toCopy = Utils.clone(Main.trees[treeId]),
        nodes = [];
        //Save all node data in tree
        $.each(Main.trees[treeId].nodes, function(index, nodeId)
        {
            nodes.push(copyNode(nodeId));
        });
        toCopy.nodes = nodes;

        return toCopy;
    }

    function copyNode(nodeId)
    {
        toCopy = Utils.clone(Main.nodes[nodeId]);
        //Get node connections
        var connections = jsPlumb.getConnections(
                    {
                        target: nodeId
                    });
        //Get node position
        var position = $('#' + nodeId).position();

        //Save extra node info
        toCopy.connections = connections;
        toCopy.position = position;

        return toCopy;
    }

    function cutElement()
    {
        copyElement();
        Main.deleteAllSelected();
    }

    function pasteElement()
    {
        if (copiedElement !== null && copiedElement !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                pasteTree(copiedElement, 0, 0);
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                var newNode = pasteNode(copiedElement);
                Main.selectElement(newNode.id);
            }
        }
        else if (copiedElements !== null && copiedElements !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                // In grid positions
                var minY = Number.MAX_VALUE;
                var minX = Number.MAX_VALUE;
                var offSetY = [];
                var offSetX = [];

                $.each(copiedElements, function(index, tree)
                {
                    if(tree.leftPos < minX)
                        minX = tree.leftPos;
                    if(tree.topPos < minY)
                        minY = tree.topPos;
                });

                $.each(copiedElements, function(index, tree)
                {
                    offSetY[index] = tree.topPos-minY;
                    offSetX[index] = tree.leftPos-minX;
                });

                // Paste trees relative to top left of smallest bounding box
                $.each(copiedElements, function(index, tree)
                {
                    pasteTree(tree, offSetX[index], offSetY[index]);
                });
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                //Needed to save jsPlumb connections
                var idMappings = {};
                $.each(copiedElements, function(index, node)
                {
                    newNode = pasteNode(node);
                    idMappings[node.id] = newNode.id;
                });

                //Copy jsPlumb connections
                $.each(copiedElements, function(index, node)
                {
                    if (!node) //due to deleting from arrays in js leaving values undefined
                        return true;

                    var connections = node.connections;

                    $.each(connections, function(index,
                        connection)
                    {
                        var target = idMappings[
                            connection.targetId]; //map original target to copied target
                        if (!target)
                            return true;
                        var source = idMappings[
                            connection.sourceId]; //map original source to copied source
                        if (!source)
                            return true;
                        jsPlumb.connect(
                        {
                            "source": source,
                            "target": target
                        });
                    });
                });
                // select all nodes just copied
                for (var key in idMappings)
                {
                    // function that allows for more than one selected node at a time
                    KeyControl.selectExtraElement(idMappings[key]);
                }
            }
        }
    }

    function pasteNode(copiedNode)
    {
        var node = Utils.clone(copiedNode); //no dom action just yet. this just copies the object in the nodes object
        var newNode = Main.addNewNode(node.type); //to do dom manipulations and create the id. no data now present in nodes[newNode.id] is kept

        Main.selectElement(null);

        node.id = newNode.id;
        delete node.position;
        delete node.connections;

        Main.nodes[newNode.id] = node;

        // set nodeposition relatively to the positions off the original node(s)
        var left = copiedNode.position.left + 50;
        var top = copiedNode.position.top + 50;

        var nodeElem = $('#' + newNode.id);
        //Set position
        nodeElem.css(
        {
            "top": top,
            "left": left
        });
        //Save node text
        nodeElem.find(".statementText").text(copiedNode.text).show();
        nodeElem.find("textarea.nodestatement").val(copiedNode.text);

        Main.changeNodeText(newNode.id);

        return node;
    }

    function pasteTree(toCopy, offSetX, offSetY)
    {
        var idMappings = {}; //record wich original node id was copied to which id
        //idmappings[originalID] = copyID
        //all other information like dom elements and position should not be copied

        var newTree = Main.addNewTree(null, true, offSetX, offSetY);

        newTree.subject = LanguageManager.fLang("edt_clipboard_copy_of", [toCopy.subject]);
        newTree.optional = toCopy.optional;

        var treeDiv = $("#" + newTree.id);
        treeDiv.find(".subjectName").text(newTree.subject);
        treeDiv.find(".subjectNameInput").val(newTree.subject);

        Main.selectElement(newTree.id); //tree needs to be selected when copied nodes are created

        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true; //$.each version of continue

            var newNode = pasteNode(node);

            Main.selectElement(newTree.id); //after creation a new node is immediately selected. so we need to reselect the tree

            idMappings[node.id] = newNode.id; //needed to also copy over jsplumb connectors.

            var newNodeDiv = $("#" + newNode.id);

            newNodeDiv.css(
            {
                "top": node.position.top,
                "left": node.position.left
            }); //position is relative to dom parent, so can be copied directly
        });

        //all nodes have been created. now copy connectors
        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true;

            var connections = node.connections;

            $.each(connections, function(index, connection)
            {
                var target = idMappings[connection.targetId]; //map original target to copied target
                var source = idMappings[connection.sourceId]; //map original source to copied source
                jsPlumb.connect(
                {
                    "source": source,
                    "target": target
                });
            });
        });
    }

}());
<commit_msg>Fixed double encoding of texts of pasted nodes<commit_after>/*
//This program has been developed by students from the bachelor Computer Science at Utrecht University
//within the Software and Game project courses 2013-2015
//©Copyright Utrecht University (Department of Information and Computing Sciences)
*/

var Clipboard;

(function()
{
    Clipboard =
    {
        copyElement: copyElement,
        cutElement: cutElement,
        pasteElement: pasteElement
    };

    //Public Variables

    //Private Variables
    var copiedElement = null,
        copiedElements = [],
        copiedTrees = false;

    $(document).ready(function()
    {
        $("#copyNode").on('click', function()
        {
            copyElement();
        });
        $("#cutNode").on('click', function ()
        {
            cutElement();
        });
        $("#pasteNode").on('click', function()
        {
            pasteElement();
        });
    });

    function copyElement()
    {
        //Check if we're saving tree(s) or node(s)
        copiedTrees = !Zoom.isZoomed();

        //Save element(s) in memory
        if (Main.selectedElement !== null && Main.selectedElement !==
            undefined)
        {
            if (copiedTrees)
            {
                copiedElement = copyTree(Main.selectedElement);
            }
            else
            {
                copiedElement = copyNode(Main.selectedElement);
            }
            copiedElements = null;
        }
        else if (Main.selectedElements !== null && Main.selectedElements !==
            undefined)
        {
            copiedElements = [];
            if (copiedTrees)
            {
                $.each(Main.selectedElements, function(index, treeId)
                {
                    copiedElements.push(copyTree(treeId));
                });
            }
            else
            {
                $.each(Main.selectedElements, function(index, nodeId)
                {
                    copiedElements.push(copyNode(nodeId));
                });
            }
            copiedElement = null;
        }
    }

    function copyTree(treeId)
    {
        //Save tree data
        var toCopy = Utils.clone(Main.trees[treeId]),
        nodes = [];
        //Save all node data in tree
        $.each(Main.trees[treeId].nodes, function(index, nodeId)
        {
            nodes.push(copyNode(nodeId));
        });
        toCopy.nodes = nodes;

        return toCopy;
    }

    function copyNode(nodeId)
    {
        toCopy = Utils.clone(Main.nodes[nodeId]);
        //Get node connections
        var connections = jsPlumb.getConnections(
                    {
                        target: nodeId
                    });
        //Get node position
        var position = $('#' + nodeId).position();

        //Save extra node info
        toCopy.connections = connections;
        toCopy.position = position;

        return toCopy;
    }

    function cutElement()
    {
        copyElement();
        Main.deleteAllSelected();
    }

    function pasteElement()
    {
        if (copiedElement !== null && copiedElement !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                pasteTree(copiedElement, 0, 0);
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                var newNode = pasteNode(copiedElement);
                Main.selectElement(newNode.id);
            }
        }
        else if (copiedElements !== null && copiedElements !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                // In grid positions
                var minY = Number.MAX_VALUE;
                var minX = Number.MAX_VALUE;
                var offSetY = [];
                var offSetX = [];

                $.each(copiedElements, function(index, tree)
                {
                    if(tree.leftPos < minX)
                        minX = tree.leftPos;
                    if(tree.topPos < minY)
                        minY = tree.topPos;
                });

                $.each(copiedElements, function(index, tree)
                {
                    offSetY[index] = tree.topPos-minY;
                    offSetX[index] = tree.leftPos-minX;
                });

                // Paste trees relative to top left of smallest bounding box
                $.each(copiedElements, function(index, tree)
                {
                    pasteTree(tree, offSetX[index], offSetY[index]);
                });
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                //Needed to save jsPlumb connections
                var idMappings = {};
                $.each(copiedElements, function(index, node)
                {
                    newNode = pasteNode(node);
                    idMappings[node.id] = newNode.id;
                });

                //Copy jsPlumb connections
                $.each(copiedElements, function(index, node)
                {
                    if (!node) //due to deleting from arrays in js leaving values undefined
                        return true;

                    var connections = node.connections;

                    $.each(connections, function(index,
                        connection)
                    {
                        var target = idMappings[
                            connection.targetId]; //map original target to copied target
                        if (!target)
                            return true;
                        var source = idMappings[
                            connection.sourceId]; //map original source to copied source
                        if (!source)
                            return true;
                        jsPlumb.connect(
                        {
                            "source": source,
                            "target": target
                        });
                    });
                });
                // select all nodes just copied
                for (var key in idMappings)
                {
                    // function that allows for more than one selected node at a time
                    KeyControl.selectExtraElement(idMappings[key]);
                }
            }
        }
    }

    function pasteNode(copiedNode)
    {
        var node = Utils.clone(copiedNode); //no dom action just yet. this just copies the object in the nodes object
        var newNode = Main.addNewNode(node.type); //to do dom manipulations and create the id. no data now present in nodes[newNode.id] is kept

        Main.selectElement(null);

        node.id = newNode.id;
        delete node.position;
        delete node.connections;

        Main.nodes[newNode.id] = node;

        // set nodeposition relatively to the positions off the original node(s)
        var left = copiedNode.position.left + 50;
        var top = copiedNode.position.top + 50;

        var nodeElem = $('#' + newNode.id);
        //Set position
        nodeElem.css(
        {
            "top": top,
            "left": left
        });
        //Save node text
        nodeElem.find(".statementText").text(copiedNode.text).show();
        nodeElem.find("textarea.nodestatement").val(Main.unEscapeTags(copiedNode.text));

        Main.changeNodeText(newNode.id);

        return node;
    }

    function pasteTree(toCopy, offSetX, offSetY)
    {
        var idMappings = {}; //record wich original node id was copied to which id
        //idmappings[originalID] = copyID
        //all other information like dom elements and position should not be copied

        var newTree = Main.addNewTree(null, true, offSetX, offSetY);

        newTree.subject = LanguageManager.fLang("edt_clipboard_copy_of", [toCopy.subject]);
        newTree.optional = toCopy.optional;

        var treeDiv = $("#" + newTree.id);
        treeDiv.find(".subjectName").text(newTree.subject);
        treeDiv.find(".subjectNameInput").val(newTree.subject);

        Main.selectElement(newTree.id); //tree needs to be selected when copied nodes are created

        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true; //$.each version of continue

            var newNode = pasteNode(node);

            Main.selectElement(newTree.id); //after creation a new node is immediately selected. so we need to reselect the tree

            idMappings[node.id] = newNode.id; //needed to also copy over jsplumb connectors.

            var newNodeDiv = $("#" + newNode.id);

            newNodeDiv.css(
            {
                "top": node.position.top,
                "left": node.position.left
            }); //position is relative to dom parent, so can be copied directly
        });

        //all nodes have been created. now copy connectors
        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true;

            var connections = node.connections;

            $.each(connections, function(index, connection)
            {
                var target = idMappings[connection.targetId]; //map original target to copied target
                var source = idMappings[connection.sourceId]; //map original source to copied source
                jsPlumb.connect(
                {
                    "source": source,
                    "target": target
                });
            });
        });
    }

}());
<|endoftext|>


<commit_before>/* © Utrecht University and DialogueTrainer */

(function()
{
    "use strict";

    $(document).ready(function()
    {
        var isIEClipboard = window.clipboardData && window.clipboardData.getData;

        var handleClipboardEvent = function(e, clipboard, action)
        {
            var handlers =
            {
                copy: copy,
                cut: cut,
                paste: paste
            };

            var clipboardFormat = isIEClipboard ? clipboardFormat = 'Text' : 'text/plain';

            if (Main.isEditingInCanvas() && handlers[action](clipboard, clipboardFormat))
            {
                e.preventDefault();
            }
        };

        var actionsByKey = { C: 'copy', X: 'cut', V: 'paste' };

        $(document).on('keydown', function(e)
        {
            if (isIEClipboard)
            {
                var key = String.fromCharCode(e.keyCode);
                if ((e.ctrlKey || e.metaKey) && key in actionsByKey)
                {
                    handleClipboardEvent(e, window.clipboardData, actionsByKey[key]);
                }
            }
        });

        Object.keys(actionsByKey).map(function(key)
        {
            var action = actionsByKey[key];
            $(document).on(action, function(e)
            {
                handleClipboardEvent(e, e.originalEvent.clipboardData, action);
            });

            // Show hint for the clipboard buttons
            $('#' + action).tooltip({ items: '#' + action, content: i18next.t('clipboard:hint', { key: key, action: action }) });
            $('#' + action).on('click', function()
            {
                $("#main").focus();
            });
        });
    });

    function copy(clipboard, format)
    {
        var dataAsText = JSON.stringify($.extend(copyElement(), { target: 'scenario', configIdRef: Config.container.id }));
        clipboard.setData(format, dataAsText);
        return true;
    }

    function cut(clipboard, format)
    {
        copy(clipboard, format);

        Main.deleteAllSelected();

        return true;
    }

    function paste(clipboard, format)
    {
        if (Main.isMousePositionWithinEditingCanvas())
        {
            try
            {
                var data = JSON.parse(clipboard.getData(format));
                if (data && data.target === 'scenario' && data.configIdRef && data.type && data.content)
                {
                    if (data.configIdRef !== Config.container.id)
                    {
                        Utils.alertDialog("The config id of the pasted content does not match the config id referred to in the scenario", 'warning');
                    }
                    return considerPasting(data.type, data.definitions, data.content);
                }
            }
            catch(_)
            {
                return false;
            }
        }

        return false;
    }

    function copyElement()
    {
        var definitions = { parameters: { userDefined: $.extend(true, {}, Parameters.container) } };
        if (Main.selectedElement !== null)
        {
            if (!Zoom.isZoomed())
            {
                return {
                    type: 'dialogue',
                    definitions: definitions,
                    content: copyTree(Main.selectedElement)
                };
            }
            else
            {
                return {
                    type: 'node',
                    definitions: definitions,
                    content: copyNode(Main.selectedElement)
                };
            }
        }
        else if (Main.selectedElements !== null)
        {
            if (!Zoom.isZoomed())
            {
                return {
                    type: 'dialogue',
                    definitions: definitions,
                    content: Main.selectedElements.map(function(treeID)
                    {
                        return copyTree(treeID);
                    })
                };
            }
            else
            {
                return {
                    type: 'node',
                    definitions: definitions,
                    content: Main.selectedElements.map(function(nodeID)
                    {
                        return copyNode(nodeID);
                    })
                };
            }
        }
    }

    function copyTree(treeId)
    {
        var tree = Main.trees[treeId];
        //Save tree data
        var toCopy = Utils.clone(
        {
            subject: tree.subject,
            level: tree.level,
            optional: tree.optional,
            leftPos: tree.leftPos,
            leftScroll: tree.leftScroll,
            topPos: tree.topPos,
            topScroll: tree.topScroll
        });
        var nodes = [];
        //Save all node data in tree
        $.each(Main.trees[treeId].nodes, function(index, nodeId)
        {
            nodes.push(copyNode(nodeId));
        });
        toCopy.nodes = nodes;

        return toCopy;
    }

    function copyNode(nodeID)
    {
        var toCopy = Utils.clone(Main.nodes[nodeID]);

        var plumbInstance = Main.getPlumbInstanceByNodeID(nodeID);
        toCopy.connections = plumbInstance.getConnections({ target: nodeID }).map(function(connection)
        {
            return {
                sourceId: connection.sourceId,
                targetId: connection.targetId,
                color: connection.getParameter('color')
            };
        });

        toCopy.position = Utils.cssPosition($('#' + nodeID));

        return toCopy;
    }

    function pasteElement(type, content)
    {
        var indicatorPos = Main.getGridIndicatorPosition();
        if (!Array.isArray(content))
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                var newTree = pasteTree(content, indicatorPos.left, indicatorPos.top);
                Main.selectElement(newTree.id);
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                var newNode = pasteNode(content, { left: 0, top: 0 });
                Main.selectElement(newNode.id);
            }
        }
        else
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                // In grid positions
                var minX = Number.MAX_VALUE;
                var minY = Number.MAX_VALUE;

                $.each(content, function(index, tree)
                {
                    if (tree.leftPos < minX) minX = tree.leftPos;
                    if (tree.topPos < minY) minY = tree.topPos;
                });

                // Paste trees relative to top left of smallest bounding box
                var pastedTreeIds = $.map(content, function(tree, index)
                {
                    var leftPos = tree.leftPos - minX + indicatorPos.left;
                    var topPos = tree.topPos - minY + indicatorPos.top;
                    return pasteTree(tree, leftPos, topPos).id;
                });

                Main.selectElements(pastedTreeIds);
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                //Needed to save jsPlumb connections
                var idMappings = {};
                var plumbInstance = Zoom.getZoomed().plumbInstance;
                plumbInstance.batch(function()
                {
                    $.each(content, function(index, node)
                    {
                        var offset = { left: node.position.left - content[0].position.left, top: node.position.top - content[0].position.top };
                        newNode = pasteNode(node, offset);
                        idMappings[node.id] = newNode.id;
                    });

                    // Paste jsPlumb connections
                    $.each(content, function(index, node)
                    {
                        if (!node) //due to deleting from arrays in js leaving values undefined
                            return true;

                        var connections = node.connections;

                        $.each(connections, function(index, connection)
                        {
                            var target = idMappings[connection.targetId]; //map original target to copied target
                            if (!target)
                                return true;
                            var source = idMappings[connection.sourceId]; //map original source to copied source
                            if (!source)
                                return true;
                            var newConnection = plumbInstance.connect(
                            {
                                "source": source,
                                "target": target
                            });

                            if (connection.color)
                            {
                                newConnection.setParameter('color', connection.color);
                            }
                        });
                    });

                    if (ColorPicker.areColorsEnabled())
                    {
                        ColorPicker.applyColors();
                    }
                });

                // select all nodes just copied
                Main.selectElements($.map(idMappings, function (newId) { return newId; }));
            }
        }
    }

    function pasteNode(copiedNode, offset, tree, doNotPosition)
    {
        if (!tree) tree = Zoom.getZoomed();
        if (!tree) return;

        var node = Utils.clone(copiedNode); //no dom action just yet. this just copies the object in the nodes object
        var nodeElem = Main.createAndReturnNode(node.type, null, tree.div, tree.id); //to do dom manipulations and create the id

        node.id = nodeElem.attr('id');
        node.parent = tree.id;
        delete node.position;
        delete node.connections;

        Main.nodes[node.id] = node;

        if (!doNotPosition)
        {
            var position = Main.mousePositionToDialoguePosition(Main.mousePosition);
            Utils.cssPosition(nodeElem, { left: Math.max(position.left + offset.left, 0), top: Math.max(position.top + offset.top, 0) });
        }

        Main.changeNodeText(node.id);

        return node;
    }

    function pasteTree(toCopy, leftPos, topPos)
    {
        var idMappings = {};

        var newTree = Main.createEmptyTree(null, leftPos, topPos);

        newTree.subject = i18next.t('clipboard:copy_of', { postProcess: 'sprintf', sprintf: [toCopy.subject]});
        newTree.optional = toCopy.optional;

        newTree.leftScroll = toCopy.leftScroll;
        newTree.topScroll = toCopy.topScroll;

        var treeDiv = $("#" + newTree.id);
        treeDiv.find(".subjectName").text(newTree.subject);
        treeDiv.find(".subjectNameInput").val(newTree.subject);

        newTree.plumbInstance.batch(function()
        {
            $.each(toCopy.nodes, function(index, node)
            {
                if (!node) //due to deleting from arrays in js leaving values undefined
                    return true; //$.each version of continue

                var newNode = pasteNode(node, { left: 0, top: 0 }, newTree, true);

                idMappings[node.id] = newNode.id; //needed to also copy over jsplumb connectors.

                Utils.cssPosition($("#" + newNode.id), node.position);
            });

            //all nodes have been created. now copy connectors
            $.each(toCopy.nodes, function(index, node)
            {
                if (!node) //due to deleting from arrays in js leaving values undefined
                    return true;

                var connections = node.connections;

                $.each(connections, function(index, connection)
                {
                    var target = idMappings[connection.targetId]; //map original target to copied target
                    var source = idMappings[connection.sourceId]; //map original source to copied source
                    var newConnection = newTree.plumbInstance.connect(
                    {
                        "source": source,
                        "target": target
                    });

                    if (connection.color)
                    {
                        newConnection.setParameter('color', connection.color);
                    }
                });
            });
        });

        return newTree;
    }

    // Pastes the content if confirmed and returns true if the type, content and context are correct
    function considerPasting(type, definitions, content)
    {
        var getAndDeleteMissingParameterReferrers = function(node)
        {
            var getEqualParameter = function(parameter)
            {
                var equalParameters = Parameters.container.sequence.filter(function(existingParameter)
                {
                    return existingParameter.name === parameter.name && existingParameter.type.equals(parameter.type);
                });
                return equalParameters.length > 0 ? equalParameters[0] : null;
            };

            var missingParameterIds = {};
            node.parameterEffects.userDefined = node.parameterEffects.userDefined.filter(function(parameterEffect)
            {
                var equalParameter = getEqualParameter(definitions.parameters.userDefined.byId[parameterEffect.idRef]);
                if (equalParameter)
                {
                    parameterEffect.idRef = equalParameter.id;
                }
                else
                {
                    missingParameterIds[parameterEffect.idRef] = true;
                }
                return equalParameter;
            });

            if (node.preconditions)
            {
                var onConditionPreservation = function(condition, equalParameter)
                {
                    condition.idRef = equalParameter.id;
                };
                var onConditionRemoval = function(condition)
                {
                    missingParameterIds[condition.idRef] = true;
                };
                node.preconditions = Condition.filter(function(condition)
                {
                    return getEqualParameter(definitions.parameters.userDefined.byId[condition.idRef]);
                }, node.preconditions, onConditionPreservation, onConditionRemoval);
            }

            return missingParameterIds;
        };

        var canPaste = false;
        var parameterIds = {};
        if (!Array.isArray(content))
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                parameterIds = content.nodes.reduce(function(misingParameterIds, node)
                {
                    return $.extend(misingParameterIds, getAndDeleteMissingParameterReferrers(node));
                }, {});
                canPaste = true;
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                parameterIds = getAndDeleteMissingParameterReferrers(content);
                canPaste = true;
            }
        }
        else
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                parameterIds = content.reduce(function(misingParameterIds, dialogue)
                {
                    return $.extend(misingParameterIds, dialogue.nodes.reduce(function(misingParameterIds, node)
                    {
                        return $.extend(misingParameterIds, getAndDeleteMissingParameterReferrers(node));
                    }, {}));
                }, {});
                canPaste = true;
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                parameterIds = content.reduce(function(misingParameterIds, node)
                {
                    return $.extend(misingParameterIds, getAndDeleteMissingParameterReferrers(node));
                }, {});
                canPaste = true;
            }
        }

        if (Object.keys(parameterIds).length > 0)
        {
            var warning = $('<div>');
            warning.append($('<div>', { text: i18next.t('clipboard:referrer_warning') }));
            warning.append($('<ul>').append(Object.keys(parameterIds).map(function(parameterId)
            {
                return $('<li>', { text: definitions.parameters.userDefined.byId[parameterId].name });
            })));
            Utils.confirmDialog(warning, 'warning')
            .then(function(confirmed)
            {
                if (confirmed) pasteElement(type, content);
            });
        }
        else
        {
            pasteElement(type, content);
        }

        return canPaste;
    }

}());
<commit_msg>Fixed copying and pasting fixed parameter effects<commit_after>/* © Utrecht University and DialogueTrainer */

(function()
{
    "use strict";

    $(document).ready(function()
    {
        var isIEClipboard = window.clipboardData && window.clipboardData.getData;

        var handleClipboardEvent = function(e, clipboard, action)
        {
            var handlers =
            {
                copy: copy,
                cut: cut,
                paste: paste
            };

            var clipboardFormat = isIEClipboard ? clipboardFormat = 'Text' : 'text/plain';

            if (Main.isEditingInCanvas() && handlers[action](clipboard, clipboardFormat))
            {
                e.preventDefault();
            }
        };

        var actionsByKey = { C: 'copy', X: 'cut', V: 'paste' };

        $(document).on('keydown', function(e)
        {
            if (isIEClipboard)
            {
                var key = String.fromCharCode(e.keyCode);
                if ((e.ctrlKey || e.metaKey) && key in actionsByKey)
                {
                    handleClipboardEvent(e, window.clipboardData, actionsByKey[key]);
                }
            }
        });

        Object.keys(actionsByKey).map(function(key)
        {
            var action = actionsByKey[key];
            $(document).on(action, function(e)
            {
                handleClipboardEvent(e, e.originalEvent.clipboardData, action);
            });

            // Show hint for the clipboard buttons
            $('#' + action).tooltip({ items: '#' + action, content: i18next.t('clipboard:hint', { key: key, action: action }) });
            $('#' + action).on('click', function()
            {
                $("#main").focus();
            });
        });
    });

    function copy(clipboard, format)
    {
        var dataAsText = JSON.stringify($.extend(copyElement(), { target: 'scenario', configIdRef: Config.container.id }));
        clipboard.setData(format, dataAsText);
        return true;
    }

    function cut(clipboard, format)
    {
        copy(clipboard, format);

        Main.deleteAllSelected();

        return true;
    }

    function paste(clipboard, format)
    {
        if (Main.isMousePositionWithinEditingCanvas())
        {
                var data;
                try
                {
                    data = JSON.parse(clipboard.getData(format));
                }
                catch(_)
                {
                    return false;
                }

                if (data && data.target === 'scenario' && data.configIdRef && data.type && data.definitions && data.content)
                {
                    if (data.configIdRef !== Config.container.id)
                    {
                        Utils.alertDialog("The config id of the pasted content does not match the config id referred to in the scenario", 'warning');
                    }
                    return considerPasting(data.type, data.definitions, data.content);
                }
        }

        return false;
    }

    function copyElement()
    {
        var definitions = { parameters: { userDefined: $.extend(true, {}, Parameters.container) } };
        if (Main.selectedElement !== null)
        {
            if (!Zoom.isZoomed())
            {
                return {
                    type: 'dialogue',
                    definitions: definitions,
                    content: copyTree(Main.selectedElement)
                };
            }
            else
            {
                return {
                    type: 'node',
                    definitions: definitions,
                    content: copyNode(Main.selectedElement)
                };
            }
        }
        else if (Main.selectedElements !== null)
        {
            if (!Zoom.isZoomed())
            {
                return {
                    type: 'dialogue',
                    definitions: definitions,
                    content: Main.selectedElements.map(function(treeID)
                    {
                        return copyTree(treeID);
                    })
                };
            }
            else
            {
                return {
                    type: 'node',
                    definitions: definitions,
                    content: Main.selectedElements.map(function(nodeID)
                    {
                        return copyNode(nodeID);
                    })
                };
            }
        }
    }

    function copyTree(treeId)
    {
        var tree = Main.trees[treeId];
        //Save tree data
        var toCopy = Utils.clone(
        {
            subject: tree.subject,
            level: tree.level,
            optional: tree.optional,
            leftPos: tree.leftPos,
            leftScroll: tree.leftScroll,
            topPos: tree.topPos,
            topScroll: tree.topScroll
        });
        var nodes = [];
        //Save all node data in tree
        $.each(Main.trees[treeId].nodes, function(index, nodeId)
        {
            nodes.push(copyNode(nodeId));
        });
        toCopy.nodes = nodes;

        return toCopy;
    }

    function copyNode(nodeID)
    {
        var toCopy = Utils.clone(Main.nodes[nodeID]);

        var plumbInstance = Main.getPlumbInstanceByNodeID(nodeID);
        toCopy.connections = plumbInstance.getConnections({ target: nodeID }).map(function(connection)
        {
            return {
                sourceId: connection.sourceId,
                targetId: connection.targetId,
                color: connection.getParameter('color')
            };
        });

        toCopy.position = Utils.cssPosition($('#' + nodeID));

        return toCopy;
    }

    function pasteElement(type, content)
    {
        var indicatorPos = Main.getGridIndicatorPosition();
        if (!Array.isArray(content))
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                var newTree = pasteTree(content, indicatorPos.left, indicatorPos.top);
                Main.selectElement(newTree.id);
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                var newNode = pasteNode(content, { left: 0, top: 0 });
                Main.selectElement(newNode.id);
            }
        }
        else
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                // In grid positions
                var minX = Number.MAX_VALUE;
                var minY = Number.MAX_VALUE;

                $.each(content, function(index, tree)
                {
                    if (tree.leftPos < minX) minX = tree.leftPos;
                    if (tree.topPos < minY) minY = tree.topPos;
                });

                // Paste trees relative to top left of smallest bounding box
                var pastedTreeIds = $.map(content, function(tree, index)
                {
                    var leftPos = tree.leftPos - minX + indicatorPos.left;
                    var topPos = tree.topPos - minY + indicatorPos.top;
                    return pasteTree(tree, leftPos, topPos).id;
                });

                Main.selectElements(pastedTreeIds);
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                //Needed to save jsPlumb connections
                var idMappings = {};
                var plumbInstance = Zoom.getZoomed().plumbInstance;
                plumbInstance.batch(function()
                {
                    $.each(content, function(index, node)
                    {
                        var offset = { left: node.position.left - content[0].position.left, top: node.position.top - content[0].position.top };
                        newNode = pasteNode(node, offset);
                        idMappings[node.id] = newNode.id;
                    });

                    // Paste jsPlumb connections
                    $.each(content, function(index, node)
                    {
                        if (!node) //due to deleting from arrays in js leaving values undefined
                            return true;

                        var connections = node.connections;

                        $.each(connections, function(index, connection)
                        {
                            var target = idMappings[connection.targetId]; //map original target to copied target
                            if (!target)
                                return true;
                            var source = idMappings[connection.sourceId]; //map original source to copied source
                            if (!source)
                                return true;
                            var newConnection = plumbInstance.connect(
                            {
                                "source": source,
                                "target": target
                            });

                            if (connection.color)
                            {
                                newConnection.setParameter('color', connection.color);
                            }
                        });
                    });

                    if (ColorPicker.areColorsEnabled())
                    {
                        ColorPicker.applyColors();
                    }
                });

                // select all nodes just copied
                Main.selectElements($.map(idMappings, function (newId) { return newId; }));
            }
        }
    }

    function pasteNode(copiedNode, offset, tree, doNotPosition)
    {
        if (!tree) tree = Zoom.getZoomed();
        if (!tree) return;

        var node = Utils.clone(copiedNode); //no dom action just yet. this just copies the object in the nodes object
        var nodeElem = Main.createAndReturnNode(node.type, null, tree.div, tree.id); //to do dom manipulations and create the id

        node.id = nodeElem.attr('id');
        node.parent = tree.id;
        delete node.position;
        delete node.connections;

        Main.nodes[node.id] = node;

        if (!doNotPosition)
        {
            var position = Main.mousePositionToDialoguePosition(Main.mousePosition);
            Utils.cssPosition(nodeElem, { left: Math.max(position.left + offset.left, 0), top: Math.max(position.top + offset.top, 0) });
        }

        Main.changeNodeText(node.id);

        return node;
    }

    function pasteTree(toCopy, leftPos, topPos)
    {
        var idMappings = {};

        var newTree = Main.createEmptyTree(null, leftPos, topPos);

        newTree.subject = i18next.t('clipboard:copy_of', { postProcess: 'sprintf', sprintf: [toCopy.subject]});
        newTree.optional = toCopy.optional;

        newTree.leftScroll = toCopy.leftScroll;
        newTree.topScroll = toCopy.topScroll;

        var treeDiv = $("#" + newTree.id);
        treeDiv.find(".subjectName").text(newTree.subject);
        treeDiv.find(".subjectNameInput").val(newTree.subject);

        newTree.plumbInstance.batch(function()
        {
            $.each(toCopy.nodes, function(index, node)
            {
                if (!node) //due to deleting from arrays in js leaving values undefined
                    return true; //$.each version of continue

                var newNode = pasteNode(node, { left: 0, top: 0 }, newTree, true);

                idMappings[node.id] = newNode.id; //needed to also copy over jsplumb connectors.

                Utils.cssPosition($("#" + newNode.id), node.position);
            });

            //all nodes have been created. now copy connectors
            $.each(toCopy.nodes, function(index, node)
            {
                if (!node) //due to deleting from arrays in js leaving values undefined
                    return true;

                var connections = node.connections;

                $.each(connections, function(index, connection)
                {
                    var target = idMappings[connection.targetId]; //map original target to copied target
                    var source = idMappings[connection.sourceId]; //map original source to copied source
                    var newConnection = newTree.plumbInstance.connect(
                    {
                        "source": source,
                        "target": target
                    });

                    if (connection.color)
                    {
                        newConnection.setParameter('color', connection.color);
                    }
                });
            });
        });

        return newTree;
    }

    // Pastes the content if confirmed and returns true if the type, content and context are correct
    function considerPasting(type, definitions, content)
    {
        // Returns the parameter IDs that are missing
        var processNode = function(node)
        {
            // Before performing any operations we need to update the references in the byId object
            // to the sequenced objects in the node's datastructures
            var parameterId;
            var fixedParameterEffects = node.parameterEffects.fixed;
            for (parameterId in fixedParameterEffects.characterIndependent.byId)
            {
                fixedParameterEffects.characterIndependent.byId[parameterId] = [];
            }
            fixedParameterEffects.characterIndependent.sequence.forEach(function(effect)
            {
                fixedParameterEffects.characterIndependent.byId[effect.idRef].push(effect);
            });
            for (var characterId in fixedParameterEffects.perCharacter)
            {
                for (parameterId in fixedParameterEffects.perCharacter[characterId].byId)
                {
                    fixedParameterEffects.perCharacter[characterId].byId[parameterId] = [];
                }

                fixedParameterEffects.perCharacter[characterId].sequence.forEach(function(effect)
                {
                    fixedParameterEffects.perCharacter[characterId].byId[effect.idRef].push(effect);
                });
            }

            var getEqualParameter = function(parameter)
            {
                var equalParameters = Parameters.container.sequence.filter(function(existingParameter)
                {
                    return existingParameter.name === parameter.name && existingParameter.type.equals(parameter.type);
                });
                return equalParameters.length > 0 ? equalParameters[0] : null;
            };

            var missingParameterIds = {};
            node.parameterEffects.userDefined = node.parameterEffects.userDefined.filter(function(parameterEffect)
            {
                var equalParameter = getEqualParameter(definitions.parameters.userDefined.byId[parameterEffect.idRef]);
                if (equalParameter)
                {
                    parameterEffect.idRef = equalParameter.id;
                }
                else
                {
                    missingParameterIds[parameterEffect.idRef] = true;
                }
                return equalParameter;
            });

            if (node.preconditions)
            {
                var onConditionPreservation = function(condition, equalParameter)
                {
                    condition.idRef = equalParameter.id;
                };
                var onConditionRemoval = function(condition)
                {
                    missingParameterIds[condition.idRef] = true;
                };
                node.preconditions = Condition.filter(function(condition)
                {
                    return getEqualParameter(definitions.parameters.userDefined.byId[condition.idRef]);
                }, node.preconditions, onConditionPreservation, onConditionRemoval);
            }

            return missingParameterIds;
        };

        var canPaste = false;
        var missingParameterIds = {};
        if (!Array.isArray(content))
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                missingParameterIds = content.nodes.reduce(function(parameterIds, node)
                {
                    return $.extend(parameterIds, processNode(node));
                }, {});
                canPaste = true;
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                missingParameterIds = processNode(content);
                canPaste = true;
            }
        }
        else
        {
            if (type === 'dialogue' && !Zoom.isZoomed())
            {
                missingParameterIds = content.reduce(function(parameterIds, dialogue)
                {
                    return $.extend(parameterIds, dialogue.nodes.reduce(function(parameterIds, node)
                    {
                        return $.extend(parameterIds, processNode(node));
                    }, {}));
                }, {});
                canPaste = true;
            }
            else if (type === 'node' && Zoom.isZoomed())
            {
                missingParameterIds = content.reduce(function(parameterIds, node)
                {
                    return $.extend(parameterIds, processNode(node));
                }, {});
                canPaste = true;
            }
        }

        if (canPaste)
        {
            if (Object.keys(missingParameterIds).length > 0)
            {
                var warning = $('<div>');
                warning.append($('<div>', { text: i18next.t('clipboard:referrer_warning') }));
                warning.append($('<ul>').append(Object.keys(missingParameterIds).map(function(parameterId)
                {
                    return $('<li>', { text: definitions.parameters.userDefined.byId[parameterId].name });
                })));
                Utils.confirmDialog(warning, 'warning')
                .then(function(confirmed)
                {
                    if (confirmed) pasteElement(type, content);
                });
            }
            else
            {
                pasteElement(type, content);
            }
        }

        return canPaste;
    }

}());
<|endoftext|>


<commit_before>RED.gitvcs = (function () {

    var deploymentType = "full";
    var commitAllowed = false;

    var resolveConflictFunction;

    var lastMergedRevision;

    function disableCommitButton() {
        $("#btn-commit").addClass("disabled");
        $("#btn-commit").css("cursor", "default");
        $("#btn-commit").css("background", "#444");
        $("#btn-commit").css("color", "#999");
    }

    function enableCommitButtonIfAllowed() {
        if (commitAllowed) {
            $("#btn-commit").removeClass("disabled");
            $("#btn-commit").css("cursor", "pointer");
            $("#btn-commit").css("background", "#8C101C");
            $("#btn-commit").css("color", "#eee");
            window.onbeforeunload = function() {
                return RED._("deploy.confirm.undeployedChanges");
            };
        }
    }

    function setAllowCommitMode() {
        commitAllowed = true;
    }

    function getAllowCommitMode() {
        return commitAllowed;
    }

    function setDisallowCommitMode() {
        commitAllowed = false;
    }

    function setLastMergedRevision(rev) {
        lastMergedRevision = rev;
        $.ajax({
            url: "/lastMergedRevision?" + (lastMergedRevision ? "lastMergedRevision=" + lastMergedRevision : ""),
            type: "POST"
        })
    }

    function commit() {
        if (!commitAllowed) {
            return;
        }
        var startTime = Date.now();
        $(".deploy-button-content").css('opacity',0);
        $(".deploy-button-spinner").show();

        var nns = RED.nodes.createCompleteNodeSet();
        $.ajax({
            url: "/repositoryflows?" + (lastMergedRevision ? "lastMergedRevision=" + lastMergedRevision : ""),
            type: "POST",
            data: JSON.stringify(nns),
            contentType: "application/json; charset=utf-8",
            headers: {
                "Node-RED-Deployment-Type": deploymentType
            }
        })
            .done(function () {
                RED.nodes.originalFlow(nns);
                lastMergedRevision = null;
                disableCommitButton();
                setDisallowCommitMode();
                window.onbeforeunload = null;
            })
            .fail(function (xhr, textStatus, err) {
                RED.notify(RED._("notification.error",{message:xhr.responseText}), "error");
                if (xhr.status === 409) {
                    sendSignalToReloadFlowFromGithub(function() {
                        if (resolveConflictFunction) resolveConflictFunction(nns);
                    });
                }
            }).always(function(){
                var delta = Math.max(0,300-(Date.now()-startTime));
                setTimeout(function() {
                    $(".deploy-button-content").css('opacity',1);
                    $(".deploy-button-spinner").hide();
                },delta);
            });
    }

    function sendSignalToReloadFlowFromGithub(callback) {
        $.ajax({
            url: "/repositorymode",
            type: "POST",
            // data: JSON.stringify(data),
            // contentType: "application/json; charset=utf-8",
            headers: {
                "Node-RED-Deployment-Type": deploymentType
            }
        }).done(function (data, textStatus, xhr) {
            callback();
        });
    }

    function init(resolveConflictFunc) {
        $('' +
            'Commit to Github' +
            '' +
                '' +
            '' +
            '').prependTo(".header-toolbar");

        disableCommitButton();
        $('#btn-commit').click(commit);

        resolveConflictFunction = resolveConflictFunc;
    }

    return {
        init: init,
        //commit: commit,

        disableCommitButton: disableCommitButton,
        enableCommitButtonIfAllowed: enableCommitButtonIfAllowed,
        setAllowCommitMode: setAllowCommitMode,
        setLastMergedRevision: setLastMergedRevision,
        sendSignalToReloadFlowFromGithub: sendSignalToReloadFlowFromGithub
    }

})();
<commit_msg>Show Notifications on commit success<commit_after>RED.gitvcs = (function () {

    var deploymentType = "full";
    var commitAllowed = false;

    var resolveConflictFunction;

    var lastMergedRevision;

    function disableCommitButton() {
        $("#btn-commit").addClass("disabled");
        $("#btn-commit").css("cursor", "default");
        $("#btn-commit").css("background", "#444");
        $("#btn-commit").css("color", "#999");
    }

    function enableCommitButtonIfAllowed() {
        if (commitAllowed) {
            $("#btn-commit").removeClass("disabled");
            $("#btn-commit").css("cursor", "pointer");
            $("#btn-commit").css("background", "#8C101C");
            $("#btn-commit").css("color", "#eee");
            window.onbeforeunload = function() {
                return RED._("deploy.confirm.undeployedChanges");
            };
        }
    }

    function setAllowCommitMode() {
        commitAllowed = true;
    }

    function getAllowCommitMode() {
        return commitAllowed;
    }

    function setDisallowCommitMode() {
        commitAllowed = false;
    }

    function setLastMergedRevision(rev) {
        lastMergedRevision = rev;
        $.ajax({
            url: "/lastMergedRevision?" + (lastMergedRevision ? "lastMergedRevision=" + lastMergedRevision : ""),
            type: "POST"
        })
    }

    function commit() {
        if (!commitAllowed) {
            return;
        }
        var startTime = Date.now();
        $(".deploy-button-content").css('opacity',0);
        $(".deploy-button-spinner").show();

        var nns = RED.nodes.createCompleteNodeSet();
        $.ajax({
            url: "/repositoryflows?" + (lastMergedRevision ? "lastMergedRevision=" + lastMergedRevision : ""),
            type: "POST",
            data: JSON.stringify(nns),
            contentType: "application/json; charset=utf-8",
            headers: {
                "Node-RED-Deployment-Type": deploymentType
            }
        })
            .done(function () {
                RED.notify(RED._("Successfully committed"),"success");
                RED.nodes.originalFlow(nns);
                lastMergedRevision = null;
                disableCommitButton();
                setDisallowCommitMode();
                window.onbeforeunload = null;
            })
            .fail(function (xhr, textStatus, err) {
                RED.notify(RED._("notification.error",{message:xhr.responseText}), "error");
                if (xhr.status === 409) {
                    sendSignalToReloadFlowFromGithub(function() {
                        if (resolveConflictFunction) resolveConflictFunction(nns);
                    });
                }
            }).always(function(){
                var delta = Math.max(0,300-(Date.now()-startTime));
                setTimeout(function() {
                    $(".deploy-button-content").css('opacity',1);
                    $(".deploy-button-spinner").hide();
                },delta);
            });
    }

    function sendSignalToReloadFlowFromGithub(callback) {
        $.ajax({
            url: "/repositorymode",
            type: "POST",
            // data: JSON.stringify(data),
            // contentType: "application/json; charset=utf-8",
            headers: {
                "Node-RED-Deployment-Type": deploymentType
            }
        }).done(function (data, textStatus, xhr) {
            callback();
        });
    }

    function init(resolveConflictFunc) {
        $('' +
            'Commit to Github' +
            '' +
                '' +
            '' +
            '').prependTo(".header-toolbar");

        disableCommitButton();
        $('#btn-commit').click(commit);

        resolveConflictFunction = resolveConflictFunc;
    }

    return {
        init: init,
        //commit: commit,

        disableCommitButton: disableCommitButton,
        enableCommitButtonIfAllowed: enableCommitButtonIfAllowed,
        setAllowCommitMode: setAllowCommitMode,
        setLastMergedRevision: setLastMergedRevision,
        sendSignalToReloadFlowFromGithub: sendSignalToReloadFlowFromGithub
    }

})();
<|endoftext|>


<commit_before>/*!
 * iFrame-Embed multi-function iframe embed script v2.0.0
 * https://github.com/ExSituMarketing/iFrame-Embed
 *
 * Copyright 2015 Ex Situ Marketing
 * Released under the MIT license
 */
window.document.getElementsByClassName=function(e){for(var t=[],n=this.getElementsByTagName("*"),r=0;r<n.length;r++)(" "+n[r].className+" ").indexOf(" "+e+" ")>-1&&t.push(n[r]);return t},function(e,t){t.init=function(e,t){t.document=e.document,t.params={hasResponsive:!1,hasRefresh:!1,asyncImpressionLog:!0,mobileWidth:600,isActiveWindow:!0},t.elements={},t.current=null,t.fwidth={},t.fheight={},t.responsiveSteps={300:"250",728:"90",962:"102",1144:"250",600:"250"},t.messageID={},t.timerID={},t.inTimerID={},t.refreshTimer={mobile:6e3,desktop:12e3}},t.totalViewportTimer=0,t.inViewportTimer=0,t.setDocument=function(e){t.document=e},t.getClient=function(){return Math.max(t.document.documentElement.clientWidth,e.innerWidth||0)<=t.params.mobileWidth?"mobile":"desktop"},t.defaultTimerID=function(e){return e&&e.id&&!t.timerID[e.id]?(t.timerID[e.id]=0,t.timerID[e.id]):!1},t.handleRefresh=function(e){return null===e?!1:(t.defaultTimerID(e),"true"===t.isAutoRefresh(e)&&t.inViewport(e.id)!==!1&&t.params.isActiveWindow===!0&&t.startTimer(e),!0)},t.inTimer=function(){try{return"true"===t.isAutoRefresh(this)&&t.inViewport(this.id)!==!1&&t.params.isActiveWindow===!0?(t.loadFrame(this),!0):(t.stopTimer(this),!1)}catch(e){return!1}},t.startTimer=function(e){try{return("undefined"==typeof t.timerID[e.id]||0===t.timerID[e.id])&&(t.timerID[e.id]=setInterval(t.inTimer.bind(e),t.refreshTimer[t.getClient()])),!0}catch(n){return!1}},t.stopTimer=function(e){try{clearInterval(t.timerID[e.id]),t.timerID[e.id]=0}catch(n){return!1}return!0},t.inViewport=function(e){try{var n=t.getWindowSize(),r=t.getViewportSize(n),i=t.getBoundPos(e,n);return!(r.right<i.left||r.left>i.right||r.bottom<Number(i.top)+Number(n.scrollTop)||i.bottom<0)}catch(o){return!0}},t.getBoundPos=function(e,t){var n=document.getElementById(e),r=document.getElementById(e).getBoundingClientRect();return r.right=Number(r.left)+Number(t.scrollLeft)+Number(n.width),r.bottom=Number(r.top)+Number(t.scrollTop)+Number(n.height),r},t.getViewportSize=function(e){return{top:e.scrollTop,left:e.scrollLeft,right:e.scrollLeft+e.width,bottom:e.scrollTop+e.height}},t.getWindowSize=function(){return{scrollLeft:t.getScrollLeft(),scrollTop:t.getScrollTop(),width:t.getParentWidthPos(),height:t.getParentHeightPos()}},t.getScrollLeft=function(){return void 0!==e.pageXOffset?e.pageXOffset:(document.body||document.body.parentNode||document.documentElement).scrollLeft},t.getScrollTop=function(){return void 0!==e.pageYOffset?e.pageYOffset:(document.body||document.body.parentNode||document.documentElement).scrollTop},t.getParentWidthPos=function(){return e.innerWidth||document.documentElement.clientWidth||document.body.clientWidth},t.getParentHeightPos=function(){return e.innerHeight||document.documentElement.clientHeight||document.body.clientHeight},t.appendFramewidth=function(e,n){return"true"===t.isResponsive(n)&&e.push("frameWidth="+t.fwidth[n.id]),e},t.appendAsyncImpressionLogging=function(e){return t.params.asyncImpressionLog===!0&&e.push("ail=1"),e},t.getCurrentUrl=function(t){var n=e.location.href;return n&&t.push("ref="+n),t},t.getUrlAppend=function(e){var n=[];return t.appendFramewidth(n,e),t.appendAsyncImpressionLogging(n),t.getCurrentUrl(n),t.niceQueryString(n)},t.niceQueryString=function(e){return e.length>0?"?"+e.join("&"):""},t.getParentWidth=function(e){try{return e.parentNode.offsetWidth}catch(t){return e.width}},t.getReponsiveFrameWidth=function(e){var t=e;return t=600>e?"300":728>e&&e>=600?"600":962>e&&e>=728?"728":1144>e&&e>=962?"962":"1144"},t.setIframeParams=function(e){t.isAutoRefresh(e),"true"===t.isResponsive(e)?(t.fwidth[e.id]=t.getReponsiveFrameWidth(t.getParentWidth(e)),t.fheight[e.id]=t.responsiveSteps[t.fwidth[e.id]]):(t.fwidth[e.id]=t.getFrameWidth(e),t.fheight[e.id]=t.getFrameHeight(e))},t.getFrameWidth=function(e){try{return e.width}catch(t){return 0}},t.getFrameHeight=function(e){try{return e.height}catch(t){return 0}},t.getDatasetDomainFromLocation=function(e){try{var n=t.getDataset(e,"data-loc").split("/");return n[0]}catch(r){return!1}},t.getDatasetLocation=function(e){try{return t.getDataset(e,"data-loc")}catch(n){return""}},t.isAutoRefresh=function(e){var n=t.getDatasetBoolean(e,"data-ref");return"true"===n&&(t.params.hasRefresh=!0),n},t.isResponsive=function(e){var n=t.getDatasetBoolean(e,"data-res");return"true"===n&&(t.params.hasResponsive=!0),n},t.getLocation=function(e){var n=t.document.location.protocol+"//"+t.getDatasetLocation(e)+t.getUrlAppend(e);return n},t.loadFrame=function(e){try{t.inViewportTimer=0,t.setIframeParams(e),e.src=t.getLocation(e),e.width=t.fwidth[e.id],e.height=t.fheight[e.id],e.style.display="block",e.onload=function(){t.postMessageSender(e)}}catch(n){return!1}},t.getDatasetBoolean=function(e,n){try{return t.getDataset(e,n)}catch(r){return!1}},t.getDataset=function(e,t){var n=e.getAttribute(t);return n},t.loadResponsiveFrames=function(e){"true"===t.isResponsive(e)&&t.getReponsiveFrameWidth(t.getParentWidth(e))!==t.getFrameWidth(e)&&t.loadFrame(e)},t.setIsActiveWindow=function(){t.params.isActiveWindow=!0,t.executeRefresh()},t.setIsInActiveWindow=function(){t.params.isActiveWindow=!1},t.MoveAway=function(){var e=t.getDatasetDomainFromLocation(t.current);t.current.contentWindow.postMessage("total|"+t.totalViewportTimer,"http://"+e)},t.executeResponsive=function(){t.params.hasResponsive===!0&&t.each("loadResponsiveFrames")},t.executeRefresh=function(){t.params.hasRefresh===!0&&t.each("handleRefresh")},t.execute=function(){t.each("loadFrame")},t.each=function(e){for(var n=0;n<t.elements.length;n++)"undefined"!=typeof t.elements[n]&&t[e](t.elements[n])},t.attachListeners=function(){t.attacheRefreshListeners(),t.attacheResponsiveListeners(),t.attachActiveWindowListeners(),t.attachMoveAwayListeners()},t.attacheRefreshListeners=function(){e.addEventListener?e.addEventListener("scroll",t.executeRefresh,!1):e.attachEvent("onscroll",t.executeRefresh)},t.attachActiveWindowListeners=function(){e.onfocus=t.setIsActiveWindow,e.onblur=t.setIsInActiveWindow},t.attachMoveAwayListeners=function(){"undefined"!=t.totalViewportTimer&&t.totalViewportTimer<900&&(e.onbeforeunload=t.MoveAway)},t.attacheResponsiveListeners=function(){e.onresize=t.executeResponsive},t.asyncImpressionLogger=function(){try{t.sendLog()}catch(e){return!1}},t.sendLog=function(){var e=t.getDatasetDomainFromLocation(t.current);t.inViewport(t.current.id)!==!1&&e!==!1&&t.params.isActiveWindow===!0?(t.totalViewportTimer++,t.inViewportTimer++,t.current.contentWindow.postMessage("in|"+t.inViewportTimer,"http://"+e)):t.inViewportTimer=0},t.postMessageSender=function(e){t.params.asyncImpressionLog===!0&&(t.stopMessage(e),t.startMessage(e))},t.stopMessage=function(e){t.messageID[e.id]&&(clearInterval(t.messageID[e.id]),t.messageID[e.id]=0)},t.startMessage=function(e){t.current=e,("undefined"==typeof t.messageID[e.id]||0===t.messageID[e.id])&&(t.messageID[e.id]=setInterval(t.asyncImpressionLogger,1e3))},t.run=function(){t.document=e.document,t.elements=t.document.getElementsByClassName("aoembed"),t.attachListeners(),t.execute(),t.executeRefresh()},function(){t.init(e,t),t.run()}()}(window,AOembed=window.AOembed||{}),function(e,t){function n(n,r){function i(o){t.removeEventListener("DOMContentLoaded",i),n.call(r||e,o)}function o(i){"complete"===t.readyState&&(t.detachEvent("onreadystatechange",o),n.call(r||e,i))}t.addEventListener&&t.addEventListener("DOMContentLoaded",i)||t.attachEvent&&t.attachEvent("onreadystatechange",o)}e.domReady=n}(window,document),domReady(function(){AOembed.run()}),Function.prototype.bind||(Function.prototype.bind=function(e){if("function"!=typeof this)return!1;var t=Array.prototype.slice.call(arguments,1),n=this,r=function(){},i=function(){return n.apply(this instanceof r&&e?this:e,t.concat(Array.prototype.slice.call(arguments)))};return r.prototype=this.prototype,i.prototype=new r,i});<commit_msg>MOD: clean up app parameters<commit_after>/*!
 * iFrame-Embed multi-function iframe embed script v2.0.0
 * https://github.com/ExSituMarketing/iFrame-Embed
 *
 * Copyright 2015 Ex Situ Marketing
 * Released under the MIT license
 */
window.document.getElementsByClassName=function(cl){var retnode=[];var elem=this.getElementsByTagName("*");for(var i=0;i<elem.length;i++){if((" "+elem[i].className+" ").indexOf(" "+cl+" ")>-1)retnode.push(elem[i])}return retnode};(function(window,ao){ao.init=function(window,ao){ao.document=window.document;ao.params={hasResponsive:false,hasRefresh:false,asyncImpressionLog:true,mobileWidth:600,isActiveWindow:true},ao.elements={},ao.current=null,ao.fwidth={},ao.fheight={},ao.responsiveSteps={300:"250",728:"90",962:"102",1144:"250",600:"250"},ao.messageID={},ao.timerID={},ao.inTimerID={},ao.refreshTimer={mobile:6e3,desktop:12e3}},ao.totalViewportTimer=0;ao.inViewportTimer=0;ao.setDocument=function(doc){ao.document=doc},ao.getClient=function(){if(Math.max(ao.document.documentElement.clientWidth,window.innerWidth||0)<=ao.params.mobileWidth){return"mobile"}return"desktop"},ao.defaultTimerID=function(e){if(e&&e.id&&!ao.timerID[e.id]){ao.timerID[e.id]=0}else{return false}return ao.timerID[e.id]},ao.handleRefresh=function(e){if(e===null){return false}ao.defaultTimerID(e);if(ao.isAutoRefresh(e)==="true"&&ao.inViewport(e.id)!==false&&ao.params.isActiveWindow===true){ao.startTimer(e)}return true},ao.inTimer=function(){try{if(ao.isAutoRefresh(this)==="true"&&ao.inViewport(this.id)!==false&&ao.params.isActiveWindow===true){ao.loadFrame(this);return true}else{ao.stopTimer(this);return false}}catch(ex){return false}},ao.startTimer=function(e){try{if(typeof ao.timerID[e.id]==="undefined"||ao.timerID[e.id]===0){ao.timerID[e.id]=setInterval(ao.inTimer.bind(e),ao.refreshTimer[ao.getClient()])}return true}catch(ex){return false}},ao.stopTimer=function(e){try{clearInterval(ao.timerID[e.id]);ao.timerID[e.id]=0}catch(ex){return false}return true},ao.inViewport=function(id){try{var windowSize=ao.getWindowSize();var viewport=ao.getViewportSize(windowSize);var bounds=ao.getBoundPos(id,windowSize);return!(viewport.right<bounds.left||viewport.left>bounds.right||viewport.bottom<Number(bounds.top)+Number(windowSize.scrollTop)||bounds.bottom<0)}catch(ex){return true}},ao.getBoundPos=function(id,windowSize){var AoFrame=document.getElementById(id);var bounds=document.getElementById(id).getBoundingClientRect();bounds.right=Number(bounds.left)+Number(windowSize.scrollLeft)+Number(AoFrame.width);bounds.bottom=Number(bounds.top)+Number(windowSize.scrollTop)+Number(AoFrame.height);return bounds},ao.getViewportSize=function(windowSize){return{top:windowSize.scrollTop,left:windowSize.scrollLeft,right:windowSize.scrollLeft+windowSize.width,bottom:windowSize.scrollTop+windowSize.height}},ao.getWindowSize=function(){return{scrollLeft:ao.getScrollLeft(),scrollTop:ao.getScrollTop(),width:ao.getParentWidthPos(),height:ao.getParentHeightPos()}},ao.getScrollLeft=function(){return window.pageXOffset!==undefined?window.pageXOffset:(document.body||document.body.parentNode||document.documentElement).scrollLeft},ao.getScrollTop=function(){return window.pageYOffset!==undefined?window.pageYOffset:(document.body||document.body.parentNode||document.documentElement).scrollTop},ao.getParentWidthPos=function(){return window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth},ao.getParentHeightPos=function(){return window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight},ao.appendFramewidth=function(a,e){if(ao.isResponsive(e)==="true"){a.push("frameWidth="+ao.fwidth[e.id])}return a},ao.appendAsyncImpressionLogging=function(a){if(ao.params.asyncImpressionLog===true){a.push("ail=1")}return a},ao.getCurrentUrl=function(a){var currentUrl=window.location.href;if(currentUrl){a.push("ref="+currentUrl)}return a},ao.getUrlAppend=function(e){var append=[];ao.appendFramewidth(append,e);ao.appendAsyncImpressionLogging(append);ao.getCurrentUrl(append);return ao.niceQueryString(append)},ao.niceQueryString=function(args){if(args.length>0){return"?"+args.join("&")}return""},ao.getParentWidth=function(e){try{return e.parentNode.offsetWidth}catch(ex){return e.width}},ao.getReponsiveFrameWidth=function(w){var fWidth=w;if(w<600){fWidth="300"}else if(w<728&&w>=600){fWidth="600"}else if(w<962&&w>=728){fWidth="728"}else if(w<1144&&w>=962){fWidth="962"}else{fWidth="1144"}return fWidth},ao.setIframeParams=function(e){ao.isAutoRefresh(e);if(ao.isResponsive(e)==="true"){ao.fwidth[e.id]=ao.getReponsiveFrameWidth(ao.getParentWidth(e));ao.fheight[e.id]=ao.responsiveSteps[ao.fwidth[e.id]]}else{ao.fwidth[e.id]=ao.getFrameWidth(e);ao.fheight[e.id]=ao.getFrameHeight(e)}},ao.getFrameWidth=function(e){try{return e.width}catch(ex){return 0}},ao.getFrameHeight=function(e){try{return e.height}catch(ex){return 0}},ao.getDatasetDomainFromLocation=function(e){try{var arr=ao.getDataset(e,"data-loc").split("/");return arr[0]}catch(ex){return false}},ao.getDatasetLocation=function(e){try{return ao.getDataset(e,"data-loc")}catch(ex){return""}},ao.isAutoRefresh=function(e){var refresh=ao.getDatasetBoolean(e,"data-ref");if(refresh==="true"){ao.params.hasRefresh=true}return refresh},ao.isResponsive=function(e){var responsive=ao.getDatasetBoolean(e,"data-res");if(responsive==="true"){ao.params.hasResponsive=true}return responsive},ao.getLocation=function(r){var loc=ao.document.location.protocol+"//"+ao.getDatasetLocation(r)+ao.getUrlAppend(r);return loc},ao.loadFrame=function(e){try{ao.inViewportTimer=0;ao.setIframeParams(e);e.src=ao.getLocation(e);e.width=ao.fwidth[e.id];e.height=ao.fheight[e.id];e.style.display="block";e.onload=function(){ao.postMessageSender(e)}}catch(ex){return false}},ao.getDatasetBoolean=function(e,a){try{return ao.getDataset(e,a)}catch(ex){return false}},ao.getDataset=function(e,a){var dset=e.getAttribute(a);return dset},ao.loadResponsiveFrames=function(e){if(ao.isResponsive(e)==="true"&&ao.getReponsiveFrameWidth(ao.getParentWidth(e))!==ao.getFrameWidth(e)){ao.loadFrame(e)}},ao.setIsActiveWindow=function(){ao.params.isActiveWindow=true;ao.executeRefresh()},ao.setIsInActiveWindow=function(){ao.params.isActiveWindow=false},ao.MoveAway=function(){var target=ao.getDatasetDomainFromLocation(ao.current);ao.current.contentWindow.postMessage("total|"+ao.totalViewportTimer,"http://"+target)},ao.executeResponsive=function(){if(ao.params.hasResponsive===true){ao.each("loadResponsiveFrames")}},ao.executeRefresh=function(){if(ao.params.hasRefresh===true){ao.each("handleRefresh")}},ao.execute=function(){ao.each("loadFrame")},ao.each=function(m){for(var i=0;i<ao.elements.length;i++){if(typeof ao.elements[i]!=="undefined"){ao[m](ao.elements[i])}}},ao.attachListeners=function(){ao.attacheRefreshListeners();ao.attacheResponsiveListeners();ao.attachActiveWindowListeners();ao.attachMoveAwayListeners()},ao.attacheRefreshListeners=function(){if(window.addEventListener){window.addEventListener("scroll",ao.executeRefresh,false)}else{window.attachEvent("onscroll",ao.executeRefresh)}},ao.attachActiveWindowListeners=function(){window.onfocus=ao.setIsActiveWindow;window.onblur=ao.setIsInActiveWindow},ao.attachMoveAwayListeners=function(){if(ao.totalViewportTimer!="undefined"&&ao.totalViewportTimer<900){window.onbeforeunload=ao.MoveAway}},ao.attacheResponsiveListeners=function(){window.onresize=ao.executeResponsive},ao.asyncImpressionLogger=function(){try{ao.sendLog()}catch(ex){return false}},ao.sendLog=function(){var target=ao.getDatasetDomainFromLocation(ao.current);if(ao.inViewport(ao.current.id)!==false&&target!==false&&ao.params.isActiveWindow===true){ao.totalViewportTimer++;ao.inViewportTimer++;ao.current.contentWindow.postMessage("in|"+ao.inViewportTimer,"http://"+target)}else{ao.inViewportTimer=0}},ao.postMessageSender=function(e){if(ao.params.asyncImpressionLog===true){ao.stopMessage(e);ao.startMessage(e)}},ao.stopMessage=function(e){if(ao.messageID[e.id]){clearInterval(ao.messageID[e.id]);ao.messageID[e.id]=0}},ao.startMessage=function(e){ao.current=e;if(typeof ao.messageID[e.id]==="undefined"||ao.messageID[e.id]===0){ao.messageID[e.id]=setInterval(ao.asyncImpressionLogger,1e3)}},ao.run=function(){ao.document=window.document;ao.elements=ao.document.getElementsByClassName("aoembed");ao.attachListeners();ao.execute();ao.executeRefresh()},function(){ao.init(window,ao);ao.run()}()})(window,AOembed=window.AOembed||{});(function(exports,d){function domReady(fn,context){function onReady(event){d.removeEventListener("DOMContentLoaded",onReady);fn.call(context||exports,event)}function onReadyIe(event){if(d.readyState==="complete"){d.detachEvent("onreadystatechange",onReadyIe);fn.call(context||exports,event)}}d.addEventListener&&d.addEventListener("DOMContentLoaded",onReady)||d.attachEvent&&d.attachEvent("onreadystatechange",onReadyIe)}exports.domReady=domReady})(window,document);domReady(function(){AOembed.run()});if(!Function.prototype.bind){Function.prototype.bind=function(oThis){if(typeof this!=="function"){return false}var aArgs=Array.prototype.slice.call(arguments,1),fToBind=this,fNOP=function(){},fBound=function(){return fToBind.apply(this instanceof fNOP&&oThis?this:oThis,aArgs.concat(Array.prototype.slice.call(arguments)))};fNOP.prototype=this.prototype;fBound.prototype=new fNOP;return fBound}}<|endoftext|>


<commit_before>module.exports = {
  rules: {
    'no-extraneous-dependencies': require('./no-extraneous-dependencies'),
  },
  configs: {
    recommended: {
      rules: {
        'silk/no-extraneous-dependencies': ['error', {
          allowSelf: true,
          devDependencies: [
            'test/**/*.js',
            'tools/**/*.js',
            '**/webpack.config.js',
          ],
          optionalDependencies: true,
          peerDependencies: true,
          symlinkDependencies: true,
        }],
      },
    },
  },
};
<commit_msg>eslint-plugin-silk: bin/* are generally dev-only tools<commit_after>module.exports = {
  rules: {
    'no-extraneous-dependencies': require('./no-extraneous-dependencies'),
  },
  configs: {
    recommended: {
      rules: {
        'silk/no-extraneous-dependencies': ['error', {
          allowSelf: true,
          devDependencies: [
            'test/**/*.js',
            'tools/**/*.js',
            'bin/**/*.js',
            '**/webpack.config.js',
          ],
          optionalDependencies: true,
          peerDependencies: true,
          symlinkDependencies: true,
        }],
      },
    },
  },
};
<|endoftext|>


<commit_before>var querystring = require('querystring');
var moment = require('moment');
var utils = require('./utils');
var config = require('./config');

function constructAddress(venue) {
  var address = '';

  if (venue) {
    address = venue.name + ', ' + venue.address_1 || '' + (venue.address_2 ? ', ' + venue.address_2 : '');
    address += address.indexOf(config.meetupParams.city) === -1 ? ', ' + config.meetupParams.city : '';
    console.log(address)
  } else {
    address = config.meetupParams.city;
  }

  return address;
}

function isValidGroup(row) {
  'use strict';

  var blacklistGroups = config.blacklistGroups || [];
  var blacklistWords = config.blacklistWords || [];
  var blacklistRE = new RegExp(blacklistWords.join('|'), 'i');

  // Enforce country filter. Meetup adds JB groups into SG
  return blacklistWords.length === 0 ? true : !row.name.match(blacklistRE) && !blacklistGroups.some(function(id) { return row.id === id }) && row.country === (config.meetupParams.country || row.country);
}

function findGroupEvents(eventsArr, row) {
  'use strict';

  if (!(row.next_event && row.next_event.time)) return eventsArr;

  var entry = {
    id: row.next_event.id,
    name: row.next_event.name,
    description: utils.htmlStrip(row.description),
    location: '',
    url: 'http://meetup.com/' + row.urlname + '/events/' + row.next_event.id,
    group_name: row.name,
    group_url: row.link,
    formatted_time: moment.utc(row.next_event.time + row.next_event.utc_offset).format(utils.timeformat),
    start_time: moment.utc(row.next_event.time).zone(row.next_event.utc_offset).toISOString()
  }
  eventsArr.push(entry);

  return eventsArr;
}

function findCommunityEvents(eventsArr, row) {
  'use strict';

  if (!(row.time && row.venue_name)) return eventsArr;

  var event_time = moment.utc(row.time).zone('+0800')
  row.name = row.venue_name;
  row.address_1 = row.address1 || '';

  var entry = {
    id: row.id.toString(),
    name: row.short_description,
    description: utils.htmlStrip(row.description),
    location: constructAddress(row),
    url: row.meetup_url,
    group_name: row.container.name + ' Community',
    group_url: 'http://meetup.com/' + row.container.urlname + '/' + row.community.urlname,
    formatted_time: event_time.format(utils.timeformat),
    start_time: event_time.toISOString(),
    end_time: event_time.add('milliseconds', 7200000).toISOString()
  }
  eventsArr.push(entry);

  return eventsArr;
}

function findEventsWithVenues(eventsData) {
  return function(evt, i) {
    if (eventsData[i].hasOwnProperty('venue') || eventsData[i].venue_visibility === 'members') {
      if (eventsData[i].duration === undefined) {
        eventsData[i].duration = 7200000
      }
      evt.location = constructAddress(eventsData[i].venue);
      evt.end_time = moment.utc(evt.start_time).add('milliseconds', eventsData[i].duration).zone(evt.start_time).toISOString();
      return true;
    }
  }
}

function getMeetupGroups() { //regardless of venue
  'use strict';

  var url = 'https://api.meetup.com/2/groups?' +
    querystring.stringify(config.meetupParams);

  return utils.prequest(url).then(function(data) {
    console.log('Fetched ' + data.results.length + ' Meetup groups');
    var events = [];
    data.results
      .filter(isValidGroup)
      .reduce(findGroupEvents, events);
    return events;
  }).catch(function(err) {
    console.error('Error getMeetupGroups(): ' + err);
  });
}

function getMeetupCommunityEvents() {
  'use strict';

  var url = 'https://api.meetup.com/ew/events?' +
    querystring.stringify({
      key: config.meetupParams.key,
      country: config.meetupParams.country,
      city: config.meetupParams.city,
      urlname: config.meetupCommunities.join(','),
      after: '0d'
    });

  return utils.prequest(url).then(function(data) {
    console.log(data.results.length + ' Meetup community events with venues');
    var events = [];
    data.results.reduce(findCommunityEvents, events);
    return events;
  }).catch(function(err) {
    console.error('Error getMeetupCommunityEvents(): ' + err);
  });
}

function getMeetupEvents() { //events with eventsData
  'use strict';

  return getMeetupGroups().then(function(events) {
    console.log('Fetched ' + events.length + ' Meetup group events');
    var eventReqs = events.map(function(event) {
      return utils.prequest('https://api.meetup.com/2/event/'+ event.id + '?fields=venue_visibility&key='+ config.meetupParams.key);
    });

    return utils.waitAllPromises(eventReqs).then(function(eventsData) {
      return getMeetupCommunityEvents().then(function(communityEvents) {
        var eventsWithVenues = events.filter(findEventsWithVenues(eventsData));
        eventsWithVenues = eventsWithVenues.concat(communityEvents);
        console.log(eventsWithVenues.length + ' Meetup events with venues');
        return eventsWithVenues;
      });
    }).catch(function(err) {
      console.error('Error getMeetupEvents(): ' + err);
    });
  });
}

exports.get = getMeetupEvents;
<commit_msg>Fixed jshint<commit_after>var querystring = require('querystring');
var moment = require('moment');
var utils = require('./utils');
var config = require('./config');

function constructAddress(venue) {
  'use strict';

  var address = '';

  if (venue) {
    address = venue.name + ', ' + venue.address_1 || '' + (venue.address_2 ? ', ' + venue.address_2 : '');
    address += address.indexOf(config.meetupParams.city) === -1 ? ', ' + config.meetupParams.city : '';
    console.log(address)
  } else {
    address = config.meetupParams.city;
  }

  return address;
}

function isValidGroup(row) {
  'use strict';

  var blacklistGroups = config.blacklistGroups || [];
  var blacklistWords = config.blacklistWords || [];
  var blacklistRE = new RegExp(blacklistWords.join('|'), 'i');

  // Enforce country filter. Meetup adds JB groups into SG
  return blacklistWords.length === 0 ? true : !row.name.match(blacklistRE) && !blacklistGroups.some(function(id) { return row.id === id }) && row.country === (config.meetupParams.country || row.country);
}

function findGroupEvents(eventsArr, row) {
  'use strict';

  if (!(row.next_event && row.next_event.time)) return eventsArr;

  var entry = {
    id: row.next_event.id,
    name: row.next_event.name,
    description: utils.htmlStrip(row.description),
    location: '',
    url: 'http://meetup.com/' + row.urlname + '/events/' + row.next_event.id,
    group_name: row.name,
    group_url: row.link,
    formatted_time: moment.utc(row.next_event.time + row.next_event.utc_offset).format(utils.timeformat),
    start_time: moment.utc(row.next_event.time).zone(row.next_event.utc_offset).toISOString()
  }
  eventsArr.push(entry);

  return eventsArr;
}

function findCommunityEvents(eventsArr, row) {
  'use strict';

  if (!(row.time && row.venue_name)) return eventsArr;

  var event_time = moment.utc(row.time).zone('+0800')
  row.name = row.venue_name;
  row.address_1 = row.address1 || '';

  var entry = {
    id: row.id.toString(),
    name: row.short_description,
    description: utils.htmlStrip(row.description),
    location: constructAddress(row),
    url: row.meetup_url,
    group_name: row.container.name + ' Community',
    group_url: 'http://meetup.com/' + row.container.urlname + '/' + row.community.urlname,
    formatted_time: event_time.format(utils.timeformat),
    start_time: event_time.toISOString(),
    end_time: event_time.add('milliseconds', 7200000).toISOString()
  }
  eventsArr.push(entry);

  return eventsArr;
}

function findEventsWithVenues(eventsData) {
  'use strict';

  return function(evt, i) {
    if (eventsData[i].hasOwnProperty('venue') || eventsData[i].venue_visibility === 'members') {
      if (eventsData[i].duration === undefined) {
        eventsData[i].duration = 7200000
      }
      evt.location = constructAddress(eventsData[i].venue);
      evt.end_time = moment.utc(evt.start_time).add('milliseconds', eventsData[i].duration).zone(evt.start_time).toISOString();
      return true;
    }
  }
}

function getMeetupGroups() { //regardless of venue
  'use strict';

  var url = 'https://api.meetup.com/2/groups?' +
    querystring.stringify(config.meetupParams);

  return utils.prequest(url).then(function(data) {
    console.log('Fetched ' + data.results.length + ' Meetup groups');
    var events = [];
    data.results
      .filter(isValidGroup)
      .reduce(findGroupEvents, events);
    return events;
  }).catch(function(err) {
    console.error('Error getMeetupGroups(): ' + err);
  });
}

function getMeetupCommunityEvents() {
  'use strict';

  var url = 'https://api.meetup.com/ew/events?' +
    querystring.stringify({
      key: config.meetupParams.key,
      country: config.meetupParams.country,
      city: config.meetupParams.city,
      urlname: config.meetupCommunities.join(','),
      after: '0d'
    });

  return utils.prequest(url).then(function(data) {
    console.log(data.results.length + ' Meetup community events with venues');
    var events = [];
    data.results.reduce(findCommunityEvents, events);
    return events;
  }).catch(function(err) {
    console.error('Error getMeetupCommunityEvents(): ' + err);
  });
}

function getMeetupEvents() { //events with eventsData
  'use strict';

  return getMeetupGroups().then(function(events) {
    console.log('Fetched ' + events.length + ' Meetup group events');
    var eventReqs = events.map(function(event) {
      return utils.prequest('https://api.meetup.com/2/event/'+ event.id + '?fields=venue_visibility&key='+ config.meetupParams.key);
    });

    return utils.waitAllPromises(eventReqs).then(function(eventsData) {
      return getMeetupCommunityEvents().then(function(communityEvents) {
        var eventsWithVenues = events.filter(findEventsWithVenues(eventsData));
        eventsWithVenues = eventsWithVenues.concat(communityEvents);
        console.log(eventsWithVenues.length + ' Meetup events with venues');
        return eventsWithVenues;
      });
    }).catch(function(err) {
      console.error('Error getMeetupEvents(): ' + err);
    });
  });
}

exports.get = getMeetupEvents;
<|endoftext|>