Subversion Repository Public Repository

Nextrek

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    "uid": "3A731523KD345A49DAS903FE171A585AEB27",
    "isLoaded": true,
    "lastModificationTime": 1421095528705,
    "items": {
        "name": "DataOptimizer",
        "type": "game_script",
        "order": 0,
        "content": "# ===================================================================\n#\n#   Script: DataOptimizer\n#\n#   $$COPYRIGHT$$\n#\n# ===================================================================\nclass DataOptimizer\n    ###*\n    * The data optimizer is to optimize data structures coming from data files to\n    * make processing faster. One way of optimization for example is to convert\n    * regular array to typed arrays.\n    *\n    * @module gs\n    * @class DataOptimizer\n    * @memberof gs\n    * @static\n    * @constructor\n    ###\n    constructor: ->\n        @labels = {}\n        @labelJumps = {}\n        \n    ###*\n    * Converts the specified number-array to a typed Int16 array.\n    *\n    * @method arrayToNativeArray\n    * @param {Array} array - The array to convert.\n    * @return {Int16Array} The typed array.\n    * @static\n    ### \n    arrayToNativeArray: (array) ->\n        result = null\n        length = array.length || Object.keys(array).length\n        if array?\n            if window.ArrayBuffer?\n                result = new ArrayBuffer(length * 2)\n                result = new Int16Array(result)\n            else\n                result = new Array(length)\n           \n            \n            for i in [0...length]\n                result[i] = array[i]\n                \n        return result\n    \n    ###*\n    * Creates a typed Int16 array if supported. Otherwise a regular array is created.\n    *\n    * @method nativeArray16\n    * @param {number} size - The size of the array in elements.(Not in bytes).\n    * @return {Int16Array} The Int16 array.\n    * @static\n    ### \n    nativeArray16: (size) ->\n        #result = new ArrayBuffer(size * 2)\n        #result = new Int16Array(result)\n        result = new Array(size)\n        return result\n    \n    ###*\n    * Creates a typed Int8 array if supported. Otherwise a regular array is created.\n    *\n    * @method nativeArray16\n    * @param {number} size - The size of the array in elements.(Not in bytes).\n    * @return {Int8Array} The Int8 array.\n    * @static\n    ###     \n    nativeArray8: (size) ->\n        result = new Array(size)\n        return result\n     \n     \n    ###*\n    * Removes a single empty command like a comment.\n    *\n    * @method removeEmptyCommand\n    * @private\n    * @param {Object[]} commands - A list of commands.\n    * @param {Object} command - The command to optimize.\n    * @static\n    ### \n    removeEmptyCommand: (command, index, commands) ->\n        return no if GameManager.inLivePreview\n        \n        result = no\n        switch commands[index].id\n            when \"gs.Comment\"\n                commands.splice(index, 1)\n                result = yes\n            when \"gs.EmptyCommand\"\n                commands.splice(index, 1)\n                result = yes\n        return result\n     \n    ###*\n    * Checks if a common event call can be optimized by inline it. In special cases,\n    * such as recursion or parameters, an optimization is no possible.\n    *\n    * @method optimizeCommonEventCall\n    * @private\n    * @param {Object[]} commands - A list of commands.\n    * @param {number} index - Index of the command in command-list.\n    * @param {Object} command - The command to optimize.\n    * @return If <b>true</b> the call can be safly inline. Otherwise <b>false</b>\n    * @static\n    ###    \n    canInlineCommonEventCall: (command, index, commands, callStack) ->\n        result = !(command.params.commonEventId.index?)\n        commonEvent = RecordManager.commonEvents[command.params.commonEventId]\n        if commonEvent?.inline\n            if callStack.indexOf(commonEvent) != -1\n                result = no\n            else\n                callStack.push(commonEvent)\n                for c, i in commonEvent.commands\n                    if c.id == \"gs.CallCommonEvent\"\n                        result = @canInlineCommonEventCall(c, i, commonEvent.commands, callStack)\n        \n        return result\n            \n    ###*\n    * Optimizes a common event call.\n    *\n    * @method optimizeCommonEventCall\n    * @private\n    * @param {Object[]} commands - A list of commands.\n    * @param {number} index - Index of the command in command-list.\n    * @param {Object} command - The command to optimize.\n    * @static\n    ### \n    optimizeCommonEventCall: (command, index, commands) ->\n        commonEvent = RecordManager.commonEvents[command.params.commonEventId]\n        if commonEvent?.inline\n            if @canInlineCommonEventCall(command, index, commands, [])\n                commands.splice(index, 1)\n                commands.splice.apply(commands, [index, 0].concat(Object.copy(commonEvent.commands)))\n    \n    ###*\n    * Optimizes the variable-access by replacing the domain-string with the domain-index\n    * value at runtime to allow faster domain access using integer numbers instead of strings.\n    *\n    * @method optimizeVariableAccess\n    * @param {Object} data - The data to opimize, e.g. the params-object of a command.\n    * @static\n    ###             \n    optimizeVariableAccess: (data) ->\n        return if data?.__optimized\n        data?.__optimized = yes \n        for p of data\n            if data[p] instanceof Array and !data[p].__optimized\n                data[p].__optimized = yes\n                for e in data[p]\n                    @optimizeVariableAccess(e)\n            else if p == \"domain\" and data.scope > 0 and data.index?\n                domainIndex = GameManager.variableStore.domains.indexOf(data[p])\n                data[p] = if domainIndex == -1 then data[p] else domainIndex\n            else if typeof data[p] == \"object\" and !(data[p] instanceof String || data[p] instanceof Array)\n                @optimizeVariableAccess(data[p]) if not data[p]?.__optimized\n                data[p]?.__optimized = yes\n       \n    \n    ###*\n    * Optimizes a single sub-message created by {CP} text code. It will split the sub-message into multiple\n    * independent ShowMessage commands at {P} text code.\n    *\n    * @method optimizeSubMessage\n    * @private\n    * @param {string} message - The sub message.\n    * @param {Object} command - The command to optimize.\n    * @param {number} index - Index of the command in command-list.\n    * @param {Object[]} commands - A list of commands.\n    * @return {number} The current command-pointer where add/insert the next command (If necessary).\n    * @static\n    ###  \n    optimizeSubMessage: (message, command, index, commands) ->\n        subMessages = message.split(\"{P}\")\n        for subMessage in subMessages\n            messageCommand = Object.flatCopy(command)\n            messageCommand.params = Object.flatCopy(messageCommand.params)\n            messageCommand.params.message = subMessage.ltrim()\n            commands.splice(index, 0, messageCommand)\n            index++\n                \n        return index\n        \n    ###*\n    * Optimizes a single ShowMessage command. It will split the command into multiple\n    * independent ShowMessage commands at {P} text code for example.\n    *\n    * @method optimizeShowMessage\n    * @private\n    * @param {Object} command - The command to optimize.\n    * @param {number} index - Index of the command in command-list.\n    * @param {Object[]} commands - A list of commands.\n    * @return {number} The current command-pointer where add/insert the next command (If necessary).\n    * @static\n    ###     \n    optimizeShowMessage: (command, index, commands) -> \n        msg = lcs(command.params.message)\n        \n        if msg.contains(\"{CP}\") or msg.contains(\"{P}\")\n            commands.splice(index, 1)\n            subMessages = msg.split(\"{CP}\")\n            for subMessage, i in subMessages\n                index = @optimizeSubMessage(subMessage, command, index, commands)\n                \n                if i < subMessages.length-1\n                    clearCommand = { id: \"gs.ClearMessage\", indent: command.indent, params: { fieldFlags: { duration: 1 }, duration: 30, waitForCompletion: yes } }\n                    commands.splice(index, 0, clearCommand)\n                    index++\n                \n        return index\n        \n    ###*\n    * Optimizes a single command.\n    *\n    * @method optimizeCommand\n    * @private\n    * @param {Object[]} commands - A list of commands.\n    * @param {number} index - Index of the command in command-list.\n    * @param {Object} command - The command to optimize.\n    * @static\n    ###     \n    optimizeCommand: (command, index, commands) ->\n        @optimizeVariableAccess(command.params)\n        \n        switch command.id\n            when \"gs.ShowMessage\"\n                index = @optimizeShowMessage(command, index, commands)\n            when \"gs.CallCommonEvent\"\n                @optimizeCommonEventCall(command, index, commands)\n            when \"gs.Label\"\n                @labels[command.params.name] = index\n                @labelJumps[command.params.name]?.forEach (c) -> c.params.labelIndex = index\n            when \"vn.Choice\"\n                command.params.action.labelIndex = @labels[command.params.action.label]\n                if !@labelJumps[command.params.action.label]\n                    @labelJumps[command.params.action.label] = []\n                @labelJumps[command.params.action.label].push(command)\n            when \"gs.CheckSwitch\", \"gs.CheckNumberVariable\", \"gs.CheckTextVariable\"\n                command.params.labelIndex = @labels[command.params.label]\n                if !@labelJumps[command.params.label]\n                    @labelJumps[command.params.label] = []\n                @labelJumps[command.params.label].push(command)\n            #when \"gs.AddHotspot\"\n            #    command.params.actions.onClick\n            when \"gs.JumpToLabel\"\n                command.params.labelIndex = @labels[command.params.name]\n                if !@labelJumps[command.params.name]\n                    @labelJumps[command.params.name] = []\n                @labelJumps[command.params.name].push(command)\n        \n        return index\n        \n    ###*\n    * Optimizes a list of event/scene commands by removing unnecessary commands like\n    * comments or empty commands. It also optimizes label jumps. Adds an <b>optimized</b> to\n    * the specified command-list to indicate that the list was already optimized. If <b>optimized</b>\n    * property of command-list is set to <b>true</b> this method will return immediately.\n    *\n    * @method optimizeEventCommands\n    * @param {Object[]} commands - A list of commands to optimize.\n    * @static\n    ###       \n    optimizeEventCommands: (commands) ->\n        return if commands.optimized\n\n        i = 0\n        @labels = {}\n        @labelJumps = {}\n        if !$PARAMS.preview\n            while i < commands.length\n                commands[i].indent = commands[i].indent || 0\n                if @removeEmptyCommand(commands[i], i, commands)\n                    i--\n                i++\n        i = 0\n        while i < commands.length\n            i = @optimizeCommand(commands[i], i, commands)\n            i++\n        commands.optimized = yes\n        \n        \nwindow.DataOptimizer = new DataOptimizer()\ngs.DataOptimizer = DataOptimizer",
        "compiledContent": "var DataOptimizer;\n\nDataOptimizer = (function() {\n\n  /**\n  * The data optimizer is to optimize data structures coming from data files to\n  * make processing faster. One way of optimization for example is to convert\n  * regular array to typed arrays.\n  *\n  * @module gs\n  * @class DataOptimizer\n  * @memberof gs\n  * @static\n  * @constructor\n   */\n  function DataOptimizer() {\n    this.labels = {};\n    this.labelJumps = {};\n  }\n\n\n  /**\n  * Converts the specified number-array to a typed Int16 array.\n  *\n  * @method arrayToNativeArray\n  * @param {Array} array - The array to convert.\n  * @return {Int16Array} The typed array.\n  * @static\n   */\n\n  DataOptimizer.prototype.arrayToNativeArray = function(array) {\n    var i, j, length, ref, result;\n    result = null;\n    length = array.length || Object.keys(array).length;\n    if (array != null) {\n      if (window.ArrayBuffer != null) {\n        result = new ArrayBuffer(length * 2);\n        result = new Int16Array(result);\n      } else {\n        result = new Array(length);\n      }\n      for (i = j = 0, ref = length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {\n        result[i] = array[i];\n      }\n    }\n    return result;\n  };\n\n\n  /**\n  * Creates a typed Int16 array if supported. Otherwise a regular array is created.\n  *\n  * @method nativeArray16\n  * @param {number} size - The size of the array in elements.(Not in bytes).\n  * @return {Int16Array} The Int16 array.\n  * @static\n   */\n\n  DataOptimizer.prototype.nativeArray16 = function(size) {\n    var result;\n    result = new Array(size);\n    return result;\n  };\n\n\n  /**\n  * Creates a typed Int8 array if supported. Otherwise a regular array is created.\n  *\n  * @method nativeArray16\n  * @param {number} size - The size of the array in elements.(Not in bytes).\n  * @return {Int8Array} The Int8 array.\n  * @static\n   */\n\n  DataOptimizer.prototype.nativeArray8 = function(size) {\n    var result;\n    result = new Array(size);\n    return result;\n  };\n\n\n  /**\n  * Removes a single empty command like a comment.\n  *\n  * @method removeEmptyCommand\n  * @private\n  * @param {Object[]} commands - A list of commands.\n  * @param {Object} command - The command to optimize.\n  * @static\n   */\n\n  DataOptimizer.prototype.removeEmptyCommand = function(command, index, commands) {\n    var result;\n    if (GameManager.inLivePreview) {\n      return false;\n    }\n    result = false;\n    switch (commands[index].id) {\n      case \"gs.Comment\":\n        commands.splice(index, 1);\n        result = true;\n        break;\n      case \"gs.EmptyCommand\":\n        commands.splice(index, 1);\n        result = true;\n    }\n    return result;\n  };\n\n\n  /**\n  * Checks if a common event call can be optimized by inline it. In special cases,\n  * such as recursion or parameters, an optimization is no possible.\n  *\n  * @method optimizeCommonEventCall\n  * @private\n  * @param {Object[]} commands - A list of commands.\n  * @param {number} index - Index of the command in command-list.\n  * @param {Object} command - The command to optimize.\n  * @return If <b>true</b> the call can be safly inline. Otherwise <b>false</b>\n  * @static\n   */\n\n  DataOptimizer.prototype.canInlineCommonEventCall = function(command, index, commands, callStack) {\n    var c, commonEvent, i, j, len, ref, result;\n    result = !(command.params.commonEventId.index != null);\n    commonEvent = RecordManager.commonEvents[command.params.commonEventId];\n    if (commonEvent != null ? commonEvent.inline : void 0) {\n      if (callStack.indexOf(commonEvent) !== -1) {\n        result = false;\n      } else {\n        callStack.push(commonEvent);\n        ref = commonEvent.commands;\n        for (i = j = 0, len = ref.length; j < len; i = ++j) {\n          c = ref[i];\n          if (c.id === \"gs.CallCommonEvent\") {\n            result = this.canInlineCommonEventCall(c, i, commonEvent.commands, callStack);\n          }\n        }\n      }\n    }\n    return result;\n  };\n\n\n  /**\n  * Optimizes a common event call.\n  *\n  * @method optimizeCommonEventCall\n  * @private\n  * @param {Object[]} commands - A list of commands.\n  * @param {number} index - Index of the command in command-list.\n  * @param {Object} command - The command to optimize.\n  * @static\n   */\n\n  DataOptimizer.prototype.optimizeCommonEventCall = function(command, index, commands) {\n    var commonEvent;\n    commonEvent = RecordManager.commonEvents[command.params.commonEventId];\n    if (commonEvent != null ? commonEvent.inline : void 0) {\n      if (this.canInlineCommonEventCall(command, index, commands, [])) {\n        commands.splice(index, 1);\n        return commands.splice.apply(commands, [index, 0].concat(Object.copy(commonEvent.commands)));\n      }\n    }\n  };\n\n\n  /**\n  * Optimizes the variable-access by replacing the domain-string with the domain-index\n  * value at runtime to allow faster domain access using integer numbers instead of strings.\n  *\n  * @method optimizeVariableAccess\n  * @param {Object} data - The data to opimize, e.g. the params-object of a command.\n  * @static\n   */\n\n  DataOptimizer.prototype.optimizeVariableAccess = function(data) {\n    var domainIndex, e, p, ref, ref1, results;\n    if (data != null ? data.__optimized : void 0) {\n      return;\n    }\n    if (data != null) {\n      data.__optimized = true;\n    }\n    results = [];\n    for (p in data) {\n      if (data[p] instanceof Array && !data[p].__optimized) {\n        data[p].__optimized = true;\n        results.push((function() {\n          var j, len, ref, results1;\n          ref = data[p];\n          results1 = [];\n          for (j = 0, len = ref.length; j < len; j++) {\n            e = ref[j];\n            results1.push(this.optimizeVariableAccess(e));\n          }\n          return results1;\n        }).call(this));\n      } else if (p === \"domain\" && data.scope > 0 && (data.index != null)) {\n        domainIndex = GameManager.variableStore.domains.indexOf(data[p]);\n        results.push(data[p] = domainIndex === -1 ? data[p] : domainIndex);\n      } else if (typeof data[p] === \"object\" && !(data[p] instanceof String || data[p] instanceof Array)) {\n        if (!((ref = data[p]) != null ? ref.__optimized : void 0)) {\n          this.optimizeVariableAccess(data[p]);\n        }\n        results.push((ref1 = data[p]) != null ? ref1.__optimized = true : void 0);\n      } else {\n        results.push(void 0);\n      }\n    }\n    return results;\n  };\n\n\n  /**\n  * Optimizes a single sub-message created by {CP} text code. It will split the sub-message into multiple\n  * independent ShowMessage commands at {P} text code.\n  *\n  * @method optimizeSubMessage\n  * @private\n  * @param {string} message - The sub message.\n  * @param {Object} command - The command to optimize.\n  * @param {number} index - Index of the command in command-list.\n  * @param {Object[]} commands - A list of commands.\n  * @return {number} The current command-pointer where add/insert the next command (If necessary).\n  * @static\n   */\n\n  DataOptimizer.prototype.optimizeSubMessage = function(message, command, index, commands) {\n    var j, len, messageCommand, subMessage, subMessages;\n    subMessages = message.split(\"{P}\");\n    for (j = 0, len = subMessages.length; j < len; j++) {\n      subMessage = subMessages[j];\n      messageCommand = Object.flatCopy(command);\n      messageCommand.params = Object.flatCopy(messageCommand.params);\n      messageCommand.params.message = subMessage.ltrim();\n      commands.splice(index, 0, messageCommand);\n      index++;\n    }\n    return index;\n  };\n\n\n  /**\n  * Optimizes a single ShowMessage command. It will split the command into multiple\n  * independent ShowMessage commands at {P} text code for example.\n  *\n  * @method optimizeShowMessage\n  * @private\n  * @param {Object} command - The command to optimize.\n  * @param {number} index - Index of the command in command-list.\n  * @param {Object[]} commands - A list of commands.\n  * @return {number} The current command-pointer where add/insert the next command (If necessary).\n  * @static\n   */\n\n  DataOptimizer.prototype.optimizeShowMessage = function(command, index, commands) {\n    var clearCommand, i, j, len, msg, subMessage, subMessages;\n    msg = lcs(command.params.message);\n    if (msg.contains(\"{CP}\") || msg.contains(\"{P}\")) {\n      commands.splice(index, 1);\n      subMessages = msg.split(\"{CP}\");\n      for (i = j = 0, len = subMessages.length; j < len; i = ++j) {\n        subMessage = subMessages[i];\n        index = this.optimizeSubMessage(subMessage, command, index, commands);\n        if (i < subMessages.length - 1) {\n          clearCommand = {\n            id: \"gs.ClearMessage\",\n            indent: command.indent,\n            params: {\n              fieldFlags: {\n                duration: 1\n              },\n              duration: 30,\n              waitForCompletion: true\n            }\n          };\n          commands.splice(index, 0, clearCommand);\n          index++;\n        }\n      }\n    }\n    return index;\n  };\n\n\n  /**\n  * Optimizes a single command.\n  *\n  * @method optimizeCommand\n  * @private\n  * @param {Object[]} commands - A list of commands.\n  * @param {number} index - Index of the command in command-list.\n  * @param {Object} command - The command to optimize.\n  * @static\n   */\n\n  DataOptimizer.prototype.optimizeCommand = function(command, index, commands) {\n    var ref;\n    this.optimizeVariableAccess(command.params);\n    switch (command.id) {\n      case \"gs.ShowMessage\":\n        index = this.optimizeShowMessage(command, index, commands);\n        break;\n      case \"gs.CallCommonEvent\":\n        this.optimizeCommonEventCall(command, index, commands);\n        break;\n      case \"gs.Label\":\n        this.labels[command.params.name] = index;\n        if ((ref = this.labelJumps[command.params.name]) != null) {\n          ref.forEach(function(c) {\n            return c.params.labelIndex = index;\n          });\n        }\n        break;\n      case \"vn.Choice\":\n        command.params.action.labelIndex = this.labels[command.params.action.label];\n        if (!this.labelJumps[command.params.action.label]) {\n          this.labelJumps[command.params.action.label] = [];\n        }\n        this.labelJumps[command.params.action.label].push(command);\n        break;\n      case \"gs.CheckSwitch\":\n      case \"gs.CheckNumberVariable\":\n      case \"gs.CheckTextVariable\":\n        command.params.labelIndex = this.labels[command.params.label];\n        if (!this.labelJumps[command.params.label]) {\n          this.labelJumps[command.params.label] = [];\n        }\n        this.labelJumps[command.params.label].push(command);\n        break;\n      case \"gs.JumpToLabel\":\n        command.params.labelIndex = this.labels[command.params.name];\n        if (!this.labelJumps[command.params.name]) {\n          this.labelJumps[command.params.name] = [];\n        }\n        this.labelJumps[command.params.name].push(command);\n    }\n    return index;\n  };\n\n\n  /**\n  * Optimizes a list of event/scene commands by removing unnecessary commands like\n  * comments or empty commands. It also optimizes label jumps. Adds an <b>optimized</b> to\n  * the specified command-list to indicate that the list was already optimized. If <b>optimized</b>\n  * property of command-list is set to <b>true</b> this method will return immediately.\n  *\n  * @method optimizeEventCommands\n  * @param {Object[]} commands - A list of commands to optimize.\n  * @static\n   */\n\n  DataOptimizer.prototype.optimizeEventCommands = function(commands) {\n    var i;\n    if (commands.optimized) {\n      return;\n    }\n    i = 0;\n    this.labels = {};\n    this.labelJumps = {};\n    if (!$PARAMS.preview) {\n      while (i < commands.length) {\n        commands[i].indent = commands[i].indent || 0;\n        if (this.removeEmptyCommand(commands[i], i, commands)) {\n          i--;\n        }\n        i++;\n      }\n    }\n    i = 0;\n    while (i < commands.length) {\n      i = this.optimizeCommand(commands[i], i, commands);\n      i++;\n    }\n    return commands.optimized = true;\n  };\n\n  return DataOptimizer;\n\n})();\n\nwindow.DataOptimizer = new DataOptimizer();\n\ngs.DataOptimizer = DataOptimizer;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7Ozs7O0VBV2EsdUJBQUE7SUFDVCxJQUFDLENBQUEsTUFBRCxHQUFVO0lBQ1YsSUFBQyxDQUFBLFVBQUQsR0FBYztFQUZMOzs7QUFJYjs7Ozs7Ozs7OzBCQVFBLGtCQUFBLEdBQW9CLFNBQUMsS0FBRDtBQUNoQixRQUFBO0lBQUEsTUFBQSxHQUFTO0lBQ1QsTUFBQSxHQUFTLEtBQUssQ0FBQyxNQUFOLElBQWdCLE1BQU0sQ0FBQyxJQUFQLENBQVksS0FBWixDQUFrQixDQUFDO0lBQzVDLElBQUcsYUFBSDtNQUNJLElBQUcsMEJBQUg7UUFDSSxNQUFBLEdBQWEsSUFBQSxXQUFBLENBQVksTUFBQSxHQUFTLENBQXJCO1FBQ2IsTUFBQSxHQUFhLElBQUEsVUFBQSxDQUFXLE1BQVgsRUFGakI7T0FBQSxNQUFBO1FBSUksTUFBQSxHQUFhLElBQUEsS0FBQSxDQUFNLE1BQU4sRUFKakI7O0FBT0EsV0FBUywrRUFBVDtRQUNJLE1BQU8sQ0FBQSxDQUFBLENBQVAsR0FBWSxLQUFNLENBQUEsQ0FBQTtBQUR0QixPQVJKOztBQVdBLFdBQU87RUFkUzs7O0FBZ0JwQjs7Ozs7Ozs7OzBCQVFBLGFBQUEsR0FBZSxTQUFDLElBQUQ7QUFHWCxRQUFBO0lBQUEsTUFBQSxHQUFhLElBQUEsS0FBQSxDQUFNLElBQU47QUFDYixXQUFPO0VBSkk7OztBQU1mOzs7Ozs7Ozs7MEJBUUEsWUFBQSxHQUFjLFNBQUMsSUFBRDtBQUNWLFFBQUE7SUFBQSxNQUFBLEdBQWEsSUFBQSxLQUFBLENBQU0sSUFBTjtBQUNiLFdBQU87RUFGRzs7O0FBS2Q7Ozs7Ozs7Ozs7MEJBU0Esa0JBQUEsR0FBb0IsU0FBQyxPQUFELEVBQVUsS0FBVixFQUFpQixRQUFqQjtBQUNoQixRQUFBO0lBQUEsSUFBYSxXQUFXLENBQUMsYUFBekI7QUFBQSxhQUFPLE1BQVA7O0lB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WyIjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiNcbiMgICBTY3JpcHQ6IERhdGFPcHRpbWl6ZXJcbiNcbiMgICAkJENPUFlSSUdIVCQkXG4jXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmNsYXNzIERhdGFPcHRpbWl6ZXJcbiAgICAjIyMqXG4gICAgKiBUaGUgZGF0YSBvcHRpbWl6ZXIgaXMgdG8gb3B0aW1pemUgZGF0YSBzdHJ1Y3R1cmVzIGNvbWluZyBmcm9tIGRhdGEgZmlsZXMgdG9cbiAgICAqIG1ha2UgcHJvY2Vzc2luZyBmYXN0ZXIuIE9uZSB3YXkgb2Ygb3B0aW1pemF0aW9uIGZvciBleGFtcGxlIGlzIHRvIGNvbnZlcnRcbiAgICAqIHJlZ3VsYXIgYXJyYXkgdG8gdHlwZWQgYXJyYXlzLlxuICAgICpcbiAgICAqIEBtb2R1bGUgZ3NcbiAgICAqIEBjbGFzcyBEYXRhT3B0aW1pemVyXG4gICAgKiBAbWVtYmVyb2YgZ3NcbiAgICAqIEBzdGF0aWNcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICMjI1xuICAgIGNvbnN0cnVjdG9yOiAtPlxuICAgICAgICBAbGFiZWxzID0ge31cbiAgICAgICAgQGxhYmVsSnVtcHMgPSB7fVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIG51bWJlci1hcnJheSB0byBhIHR5cGVkIEludDE2IGFycmF5LlxuICAgICpcbiAgICAqIEBtZXRob2QgYXJyYXlUb05hdGl2ZUFycmF5XG4gICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSAtIFRoZSBhcnJheSB0byBjb252ZXJ0LlxuICAgICogQHJldHVybiB7SW50MTZBcnJheX0gVGhlIHR5cGVkIGFycmF5LlxuICAgICogQHN0YXRpY1xuICAgICMjIyBcbiAgICBhcnJheVRvTmF0aXZlQXJyYXk6IChhcnJheSkgLT5cbiAgICAgICAgcmVzdWx0ID0gbnVsbFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGggfHwgT2JqZWN0LmtleXMoYXJyYXkpLmxlbmd0aFxuICAgICAgICBpZiBhcnJheT9cbiAgICAgICAgICAgIGlmIHdpbmRvdy5BcnJheUJ1ZmZlcj9cbiAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgQXJyYXlCdWZmZXIobGVuZ3RoICogMilcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgSW50MTZBcnJheShyZXN1bHQpXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEFycmF5KGxlbmd0aClcbiAgICAgICAgICAgXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvciBpIGluIFswLi4ubGVuZ3RoXVxuICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IGFycmF5W2ldXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgdHlwZWQgSW50MTYgYXJyYXkgaWYgc3VwcG9ydGVkLiBPdGhlcndpc2UgYSByZWd1bGFyIGFycmF5IGlzIGNyZWF0ZWQuXG4gICAgKlxuICAgICogQG1ldGhvZCBuYXRpdmVBcnJheTE2XG4gICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSAtIFRoZSBzaXplIG9mIHRoZSBhcnJheSBpbiBlbGVtZW50cy4oTm90IGluIGJ5dGVzKS5cbiAgICAqIEByZXR1cm4ge0ludDE2QXJyYXl9IFRoZSBJbnQxNiBhcnJheS5cbiAgICAqIEBzdGF0aWNcbiAgICAjIyMgXG4gICAgbmF0aXZlQXJyYXkxNjogKHNpemUpIC0+XG4gICAgICAgICNyZXN1bHQgPSBuZXcgQXJyYXlCdWZmZXIoc2l6ZSAqIDIpXG4gICAgICAgICNyZXN1bHQgPSBuZXcgSW50MTZBcnJheShyZXN1bHQpXG4gICAgICAgIHJlc3VsdCA9IG5ldyBBcnJheShzaXplKVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIHR5cGVkIEludDggYXJyYXkgaWYgc3VwcG9ydGVkLiBPdGhlcndpc2UgYSByZWd1bGFyIGFycmF5IGlzIGNyZWF0ZWQuXG4gICAgKlxuICAgICogQG1ldGhvZCBuYXRpdmVBcnJheTE2XG4gICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSAtIFRoZSBzaXplIG9mIHRoZSBhcnJheSBpbiBlbGVtZW50cy4oTm90IGluIGJ5dGVzKS5cbiAgICAqIEByZXR1cm4ge0ludDhBcnJheX0gVGhlIEludDggYXJyYXkuXG4gICAgKiBAc3RhdGljXG4gICAgIyMjICAgICBcbiAgICBuYXRpdmVBcnJheTg6IChzaXplKSAtPlxuICAgICAgICByZXN1bHQgPSBuZXcgQXJyYXkoc2l6ZSlcbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICBcbiAgICAgXG4gICAgIyMjKlxuICAgICogUmVtb3ZlcyBhIHNpbmdsZSBlbXB0eSBjb21tYW5kIGxpa2UgYSBjb21tZW50LlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVtb3ZlRW1wdHlDb21tYW5kXG4gICAgKiBAcHJpdmF0ZVxuICAgICogQHBhcmFtIHtPYmplY3RbXX0gY29tbWFuZHMgLSBBIGxpc3Qgb2YgY29tbWFuZHMuXG4gICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCAtIFRoZSBjb21tYW5kIHRvIG9wdGltaXplLlxuICAgICogQHN0YXRpY1xuICAgICMjIyBcbiAgICByZW1vdmVFbXB0eUNvbW1hbmQ6IChjb21tYW5kLCBpbmRleCwgY29tbWFuZHMpIC0+XG4gICAgICAgIHJldHVybiBubyBpZiBHYW1lTWFuYWdlci5pbkxpdmVQcmV2aWV3XG4gICAgICAgIFxuICAgICAgICByZXN1bHQgPSBub1xuICAgICAgICBzd2l0Y2ggY29tbWFuZHNbaW5kZXhdLmlkXG4gICAgICAgICAgICB3aGVuIFwiZ3MuQ29tbWVudFwiXG4gICAgICAgICAgICAgICAgY29tbWFuZHMuc3BsaWNlKGluZGV4LCAxKVxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHllc1xuICAgICAgICAgICAgd2hlbiBcImdzLkVtcHR5Q29tbWFuZFwiXG4gICAgICAgICAgICAgICAgY29tbWFuZHMuc3BsaWNlKGluZGV4LCAxKVxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHllc1xuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgIFxuICAgICMjIypcbiAgICAqIENoZWNrcyBpZiBhIGNvbW1vbiBldmVudCBjYWxsIGNhbiBiZSBvcHRpbWl6ZWQgYnkgaW5saW5lIGl0LiBJbiBzcGVjaWFsIGNhc2VzLFxuICAgICogc3VjaCBhcyByZWN1cnNpb24gb3IgcGFyYW1ldGVycywgYW4gb3B0aW1pemF0aW9uIGlzIG5vIHBvc3NpYmxlLlxuICAgICpcbiAgICAqIEBtZXRob2Qgb3B0aW1pemVDb21tb25FdmVudENhbGxcbiAgICAqIEBwcml2YXRlXG4gICAgKiBAcGFyYW0ge09iamVjdFtdfSBjb21tYW5kcyAtIEEgbGlzdCBvZiBjb21tYW5kcy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIEluZGV4IG9mIHRoZSBjb21tYW5kIGluIGNvbW1hbmQtbGlzdC5cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIC0gVGhlIGNvbW1hbmQgdG8gb3B0aW1pemUuXG4gICAgKiBAcmV0dXJuIElmIDxiPnRydWU8L2I+IHRoZSBjYWxsIGNhbiBiZSBzYWZseSBpbmxpbmUuIE90aGVyd2lzZSA8Yj5mYWxzZTwvYj5cbiAgICAqIEBzdGF0aWNcbiAgICAjIyMgICAgXG4gICAgY2FuSW5saW5lQ29tbW9uRXZlbnRDYWxsOiAoY29tbWFuZCwgaW5kZXgsIGNvbW1hbmRzLCBjYWxsU3RhY2spIC0+XG4gICAgICAgIHJlc3VsdCA9ICEoY29tbWFuZC5wYXJhbXMuY29tbW9uRXZlbnRJZC5pbmRleD8pXG4gICAgICAgIGNvbW1vbkV2ZW50ID0gUmVjb3JkTWFuYWdlci5jb21tb25FdmVudHNbY29tbWFuZC5wYXJhbXMuY29tbW9uRXZlbnRJZF1cbiAgICAgICAgaWYgY29tbW9uRXZlbnQ/LmlubGluZVxuICAgICAgICAgICAgaWYgY2FsbFN0YWNrLmluZGV4T2YoY29tbW9uRXZlbnQpICE9IC0xXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gbm9cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjYWxsU3RhY2sucHVzaChjb21tb25FdmVudClcbiAgICAgICAgICAgICAgICBmb3IgYywgaSBpbiBjb21tb25FdmVudC5jb21tYW5kc1xuICAgICAgICAgICAgICAgICAgICBpZiBjLmlkID09IFwiZ3MuQ2FsbENvbW1vbkV2ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IEBjYW5JbmxpbmVDb21tb25FdmVudENhbGwoYywgaSwgY29tbW9uRXZlbnQuY29tbWFuZHMsIGNhbGxTdGFjaylcbiAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgICAgIFxuICAgICMjIypcbiAgICAqIE9wdGltaXplcyBhIGNvbW1vbiBldmVudCBjYWxsLlxuICAgICpcbiAgICAqIEBtZXRob2Qgb3B0aW1pemVDb21tb25FdmVudENhbGxcbiAgICAqIEBwcml2YXRlXG4gICAgKiBAcGFyYW0ge09iamVjdFtdfSBjb21tYW5kcyAtIEEgbGlzdCBvZiBjb21tYW5kcy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIEluZGV4IG9mIHRoZSBjb21tYW5kIGluIGNvbW1hbmQtbGlzdC5cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIC0gVGhlIGNvbW1hbmQgdG8gb3B0aW1pemUuXG4gICAgKiBAc3RhdGljXG4gICAgIyMjIFxuICAgIG9wdGltaXplQ29tbW9uRXZlbnRDYWxsOiAoY29tbWFuZCwgaW5kZXgsIGNvbW1hbmRzKSAtPlxuICAgICAgICBjb21tb25FdmVudCA9IFJlY29yZE1hbmFnZXIuY29tbW9uRXZlbnRzW2NvbW1hbmQucGFyYW1zLmNvbW1vbkV2ZW50SWRdXG4gICAgICAgIGlmIGNvbW1vbkV2ZW50Py5pbmxpbmVcbiAgICAgICAgICAgIGlmIEBjYW5JbmxpbmVDb21tb25FdmVudENhbGwoY29tbWFuZCwgaW5kZXgsIGNvbW1hbmRzLCBbXSlcbiAgICAgICAgICAgICAgICBjb21tYW5kcy5zcGxpY2UoaW5kZXgsIDEpXG4gICAgICAgICAgICAgICAgY29tbWFuZHMuc3BsaWNlLmFwcGx5KGNvbW1hbmRzLCBbaW5kZXgsIDBdLmNvbmNhdChPYmplY3QuY29weShjb21tb25FdmVudC5jb21tYW5kcykpKVxuICAgIFxuICAgICMjIypcbiAgICAqIE9wdGltaXplcyB0aGUgdmFyaWFibGUtYWNjZXNzIGJ5IHJlcGxhY2luZyB0aGUgZG9tYWluLXN0cmluZyB3aXRoIHRoZSBkb21haW4taW5kZXhcbiAgICAqIHZhbHVlIGF0IHJ1bnRpbWUgdG8gYWxsb3cgZmFzdGVyIGRvbWFpbiBhY2Nlc3MgdXNpbmcgaW50ZWdlciBudW1iZXJzIGluc3RlYWQgb2Ygc3RyaW5ncy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIG9wdGltaXplVmFyaWFibGVBY2Nlc3NcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIC0gVGhlIGRhdGEgdG8gb3BpbWl6ZSwgZS5nLiB0aGUgcGFyYW1zLW9iamVjdCBvZiBhIGNvbW1hbmQuXG4gICAgKiBAc3RhdGljXG4gICAgIyMjICAgICAgICAgICAgIFxuICAgIG9wdGltaXplVmFyaWFibGVBY2Nlc3M6IChkYXRhKSAtPlxuICAgICAgICByZXR1cm4gaWYgZGF0YT8uX19vcHRpbWl6ZWRcbiAgICAgICAgZGF0YT8uX19vcHRpbWl6ZWQgPSB5ZXMgXG4gICAgICAgIGZvciBwIG9mIGRhdGFcbiAgICAgICAgICAgIGlmIGRhdGFbcF0gaW5zdGFuY2VvZiBBcnJheSBhbmQgIWRhdGFbcF0uX19vcHRpbWl6ZWRcbiAgICAgICAgICAgICAgICBkYXRhW3BdLl9fb3B0aW1pemVkID0geWVzXG4gICAgICAgICAgICAgICAgZm9yIGUgaW4gZGF0YVtwXVxuICAgICAgICAgICAgICAgICAgICBAb3B0aW1pemVWYXJpYWJsZUFjY2VzcyhlKVxuICAgICAgICAgICAgZWxzZSBpZiBwID09IFwiZG9tYWluXCIgYW5kIGRhdGEuc2NvcGUgPiAwIGFuZCBkYXRhLmluZGV4P1xuICAgICAgICAgICAgICAgIGRvbWFpbkluZGV4ID0gR2FtZU1hbmFnZXIudmFyaWFibGVTdG9yZS5kb21haW5zLmluZGV4T2YoZGF0YVtwXSlcbiAgICAgICAgICAgICAgICBkYXRhW3BdID0gaWYgZG9tYWluSW5kZXggPT0gLTEgdGhlbiBkYXRhW3BdIGVsc2UgZG9tYWluSW5kZXhcbiAgICAgICAgICAgIGVsc2UgaWYgdHlwZW9mIGRhdGFbcF0gPT0gXCJvYmplY3RcIiBhbmQgIShkYXRhW3BdIGluc3RhbmNlb2YgU3RyaW5nIHx8IGRhdGFbcF0gaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgICAgICAgICAgICBAb3B0aW1pemVWYXJpYWJsZUFjY2VzcyhkYXRhW3BdKSBpZiBub3QgZGF0YVtwXT8uX19vcHRpbWl6ZWRcbiAgICAgICAgICAgICAgICBkYXRhW3BdPy5fX29wdGltaXplZCA9IHllc1xuICAgICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIE9wdGltaXplcyBhIHNpbmdsZSBzdWItbWVzc2FnZSBjcmVhdGVkIGJ5IHtDUH0gdGV4dCBjb2RlLiBJdCB3aWxsIHNwbGl0IHRoZSBzdWItbWVzc2FnZSBpbnRvIG11bHRpcGxlXG4gICAgKiBpbmRlcGVuZGVudCBTaG93TWVzc2FnZSBjb21tYW5kcyBhdCB7UH0gdGV4dCBjb2RlLlxuICAgICpcbiAgICAqIEBtZXRob2Qgb3B0aW1pemVTdWJNZXNzYWdlXG4gICAgKiBAcHJpdmF0ZVxuICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBUaGUgc3ViIG1lc3NhZ2UuXG4gICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCAtIFRoZSBjb21tYW5kIHRvIG9wdGltaXplLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gSW5kZXggb2YgdGhlIGNvbW1hbmQgaW4gY29tbWFuZC1saXN0LlxuICAgICogQHBhcmFtIHtPYmplY3RbXX0gY29tbWFuZHMgLSBBIGxpc3Qgb2YgY29tbWFuZHMuXG4gICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBjdXJyZW50IGNvbW1hbmQtcG9pbnRlciB3aGVyZSBhZGQvaW5zZXJ0IHRoZSBuZXh0IGNvbW1hbmQgKElmIG5lY2Vzc2FyeSkuXG4gICAgKiBAc3RhdGljXG4gICAgIyMjICBcbiAgICBvcHRpbWl6ZVN1Yk1lc3NhZ2U6IChtZXNzYWdlLCBjb21tYW5kLCBpbmRleCwgY29tbWFuZHMpIC0+XG4gICAgICAgIHN1Yk1lc3NhZ2VzID0gbWVzc2FnZS5zcGxpdChcIntQfVwiKVxuICAgICAgICBmb3Igc3ViTWVzc2FnZSBpbiBzdWJNZXNzYWdlc1xuICAgICAgICAgICAgbWVzc2FnZUNvbW1hbmQgPSBPYmplY3QuZmxhdENvcHkoY29tbWFuZClcbiAgICAgICAgICAgIG1lc3NhZ2VDb21tYW5kLnBhcmFtcyA9IE9iamVjdC5mbGF0Q29weShtZXNzYWdlQ29tbWFuZC5wYXJhbXMpXG4gICAgICAgICAgICBtZXNzYWdlQ29tbWFuZC5wYXJhbXMubWVzc2FnZSA9IHN1Yk1lc3NhZ2UubHRyaW0oKVxuICAgICAgICAgICAgY29tbWFuZHMuc3BsaWNlKGluZGV4LCAwLCBtZXNzYWdlQ29tbWFuZClcbiAgICAgICAgICAgIGluZGV4KytcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIGluZGV4XG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIE9wdGltaXplcyBhIHNpbmdsZSBTaG93TWVzc2FnZSBjb21tYW5kLiBJdCB3aWxsIHNwbGl0IHRoZSBjb21tYW5kIGludG8gbXVsdGlwbGVcbiAgICAqIGluZGVwZW5kZW50IFNob3dNZXNzYWdlIGNvbW1hbmRzIGF0IHtQfSB0ZXh0IGNvZGUgZm9yIGV4YW1wbGUuXG4gICAgKlxuICAgICogQG1ldGhvZCBvcHRpbWl6ZVNob3dNZXNzYWdlXG4gICAgKiBAcHJpdmF0ZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgLSBUaGUgY29tbWFuZCB0byBvcHRpbWl6ZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIEluZGV4IG9mIHRoZSBjb21tYW5kIGluIGNvbW1hbmQtbGlzdC5cbiAgICAqIEBwYXJhbSB7T2JqZWN0W119IGNvbW1hbmRzIC0gQSBsaXN0IG9mIGNvbW1hbmRzLlxuICAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgY3VycmVudCBjb21tYW5kLXBvaW50ZXIgd2hlcmUgYWRkL2luc2VydCB0aGUgbmV4dCBjb21tYW5kIChJZiBuZWNlc3NhcnkpLlxuICAgICogQHN0YXRpY1xuICAgICMjIyAgICAgXG4gICAgb3B0aW1pemVTaG93TWVzc2FnZTogKGNvbW1hbmQsIGluZGV4LCBjb21tYW5kcykgLT4gXG4gICAgICAgIG1zZyA9IGxjcyhjb21tYW5kLnBhcmFtcy5tZXNzYWdlKVxuICAgICAgICBcbiAgICAgICAgaWYgbXNnLmNvbnRhaW5zKFwie0NQfVwiKSBvciBtc2cuY29udGFpbnMoXCJ7UH1cIilcbiAgICAgICAgICAgIGNvbW1hbmRzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgICAgIHN1Yk1lc3NhZ2VzID0gbXNnLnNwbGl0KFwie0NQfVwiKVxuICAgICAgICAgICAgZm9yIHN1Yk1lc3NhZ2UsIGkgaW4gc3ViTWVzc2FnZXNcbiAgICAgICAgICAgICAgICBpbmRleCA9IEBvcHRpbWl6ZVN1Yk1lc3NhZ2Uoc3ViTWVzc2FnZSwgY29tbWFuZCwgaW5kZXgsIGNvbW1hbmRzKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIGkgPCBzdWJNZXNzYWdlcy5sZW5ndGgtMVxuICAgICAgICAgICAgICAgICAgICBjbGVhckNvbW1hbmQgPSB7IGlkOiBcImdzLkNsZWFyTWVzc2FnZVwiLCBpbmRlbnQ6IGNvbW1hbmQuaW5kZW50LCBwYXJhbXM6IHsgZmllbGRGbGFnczogeyBkdXJhdGlvbjogMSB9LCBkdXJhdGlvbjogMzAsIHdhaXRGb3JDb21wbGV0aW9uOiB5ZXMgfSB9XG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRzLnNwbGljZShpbmRleCwgMCwgY2xlYXJDb21tYW5kKVxuICAgICAgICAgICAgICAgICAgICBpbmRleCsrXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBpbmRleFxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBPcHRpbWl6ZXMgYSBzaW5nbGUgY29tbWFuZC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIG9wdGltaXplQ29tbWFuZFxuICAgICogQHByaXZhdGVcbiAgICAqIEBwYXJhbSB7T2JqZWN0W119IGNvbW1hbmRzIC0gQSBsaXN0IG9mIGNvbW1hbmRzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gSW5kZXggb2YgdGhlIGNvbW1hbmQgaW4gY29tbWFuZC1saXN0LlxuICAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgLSBUaGUgY29tbWFuZCB0byBvcHRpbWl6ZS5cbiAgICAqIEBzdGF0aWNcbiAgICAjIyMgICAgIFxuICAgIG9wdGltaXplQ29tbWFuZDogKGNvbW1hbmQsIGluZGV4LCBjb21tYW5kcykgLT5cbiAgICAgICAgQG9wdGltaXplVmFyaWFibGVBY2Nlc3MoY29tbWFuZC5wYXJhbXMpXG4gICAgICAgIFxuICAgICAgICBzd2l0Y2ggY29tbWFuZC5pZFxuICAgICAgICAgICAgd2hlbiBcImdzLlNob3dNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICBpbmRleCA9IEBvcHRpbWl6ZVNob3dNZXNzYWdlKGNvbW1hbmQsIGluZGV4LCBjb21tYW5kcylcbiAgICAgICAgICAgIHdoZW4gXCJncy5DYWxsQ29tbW9uRXZlbnRcIlxuICAgICAgICAgICAgICAgIEBvcHRpbWl6ZUNvbW1vbkV2ZW50Q2FsbChjb21tYW5kLCBpbmRleCwgY29tbWFuZHMpXG4gICAgICAgICAgICB3aGVuIFwiZ3MuTGFiZWxcIlxuICAgICAgICAgICAgICAgIEBsYWJlbHNbY29tbWFuZC5wYXJhbXMubmFtZV0gPSBpbmRleFxuICAgICAgICAgICAgICAgIEBsYWJlbEp1bXBzW2NvbW1hbmQucGFyYW1zLm5hbWVdPy5mb3JFYWNoIChjKSAtPiBjLnBhcmFtcy5sYWJlbEluZGV4ID0gaW5kZXhcbiAgICAgICAgICAgIHdoZW4gXCJ2bi5DaG9pY2VcIlxuICAgICAgICAgICAgICAgIGNvbW1hbmQucGFyYW1zLmFjdGlvbi5sYWJlbEluZGV4ID0gQGxhYmVsc1tjb21tYW5kLnBhcmFtcy5hY3Rpb24ubGFiZWxdXG4gICAgICAgICAgICAgICAgaWYgIUBsYWJlbEp1bXBzW2NvbW1hbmQucGFyYW1zLmFjdGlvbi5sYWJlbF1cbiAgICAgICAgICAgICAgICAgICAgQGxhYmVsSnVtcHNbY29tbWFuZC5wYXJhbXMuYWN0aW9uLmxhYmVsXSA9IFtdXG4gICAgICAgICAgICAgICAgQGxhYmVsSnVtcHNbY29tbWFuZC5wYXJhbXMuYWN0aW9uLmxhYmVsXS5wdXNoKGNvbW1hbmQpXG4gICAgICAgICAgICB3aGVuIFwiZ3MuQ2hlY2tTd2l0Y2hcIiwgXCJncy5DaGVja051bWJlclZhcmlhYmxlXCIsIFwiZ3MuQ2hlY2tUZXh0VmFyaWFibGVcIlxuICAgICAgICAgICAgICAgIGNvbW1hbmQucGFyYW1zLmxhYmVsSW5kZXggPSBAbGFiZWxzW2NvbW1hbmQucGFyYW1zLmxhYmVsXVxuICAgICAgICAgICAgICAgIGlmICFAbGFiZWxKdW1wc1tjb21tYW5kLnBhcmFtcy5sYWJlbF1cbiAgICAgICAgICAgICAgICAgICAgQGxhYmVsSnVtcHNbY29tbWFuZC5wYXJhbXMubGFiZWxdID0gW11cbiAgICAgICAgICAgICAgICBAbGFiZWxKdW1wc1tjb21tYW5kLnBhcmFtcy5sYWJlbF0ucHVzaChjb21tYW5kKVxuICAgICAgICAgICAgI3doZW4gXCJncy5BZGRIb3RzcG90XCJcbiAgICAgICAgICAgICMgICAgY29tbWFuZC5wYXJhbXMuYWN0aW9ucy5vbkNsaWNrXG4gICAgICAgICAgICB3aGVuIFwiZ3MuSnVtcFRvTGFiZWxcIlxuICAgICAgICAgICAgICAgIGNvbW1hbmQucGFyYW1zLmxhYmVsSW5kZXggPSBAbGFiZWxzW2NvbW1hbmQucGFyYW1zLm5hbWVdXG4gICAgICAgICAgICAgICAgaWYgIUBsYWJlbEp1bXBzW2NvbW1hbmQucGFyYW1zLm5hbWVdXG4gICAgICAgICAgICAgICAgICAgIEBsYWJlbEp1bXBzW2NvbW1hbmQucGFyYW1zLm5hbWVdID0gW11cbiAgICAgICAgICAgICAgICBAbGFiZWxKdW1wc1tjb21tYW5kLnBhcmFtcy5uYW1lXS5wdXNoKGNvbW1hbmQpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gaW5kZXhcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogT3B0aW1pemVzIGEgbGlzdCBvZiBldmVudC9zY2VuZSBjb21tYW5kcyBieSByZW1vdmluZyB1bm5lY2Vzc2FyeSBjb21tYW5kcyBsaWtlXG4gICAgKiBjb21tZW50cyBvciBlbXB0eSBjb21tYW5kcy4gSXQgYWxzbyBvcHRpbWl6ZXMgbGFiZWwganVtcHMuIEFkZHMgYW4gPGI+b3B0aW1pemVkPC9iPiB0b1xuICAgICogdGhlIHNwZWNpZmllZCBjb21tYW5kLWxpc3QgdG8gaW5kaWNhdGUgdGhhdCB0aGUgbGlzdCB3YXMgYWxyZWFkeSBvcHRpbWl6ZWQuIElmIDxiPm9wdGltaXplZDwvYj5cbiAgICAqIHByb3BlcnR5IG9mIGNvbW1hbmQtbGlzdCBpcyBzZXQgdG8gPGI+dHJ1ZTwvYj4gdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gaW1tZWRpYXRlbHkuXG4gICAgKlxuICAgICogQG1ldGhvZCBvcHRpbWl6ZUV2ZW50Q29tbWFuZHNcbiAgICAqIEBwYXJhbSB7T2JqZWN0W119IGNvbW1hbmRzIC0gQSBsaXN0IG9mIGNvbW1hbmRzIHRvIG9wdGltaXplLlxuICAgICogQHN0YXRpY1xuICAgICMjIyAgICAgICBcbiAgICBvcHRpbWl6ZUV2ZW50Q29tbWFuZHM6IChjb21tYW5kcykgLT5cbiAgICAgICAgcmV0dXJuIGlmIGNvbW1hbmRzLm9wdGltaXplZFxuXG4gICAgICAgIGkgPSAwXG4gICAgICAgIEBsYWJlbHMgPSB7fVxuICAgICAgICBAbGFiZWxKdW1wcyA9IHt9XG4gICAgICAgIGlmICEkUEFSQU1TLnByZXZpZXdcbiAgICAgICAgICAgIHdoaWxlIGkgPCBjb21tYW5kcy5sZW5ndGhcbiAgICAgICAgICAgICAgICBjb21tYW5kc1tpXS5pbmRlbnQgPSBjb21tYW5kc1tpXS5pbmRlbnQgfHwgMFxuICAgICAgICAgICAgICAgIGlmIEByZW1vdmVFbXB0eUNvbW1hbmQoY29tbWFuZHNbaV0sIGksIGNvbW1hbmRzKVxuICAgICAgICAgICAgICAgICAgICBpLS1cbiAgICAgICAgICAgICAgICBpKytcbiAgICAgICAgaSA9IDBcbiAgICAgICAgd2hpbGUgaSA8IGNvbW1hbmRzLmxlbmd0aFxuICAgICAgICAgICAgaSA9IEBvcHRpbWl6ZUNvbW1hbmQoY29tbWFuZHNbaV0sIGksIGNvbW1hbmRzKVxuICAgICAgICAgICAgaSsrXG4gICAgICAgIGNvbW1hbmRzLm9wdGltaXplZCA9IHllc1xuICAgICAgICBcbiAgICAgICAgXG53aW5kb3cuRGF0YU9wdGltaXplciA9IG5ldyBEYXRhT3B0aW1pemVyKClcbmdzLkRhdGFPcHRpbWl6ZXIgPSBEYXRhT3B0aW1pemVyIl19\n//# sourceURL=DataOptimizer_1.js",
        "parentId": "2EC9F946K6417A4973S8308E368608E89B8B"
    },
    "summary": [
        "name",
        "type",
        "order"
    ]
}

Commits for Nextrek/s2s/data/3A731523KD345A49DAS903FE171A585AEB27.json

Diff revisions: vs.
Revision Author Commited Message
1084 MOliva picture MOliva Fri 11 May, 2018 12:41:55 +0000