Subversion Repository Public Repository

Nextrek

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
    "uid": "19D5B266K1082A4D01S85D0E17BE2BBA69F8",
    "isLoaded": true,
    "lastModificationTime": 0,
    "items": {
        "name": "Object_Base",
        "type": "game_script",
        "order": 0,
        "content": "# ===================================================================\n#\n#   Script: Object_Base\n#\n#   $$COPYRIGHT$$\n#\n# ===================================================================\nclass Object_Base\n    ###*\n    * Called if this object instance is restored from a data-bundle. It can be used\n    * re-assign event-handler, anonymous functions, etc.\n    * \n    * @method onDataBundleRestore.\n    * @param Object data - The data-bundle\n    * @param gs.ObjectCodecContext context - The codec-context.\n    ###\n    onDataBundleRestore: (data, context) ->\n        if @id\n            window[\"$\"+@id] = this\n            \n    \n    #\n    # Gets or sets the group the object belongs to.\n    #\n    # @property group\n    # @type string\n    #\n    @accessors \"group\", \n        set: (g) -> \n            @group_ = g\n            gs.ObjectManager.current?.addToGroup(this, g)\n            \n        get: -> @group_\n        \n    #\n    # Gets or sets the order-index of the object. The lower the index, the\n    # earlier the object will be updated in a list of sub-objects.\n    #\n    # @property order\n    # @type number\n    #\n    @accessors \"order\",\n        set: (o) ->\n            if o != @order_\n                @order_ = o\n                @parent?.needsSort = true\n        get: -> @order_\n        \n    #\n    # Gets or sets if an objects needs an update. If true, the parent will update\n    # the object in the next update and resets the needsUpdate property back\n    # to false.\n    #\n    # @property needsUpdate\n    # @type boolean\n    #\n    @accessors \"needsUpdate\", \n        set: (v) ->\n            @needsUpdate_ = v\n            \n            parent = @parent\n            while parent\n                parent.needsUpdate_ = yes\n                parent = parent.parent\n                \n            #if v\n            #    @parent?.needsUpdate = yes\n            #if v\n            #    for object in @subObjects\n            #        object.needsUpdate_ = v\n            if v\n                @requestSubUpdate()\n        get: -> return @needsUpdate_ || SceneManager.scene.preparing\n        \n    requestSubUpdate: ->\n        for object in @subObjects\n            if object\n                object.needsUpdate_ = yes\n                object.requestSubUpdate()\n                \n        return null\n    #\n    # Gets or sets if an object needs a full update. A full update triggers\n    # an update for all sub-objects recursively. \n    #\n    # @property needsFullUpdate\n    # @type boolean\n    #\n    @accessors \"needsFullUpdate\", \n        set: (v) ->\n            @needsUpdate = v\n            if v\n                for object in @subObjects\n                    object.needsFullUpdate = v\n        get: -> @needsUpdate_\n            \n    ###*\n    * The base class for all game objects. A game object itself doesn't implement\n    * any game logic but uses components and sub-objects for that.\n    *\n    * @module gs\n    * @class Object_Base\n    * @memberof gs\n    * @constructor\n    ###\n    constructor: () ->\n        ###*\n        * @property subObjects\n        * @type gs.Object_Base[]\n        * @default []\n        * A list of game-objects grouped under this game object.\n        ###\n        @subObjects = []\n        \n        ###*\n        * @property components\n        * @type gs.Component[]\n        * @default []\n        * A list of components defining the logic/behavior and appearance of the game object.\n        ###\n        @components = []\n        \n        ###*\n        * @property componentsById\n        * @type Object\n        * @default []\n        * All associated components by their ID.\n        ###\n        @componentsById = {}\n        \n        ###*\n        * @property disposed\n        * @type boolean\n        * @default false\n        * Indicates if the game object id disposed. A disposed game object cannot be used anymore.\n        ###\n        @disposed = no\n        \n        ###*\n        * @property active\n        * @default true\n        * Indicates if the game object is active. An inactive game object will not be updated.\n        ###\n        @active = yes\n        \n        @input = no\n        \n        ###*\n        * @property id\n        * @type string\n        * @default null\n        * The game object's UID (Unique ID)\n        ###\n        @id = null \n        \n        ###*\n        * @property group\n        * @default null\n        * @type string\n        * The game object's group. To get all object's of a specific group the gs.ObjectManager.objectsByGroup property can be used.\n        ###\n        @group = null \n        \n        ###*\n        * @property parent\n        * @type gs.Object_Base\n        * @default null\n        * The parent object if the game object is a sub-object of another game object.\n        ###\n        @parent = null\n        \n        ###*\n        * @property order\n        * @type number\n        * @default 0\n        * Controls the update-order. The smaller the value the earlier the game object is updated before other game objects are updated.\n        ###\n        @order = 0\n        \n        ###*\n        * @property rIndex\n        * @type number\n        * @default 0\n        * Holds the render-index if the game object has a graphical representation on screen. The render-index is the\n        * index of the game object's graphic-object(gs.GraphicObject) in the current list of graphic-objects. The render-index\n        * is read-only. Setting the render-index to a certain value has no effect.\n        ###\n        @rIndex = 0\n        \n        ###*\n        * @property needsSort\n        * @type boolean\n        * @default true\n        * Indicates if the list of sub-objects needs to be sorted by order because of a change.\n        ###\n        @needsSort = yes\n        \n        ###*\n        * @property needsSort\n        * @type boolean\n        * @default true\n        * Indicates if the UI object needs to be updated.\n        ###\n        @needsUpdate = yes\n        \n        ###*\n        * @property initialized\n        * @type boolean\n        * @default true\n        * Indicates if the game object and its components have been initialized.\n        ###\n        @initialized = no\n        \n        ###*\n        * @property customData\n        * @type Object\n        * @default {}\n        * A custom data object which can be used to add any custom data/fields to the game\n        * object. It is an empty object by default.\n        ###\n        @customData = {}\n        \n        \n        gs.ObjectManager.current?.registerObject(this)\n        \n    ###*\n    * Disposes the object with all its components and sub-objects. A disposed object will be\n    * removed from the parent automatically.\n    *\n    * @method dispose\n    ###\n    dispose: ->\n        if not @disposed\n            @disposed = yes\n            @disposeComponents()\n            @disposeObjects()\n                \n            gs.ObjectManager.current?.unregisterObject(this)\n        \n        return null\n        \n    ###*\n    * Disposes all sub-objects.\n    *\n    * @method disposeObjects\n    * @protected\n    ###\n    disposeObjects: ->\n        for subObject in @subObjects\n            subObject?.dispose?()\n            \n    ###*\n    * Disposes all components\n    *\n    * @method disposeComponents\n    * @protected\n    ###\n    disposeComponents: ->\n        for component in @components\n            component?.dispose?()\n       \n    ###*\n    * Calls setup-routine on all components.\n    *\n    * @method setup\n    ###\n    setup: ->\n        for component in @components\n            component.setup() if not component?.isSetup\n            \n        @initialized = yes\n        return null\n        \n    ###*\n    * Deserializes components from a data-bundle object.\n    * \n    * @method componentsFromDataBundle\n    * @param {Object} data The data-bundle object.\n    ###\n    componentsFromDataBundle: (data) ->\n        if data?.components\n            for component in data.components\n                componentObject = new gs[component.className](component)\n                @addComponent(componentObject)\n            delete data.components\n                \n        return null\n           \n    ###*\n    * Serializes components of a specified type to a data-bundle. A component\n    * needs to implement the toDataBundle method for correct serialization.\n    *\n    * @method componentsToDataBundle\n    * @param {String} type - A component class name.\n    * @return A data bundle.\n    ###\n    componentsToDataBundle: (type) ->\n        components = []\n        for component in @components\n            if component instanceof type\n                continue unless component.toDataBundle?\n                bundle = component.toDataBundle()\n                bundle.className = component.constructor.name\n                components.push(bundle)\n        return components\n        \n    ###*\n    * Starts a full-refresh on all sub-objects\n    *\n    * @method fullRefresh\n    ###\n    fullRefresh: ->\n        for object in @subObjects\n            if object\n                object.needsUpdate = yes\n                object.fullRefresh()\n            \n        return null\n    \n    ###*\n    * Updates the object with all parent- and sub-objects. \n    *\n    * @method fullUpdate\n    ###\n    fullUpdate: ->\n        parent = this\n        while parent != null\n            parent.update()\n            parent = parent.parent\n            \n        for object in @subObjects\n            object?.update()\n        \n    ###*\n    * Updates the object and all its components. This method is\n    * called automatically by the parent or ObjectManager so in regular it is \n    * not necessary to call it manually.\n    *\n    * @method update\n    ###\n    update: ->\n        return if !@active\n        i = 0\n        while i < @components.length\n            component = @components[i]\n            if not component.disposed\n                component.update()\n                i++\n            else\n                @components.splice(i, 1)\n\n\n        if @input then Input.clear()\n        @input = no\n        \n        return null\n            \n    ###*\n    * Searches for the first component with the specified class name.\n    *\n    * @method findComponent\n    * @param {String} name The class name of the component.\n    * @return {Component} The component or null if a component with the specified class name cannot be found.\n    ###\n    findComponent: (name) -> @components.first (v) -> v.constructor.name == name\n    \n    ###*\n    * Searches for all components with the specified class name.\n    *\n    * @method findComponents\n    * @param {String} name The class name of the components.\n    * @return {Array} The components or null if no component with the specified class name has been found.\n    ###\n    findComponents: (name) -> @components.where (v) -> v.constructor.name == name\n    \n    ###*\n    * Searches for the component with the specified ID.\n    *\n    * @method findComponentById\n    * @param {String} id The unique identifier of the component.\n    * @return {Component} The component or null if a component with the specified ID cannot be found.\n    ###\n    findComponentById: (id) -> @componentsById[id]\n    \n    ###*\n    * Searches for the component with the specified name. If multiple components have the\n    * same name, it will return the first match.\n    *\n    * @method findComponentByName\n    * @param {String} name The name of the component to find.\n    * @return {Component} The component or null if a component with the specified name cannot be found.\n    ###\n    findComponentByName: (name) -> @components.first (v) -> v.name == name\n    \n    ###*\n    * Searches for components with the specified name.\n    *\n    * @method findComponentsByName\n    * @param {String} name The name of the components to find.\n    * @return {Component[]} An array of components matching the specified name or null if no components with the specified name exist.\n    ###\n    findComponentsByName: (name) -> @components.where (v) -> v.name == name\n    \n    ###*\n    * Adds an object to the list of sub-objects.\n    *\n    * @method addObject\n    * @param {Object_Base} object The object which should be added.\n    ###\n    addObject: (object) ->\n        gs.ObjectManager.current?.remove(object)\n        object.parent?.removeObject(object)\n        object.parent = this\n        @subObjects.push(object)\n        @needsSort = yes\n        @needsUpdate = yes\n    \n        if object.id?\n            gs.ObjectManager.current.setObjectById(object, object.id)\n        \n    ###*\n    * Inserts an object into the list of sub-objects at the specified index.\n    *\n    * @method insertObject\n    * @param {Object_Base} object The object which should be inserted.\n    * @param {Number} index The index.\n    ###\n    insertObject:(object, index) ->\n        gs.ObjectManager.current.remove(object)\n        object.parent?.removeObject(object)\n        object.parent = this\n        @subObjects.splice(index, 0, object)\n      \n        if object.id?\n            gs.ObjectManager.current.setObjectById(object, object.id)\n            \n    ###*\n    * Sets sub-object at the specified index.\n    *\n    * @method setObject\n    * @param {Object_Base} object The object.\n    * @param {Number} index The index.\n    ###\n    setObject: (object, index) ->\n        if object\n            gs.ObjectManager.current.remove(object)\n            object.parent?.removeObject(object)\n            object.parent = this\n            \n        @subObjects[index] = object\n      \n        if object?.id?\n            gs.ObjectManager.current.setObjectById(object, object.id)\n    \n    ###*\n    * Removes the specified object from the list of sub-objects.\n    *\n    * @method removeObject\n    * @param {Object_Base} object The object which should be removed.\n    ###\n    removeObject: (object) ->\n        @subObjects.remove(object)\n        object.parent = null\n        @needsUpdate = yes\n     \n    ###*\n    * Removes the object at the specified index from the list of sub-objects.\n    *\n    * @method removeObjectAt\n    * @param {number} index The index of the objec to remove.\n    ###   \n    removeObjectAt: (index) ->\n        object = @subObjects[index]\n        @subObjects.splice(index, 1)\n        object.parent = null\n        @needsUpdate = yes\n    \n    ###*\n    * Removes all sub-objects.\n    *\n    * @method removeAllObjects\n    ###     \n    removeAllObjects: ->\n        while @subObjects.length > 0\n            @removeObjectAt(0)\n    \n    ###*\n    * Erases the object at the specified index. The list size\n    * will not be changed but the the value at the index will be set to null.\n    *\n    * @method eraseObject\n    * @param {Number} object The object which should be erased.\n    ###\n    eraseObject: (index) ->\n        object = @subObjects[index]\n        object?.parent = null\n        @subObjects[index] = null\n    \n    ###*\n    * Adds the specified component to the object.\n    *\n    * @method addComponent\n    * @param {Component} component The component\n    * @param {String} id An optional unique identifier for the component.\n    ###\n    addComponent: (component, id) ->\n        if not @components.contains(component)\n            component.object = this\n            @components.push(component)\n            if id?\n                @componentsById[id] = component\n    ###*\n    * Inserts a component at the specified index.\n    *\n    * @method insertComponent\n    * @param {Component} component The component.\n    * @param {Number} index The index.\n    * @param {String} id An optional unique identifier for the component.\n    ###    \n    insertComponent: (component, index, id) ->\n        @components.remove(component)\n        component.object = this\n        @components.splice(index, 0, component)\n        if id?\n            @componentsById[id] = component\n    \n    ###*\n    * Removes a component from the object.\n    *\n    * @method removeComponent\n    * @param {Component} component The component to remove.\n    ###  \n    removeComponent: (component) -> \n        @components.remove(component)\n        if id?\n            delete @componentsById[id]\n\ngs.Object_Base = Object_Base",
        "parentId": "A05E7029K45DBA459BSADF4EEC07A526241A",
        "folder": false,
        "compiledContent": "var Object_Base;\n\nObject_Base = (function() {\n\n  /**\n  * Called if this object instance is restored from a data-bundle. It can be used\n  * re-assign event-handler, anonymous functions, etc.\n  * \n  * @method onDataBundleRestore.\n  * @param Object data - The data-bundle\n  * @param gs.ObjectCodecContext context - The codec-context.\n   */\n  Object_Base.prototype.onDataBundleRestore = function(data, context) {\n    if (this.id) {\n      return window[\"$\" + this.id] = this;\n    }\n  };\n\n  Object_Base.accessors(\"group\", {\n    set: function(g) {\n      var ref;\n      this.group_ = g;\n      return (ref = gs.ObjectManager.current) != null ? ref.addToGroup(this, g) : void 0;\n    },\n    get: function() {\n      return this.group_;\n    }\n  });\n\n  Object_Base.accessors(\"order\", {\n    set: function(o) {\n      var ref;\n      if (o !== this.order_) {\n        this.order_ = o;\n        return (ref = this.parent) != null ? ref.needsSort = true : void 0;\n      }\n    },\n    get: function() {\n      return this.order_;\n    }\n  });\n\n  Object_Base.accessors(\"needsUpdate\", {\n    set: function(v) {\n      var parent;\n      this.needsUpdate_ = v;\n      parent = this.parent;\n      while (parent) {\n        parent.needsUpdate_ = true;\n        parent = parent.parent;\n      }\n      if (v) {\n        return this.requestSubUpdate();\n      }\n    },\n    get: function() {\n      return this.needsUpdate_ || SceneManager.scene.preparing;\n    }\n  });\n\n  Object_Base.prototype.requestSubUpdate = function() {\n    var j, len, object, ref;\n    ref = this.subObjects;\n    for (j = 0, len = ref.length; j < len; j++) {\n      object = ref[j];\n      if (object) {\n        object.needsUpdate_ = true;\n        object.requestSubUpdate();\n      }\n    }\n    return null;\n  };\n\n  Object_Base.accessors(\"needsFullUpdate\", {\n    set: function(v) {\n      var j, len, object, ref, results;\n      this.needsUpdate = v;\n      if (v) {\n        ref = this.subObjects;\n        results = [];\n        for (j = 0, len = ref.length; j < len; j++) {\n          object = ref[j];\n          results.push(object.needsFullUpdate = v);\n        }\n        return results;\n      }\n    },\n    get: function() {\n      return this.needsUpdate_;\n    }\n  });\n\n\n  /**\n  * The base class for all game objects. A game object itself doesn't implement\n  * any game logic but uses components and sub-objects for that.\n  *\n  * @module gs\n  * @class Object_Base\n  * @memberof gs\n  * @constructor\n   */\n\n  function Object_Base() {\n\n    /**\n    * @property subObjects\n    * @type gs.Object_Base[]\n    * @default []\n    * A list of game-objects grouped under this game object.\n     */\n    var ref;\n    this.subObjects = [];\n\n    /**\n    * @property components\n    * @type gs.Component[]\n    * @default []\n    * A list of components defining the logic/behavior and appearance of the game object.\n     */\n    this.components = [];\n\n    /**\n    * @property componentsById\n    * @type Object\n    * @default []\n    * All associated components by their ID.\n     */\n    this.componentsById = {};\n\n    /**\n    * @property disposed\n    * @type boolean\n    * @default false\n    * Indicates if the game object id disposed. A disposed game object cannot be used anymore.\n     */\n    this.disposed = false;\n\n    /**\n    * @property active\n    * @default true\n    * Indicates if the game object is active. An inactive game object will not be updated.\n     */\n    this.active = true;\n    this.input = false;\n\n    /**\n    * @property id\n    * @type string\n    * @default null\n    * The game object's UID (Unique ID)\n     */\n    this.id = null;\n\n    /**\n    * @property group\n    * @default null\n    * @type string\n    * The game object's group. To get all object's of a specific group the gs.ObjectManager.objectsByGroup property can be used.\n     */\n    this.group = null;\n\n    /**\n    * @property parent\n    * @type gs.Object_Base\n    * @default null\n    * The parent object if the game object is a sub-object of another game object.\n     */\n    this.parent = null;\n\n    /**\n    * @property order\n    * @type number\n    * @default 0\n    * Controls the update-order. The smaller the value the earlier the game object is updated before other game objects are updated.\n     */\n    this.order = 0;\n\n    /**\n    * @property rIndex\n    * @type number\n    * @default 0\n    * Holds the render-index if the game object has a graphical representation on screen. The render-index is the\n    * index of the game object's graphic-object(gs.GraphicObject) in the current list of graphic-objects. The render-index\n    * is read-only. Setting the render-index to a certain value has no effect.\n     */\n    this.rIndex = 0;\n\n    /**\n    * @property needsSort\n    * @type boolean\n    * @default true\n    * Indicates if the list of sub-objects needs to be sorted by order because of a change.\n     */\n    this.needsSort = true;\n\n    /**\n    * @property needsSort\n    * @type boolean\n    * @default true\n    * Indicates if the UI object needs to be updated.\n     */\n    this.needsUpdate = true;\n\n    /**\n    * @property initialized\n    * @type boolean\n    * @default true\n    * Indicates if the game object and its components have been initialized.\n     */\n    this.initialized = false;\n\n    /**\n    * @property customData\n    * @type Object\n    * @default {}\n    * A custom data object which can be used to add any custom data/fields to the game\n    * object. It is an empty object by default.\n     */\n    this.customData = {};\n    if ((ref = gs.ObjectManager.current) != null) {\n      ref.registerObject(this);\n    }\n  }\n\n\n  /**\n  * Disposes the object with all its components and sub-objects. A disposed object will be\n  * removed from the parent automatically.\n  *\n  * @method dispose\n   */\n\n  Object_Base.prototype.dispose = function() {\n    var ref;\n    if (!this.disposed) {\n      this.disposed = true;\n      this.disposeComponents();\n      this.disposeObjects();\n      if ((ref = gs.ObjectManager.current) != null) {\n        ref.unregisterObject(this);\n      }\n    }\n    return null;\n  };\n\n\n  /**\n  * Disposes all sub-objects.\n  *\n  * @method disposeObjects\n  * @protected\n   */\n\n  Object_Base.prototype.disposeObjects = function() {\n    var j, len, ref, results, subObject;\n    ref = this.subObjects;\n    results = [];\n    for (j = 0, len = ref.length; j < len; j++) {\n      subObject = ref[j];\n      results.push(subObject != null ? typeof subObject.dispose === \"function\" ? subObject.dispose() : void 0 : void 0);\n    }\n    return results;\n  };\n\n\n  /**\n  * Disposes all components\n  *\n  * @method disposeComponents\n  * @protected\n   */\n\n  Object_Base.prototype.disposeComponents = function() {\n    var component, j, len, ref, results;\n    ref = this.components;\n    results = [];\n    for (j = 0, len = ref.length; j < len; j++) {\n      component = ref[j];\n      results.push(component != null ? typeof component.dispose === \"function\" ? component.dispose() : void 0 : void 0);\n    }\n    return results;\n  };\n\n\n  /**\n  * Calls setup-routine on all components.\n  *\n  * @method setup\n   */\n\n  Object_Base.prototype.setup = function() {\n    var component, j, len, ref;\n    ref = this.components;\n    for (j = 0, len = ref.length; j < len; j++) {\n      component = ref[j];\n      if (!(component != null ? component.isSetup : void 0)) {\n        component.setup();\n      }\n    }\n    this.initialized = true;\n    return null;\n  };\n\n\n  /**\n  * Deserializes components from a data-bundle object.\n  * \n  * @method componentsFromDataBundle\n  * @param {Object} data The data-bundle object.\n   */\n\n  Object_Base.prototype.componentsFromDataBundle = function(data) {\n    var component, componentObject, j, len, ref;\n    if (data != null ? data.components : void 0) {\n      ref = data.components;\n      for (j = 0, len = ref.length; j < len; j++) {\n        component = ref[j];\n        componentObject = new gs[component.className](component);\n        this.addComponent(componentObject);\n      }\n      delete data.components;\n    }\n    return null;\n  };\n\n\n  /**\n  * Serializes components of a specified type to a data-bundle. A component\n  * needs to implement the toDataBundle method for correct serialization.\n  *\n  * @method componentsToDataBundle\n  * @param {String} type - A component class name.\n  * @return A data bundle.\n   */\n\n  Object_Base.prototype.componentsToDataBundle = function(type) {\n    var bundle, component, components, j, len, ref;\n    components = [];\n    ref = this.components;\n    for (j = 0, len = ref.length; j < len; j++) {\n      component = ref[j];\n      if (component instanceof type) {\n        if (component.toDataBundle == null) {\n          continue;\n        }\n        bundle = component.toDataBundle();\n        bundle.className = component.constructor.name;\n        components.push(bundle);\n      }\n    }\n    return components;\n  };\n\n\n  /**\n  * Starts a full-refresh on all sub-objects\n  *\n  * @method fullRefresh\n   */\n\n  Object_Base.prototype.fullRefresh = function() {\n    var j, len, object, ref;\n    ref = this.subObjects;\n    for (j = 0, len = ref.length; j < len; j++) {\n      object = ref[j];\n      if (object) {\n        object.needsUpdate = true;\n        object.fullRefresh();\n      }\n    }\n    return null;\n  };\n\n\n  /**\n  * Updates the object with all parent- and sub-objects. \n  *\n  * @method fullUpdate\n   */\n\n  Object_Base.prototype.fullUpdate = function() {\n    var j, len, object, parent, ref, results;\n    parent = this;\n    while (parent !== null) {\n      parent.update();\n      parent = parent.parent;\n    }\n    ref = this.subObjects;\n    results = [];\n    for (j = 0, len = ref.length; j < len; j++) {\n      object = ref[j];\n      results.push(object != null ? object.update() : void 0);\n    }\n    return results;\n  };\n\n\n  /**\n  * Updates the object and all its components. This method is\n  * called automatically by the parent or ObjectManager so in regular it is \n  * not necessary to call it manually.\n  *\n  * @method update\n   */\n\n  Object_Base.prototype.update = function() {\n    var component, i;\n    if (!this.active) {\n      return;\n    }\n    i = 0;\n    while (i < this.components.length) {\n      component = this.components[i];\n      if (!component.disposed) {\n        component.update();\n        i++;\n      } else {\n        this.components.splice(i, 1);\n      }\n    }\n    if (this.input) {\n      Input.clear();\n    }\n    this.input = false;\n    return null;\n  };\n\n\n  /**\n  * Searches for the first component with the specified class name.\n  *\n  * @method findComponent\n  * @param {String} name The class name of the component.\n  * @return {Component} The component or null if a component with the specified class name cannot be found.\n   */\n\n  Object_Base.prototype.findComponent = function(name) {\n    return this.components.first(function(v) {\n      return v.constructor.name === name;\n    });\n  };\n\n\n  /**\n  * Searches for all components with the specified class name.\n  *\n  * @method findComponents\n  * @param {String} name The class name of the components.\n  * @return {Array} The components or null if no component with the specified class name has been found.\n   */\n\n  Object_Base.prototype.findComponents = function(name) {\n    return this.components.where(function(v) {\n      return v.constructor.name === name;\n    });\n  };\n\n\n  /**\n  * Searches for the component with the specified ID.\n  *\n  * @method findComponentById\n  * @param {String} id The unique identifier of the component.\n  * @return {Component} The component or null if a component with the specified ID cannot be found.\n   */\n\n  Object_Base.prototype.findComponentById = function(id) {\n    return this.componentsById[id];\n  };\n\n\n  /**\n  * Searches for the component with the specified name. If multiple components have the\n  * same name, it will return the first match.\n  *\n  * @method findComponentByName\n  * @param {String} name The name of the component to find.\n  * @return {Component} The component or null if a component with the specified name cannot be found.\n   */\n\n  Object_Base.prototype.findComponentByName = function(name) {\n    return this.components.first(function(v) {\n      return v.name === name;\n    });\n  };\n\n\n  /**\n  * Searches for components with the specified name.\n  *\n  * @method findComponentsByName\n  * @param {String} name The name of the components to find.\n  * @return {Component[]} An array of components matching the specified name or null if no components with the specified name exist.\n   */\n\n  Object_Base.prototype.findComponentsByName = function(name) {\n    return this.components.where(function(v) {\n      return v.name === name;\n    });\n  };\n\n\n  /**\n  * Adds an object to the list of sub-objects.\n  *\n  * @method addObject\n  * @param {Object_Base} object The object which should be added.\n   */\n\n  Object_Base.prototype.addObject = function(object) {\n    var ref, ref1;\n    if ((ref = gs.ObjectManager.current) != null) {\n      ref.remove(object);\n    }\n    if ((ref1 = object.parent) != null) {\n      ref1.removeObject(object);\n    }\n    object.parent = this;\n    this.subObjects.push(object);\n    this.needsSort = true;\n    this.needsUpdate = true;\n    if (object.id != null) {\n      return gs.ObjectManager.current.setObjectById(object, object.id);\n    }\n  };\n\n\n  /**\n  * Inserts an object into the list of sub-objects at the specified index.\n  *\n  * @method insertObject\n  * @param {Object_Base} object The object which should be inserted.\n  * @param {Number} index The index.\n   */\n\n  Object_Base.prototype.insertObject = function(object, index) {\n    var ref;\n    gs.ObjectManager.current.remove(object);\n    if ((ref = object.parent) != null) {\n      ref.removeObject(object);\n    }\n    object.parent = this;\n    this.subObjects.splice(index, 0, object);\n    if (object.id != null) {\n      return gs.ObjectManager.current.setObjectById(object, object.id);\n    }\n  };\n\n\n  /**\n  * Sets sub-object at the specified index.\n  *\n  * @method setObject\n  * @param {Object_Base} object The object.\n  * @param {Number} index The index.\n   */\n\n  Object_Base.prototype.setObject = function(object, index) {\n    var ref;\n    if (object) {\n      gs.ObjectManager.current.remove(object);\n      if ((ref = object.parent) != null) {\n        ref.removeObject(object);\n      }\n      object.parent = this;\n    }\n    this.subObjects[index] = object;\n    if ((object != null ? object.id : void 0) != null) {\n      return gs.ObjectManager.current.setObjectById(object, object.id);\n    }\n  };\n\n\n  /**\n  * Removes the specified object from the list of sub-objects.\n  *\n  * @method removeObject\n  * @param {Object_Base} object The object which should be removed.\n   */\n\n  Object_Base.prototype.removeObject = function(object) {\n    this.subObjects.remove(object);\n    object.parent = null;\n    return this.needsUpdate = true;\n  };\n\n\n  /**\n  * Removes the object at the specified index from the list of sub-objects.\n  *\n  * @method removeObjectAt\n  * @param {number} index The index of the objec to remove.\n   */\n\n  Object_Base.prototype.removeObjectAt = function(index) {\n    var object;\n    object = this.subObjects[index];\n    this.subObjects.splice(index, 1);\n    object.parent = null;\n    return this.needsUpdate = true;\n  };\n\n\n  /**\n  * Removes all sub-objects.\n  *\n  * @method removeAllObjects\n   */\n\n  Object_Base.prototype.removeAllObjects = function() {\n    var results;\n    results = [];\n    while (this.subObjects.length > 0) {\n      results.push(this.removeObjectAt(0));\n    }\n    return results;\n  };\n\n\n  /**\n  * Erases the object at the specified index. The list size\n  * will not be changed but the the value at the index will be set to null.\n  *\n  * @method eraseObject\n  * @param {Number} object The object which should be erased.\n   */\n\n  Object_Base.prototype.eraseObject = function(index) {\n    var object;\n    object = this.subObjects[index];\n    if (object != null) {\n      object.parent = null;\n    }\n    return this.subObjects[index] = null;\n  };\n\n\n  /**\n  * Adds the specified component to the object.\n  *\n  * @method addComponent\n  * @param {Component} component The component\n  * @param {String} id An optional unique identifier for the component.\n   */\n\n  Object_Base.prototype.addComponent = function(component, id) {\n    if (!this.components.contains(component)) {\n      component.object = this;\n      this.components.push(component);\n      if (id != null) {\n        return this.componentsById[id] = component;\n      }\n    }\n  };\n\n\n  /**\n  * Inserts a component at the specified index.\n  *\n  * @method insertComponent\n  * @param {Component} component The component.\n  * @param {Number} index The index.\n  * @param {String} id An optional unique identifier for the component.\n   */\n\n  Object_Base.prototype.insertComponent = function(component, index, id) {\n    this.components.remove(component);\n    component.object = this;\n    this.components.splice(index, 0, component);\n    if (id != null) {\n      return this.componentsById[id] = component;\n    }\n  };\n\n\n  /**\n  * Removes a component from the object.\n  *\n  * @method removeComponent\n  * @param {Component} component The component to remove.\n   */\n\n  Object_Base.prototype.removeComponent = function(component) {\n    this.components.remove(component);\n    if (typeof id !== \"undefined\" && id !== null) {\n      return delete this.componentsById[id];\n    }\n  };\n\n  return Object_Base;\n\n})();\n\ngs.Object_Base = Object_Base;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7O3dCQVFBLG1CQUFBLEdBQXFCLFNBQUMsSUFBRCxFQUFPLE9BQVA7SUFDakIsSUFBRyxJQUFDLENBQUEsRUFBSjthQUNJLE1BQU8sQ0FBQSxHQUFBLEdBQUksSUFBQyxDQUFBLEVBQUwsQ0FBUCxHQUFrQixLQUR0Qjs7RUFEaUI7O0VBV3JCLFdBQUMsQ0FBQSxTQUFELENBQVcsT0FBWCxFQUNJO0lBQUEsR0FBQSxFQUFLLFNBQUMsQ0FBRDtBQUNELFVBQUE7TUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVOzJEQUNjLENBQUUsVUFBMUIsQ0FBcUMsSUFBckMsRUFBMkMsQ0FBM0M7SUFGQyxDQUFMO0lBSUEsR0FBQSxFQUFLLFNBQUE7YUFBRyxJQUFDLENBQUE7SUFBSixDQUpMO0dBREo7O0VBY0EsV0FBQyxDQUFBLFNBQUQsQ0FBVyxPQUFYLEVBQ0k7SUFBQSxHQUFBLEVBQUssU0FBQyxDQUFEO0FBQ0QsVUFBQTtNQUFBLElBQUcsQ0FBQSxLQUFLLElBQUMsQ0FBQSxNQUFUO1FBQ0ksSUFBQyxDQUFBLE1BQUQsR0FBVTtnREFDSCxDQUFFLFNBQVQsR0FBcUIsY0FGekI7O0lBREMsQ0FBTDtJQUlBLEdBQUEsRUFBSyxTQUFBO2FBQUcsSUFBQyxDQUFBO0lBQUosQ0FKTDtHQURKOztFQWVBLFdBQUMsQ0FBQSxTQUFELENBQVcsYUFBWCxFQUNJO0lBQUEsR0FBQSxFQUFLLFNBQUMsQ0FBRDtBQUNELFVBQUE7TUFBQSxJQUFDLENBQUEsWUFBRCxHQUFnQjtNQUVoQixNQUFBLEdBQVMsSUFBQyxDQUFBO0FBQ1YsYUFBTSxNQUFOO1FBQ0ksTUFBTSxDQUFDLFlBQVAsR0FBc0I7UUFDdEIsTUFBQSxHQUFTLE1BQU0sQ0FBQztNQUZwQjtNQVNBLElBQUcsQ0FBSDtlQUNJLElBQUMsQ0FBQSxnQkFBRCxDQUFBLEVBREo7O0lBYkMs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QUFDLElBQVosQ0FBaUIsU0FBakI7TUFDQSxJQUFHLFVBQUg7ZUFDSSxJQUFDLENBQUEsY0FBZSxDQUFBLEVBQUEsQ0FBaEIsR0FBc0IsVUFEMUI7T0FISjs7RUFEVTs7O0FBTWQ7Ozs7Ozs7Ozt3QkFRQSxlQUFBLEdBQWlCLFNBQUMsU0FBRCxFQUFZLEtBQVosRUFBbUIsRUFBbkI7SUFDYixJQUFDLENBQUEsVUFBVSxDQUFDLE1BQVosQ0FBbUIsU0FBbkI7SUFDQSxTQUFTLENBQUMsTUFBVixHQUFtQjtJQUNuQixJQUFDLENBQUEsVUFBVSxDQUFDLE1BQVosQ0FBbUIsS0FBbkIsRUFBMEIsQ0FBMUIsRUFBNkIsU0FBN0I7SUFDQSxJQUFHLFVBQUg7YUFDSSxJQUFDLENBQUEsY0FBZSxDQUFBLEVBQUEsQ0FBaEIsR0FBc0IsVUFEMUI7O0VBSmE7OztBQU9qQjs7Ozs7Ozt3QkFNQSxlQUFBLEdBQWlCLFNBQUMsU0FBRDtJQUNiLElBQUMsQ0FBQSxVQUFVLENBQUMsTUFBWixDQUFtQixTQUFuQjtJQUNBLElBQUcsd0NBQUg7YUFDSSxPQUFPLElBQUMsQ0FBQSxjQUFlLENBQUEsRUFBQSxFQUQzQjs7RUFGYTs7Ozs7O0FBS3JCLEVBQUUsQ0FBQyxXQUFILEdBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4jXG4jICAgU2NyaXB0OiBPYmplY3RfQmFzZVxuI1xuIyAgICQkQ09QWVJJR0hUJCRcbiNcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuY2xhc3MgT2JqZWN0X0Jhc2VcbiAgICAjIyMqXG4gICAgKiBDYWxsZWQgaWYgdGhpcyBvYmplY3QgaW5zdGFuY2UgaXMgcmVzdG9yZWQgZnJvbSBhIGRhdGEtYnVuZGxlLiBJdCBjYW4gYmUgdXNlZFxuICAgICogcmUtYXNzaWduIGV2ZW50LWhhbmRsZXIsIGFub255bW91cyBmdW5jdGlvbnMsIGV0Yy5cbiAgICAqIFxuICAgICogQG1ldGhvZCBvbkRhdGFCdW5kbGVSZXN0b3JlLlxuICAgICogQHBhcmFtIE9iamVjdCBkYXRhIC0gVGhlIGRhdGEtYnVuZGxlXG4gICAgKiBAcGFyYW0gZ3MuT2JqZWN0Q29kZWNDb250ZXh0IGNvbnRleHQgLSBUaGUgY29kZWMtY29udGV4dC5cbiAgICAjIyNcbiAgICBvbkRhdGFCdW5kbGVSZXN0b3JlOiAoZGF0YSwgY29udGV4dCkgLT5cbiAgICAgICAgaWYgQGlkXG4gICAgICAgICAgICB3aW5kb3dbXCIkXCIrQGlkXSA9IHRoaXNcbiAgICAgICAgICAgIFxuICAgIFxuICAgICNcbiAgICAjIEdldHMgb3Igc2V0cyB0aGUgZ3JvdXAgdGhlIG9iamVjdCBiZWxvbmdzIHRvLlxuICAgICNcbiAgICAjIEBwcm9wZXJ0eSBncm91cFxuICAgICMgQHR5cGUgc3RyaW5nXG4gICAgI1xuICAgIEBhY2Nlc3NvcnMgXCJncm91cFwiLCBcbiAgICAgICAgc2V0OiAoZykgLT4gXG4gICAgICAgICAgICBAZ3JvdXBfID0gZ1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50Py5hZGRUb0dyb3VwKHRoaXMsIGcpXG4gICAgICAgICAgICBcbiAgICAgICAgZ2V0OiAtPiBAZ3JvdXBfXG4gICAgICAgIFxuICAgICNcbiAgICAjIEdldHMgb3Igc2V0cyB0aGUgb3JkZXItaW5kZXggb2YgdGhlIG9iamVjdC4gVGhlIGxvd2VyIHRoZSBpbmRleCwgdGhlXG4gICAgIyBlYXJsaWVyIHRoZSBvYmplY3Qgd2lsbCBiZSB1cGRhdGVkIGluIGEgbGlzdCBvZiBzdWItb2JqZWN0cy5cbiAgICAjXG4gICAgIyBAcHJvcGVydHkgb3JkZXJcbiAgICAjIEB0eXBlIG51bWJlclxuICAgICNcbiAgICBAYWNjZXNzb3JzIFwib3JkZXJcIixcbiAgICAgICAgc2V0OiAobykgLT5cbiAgICAgICAgICAgIGlmIG8gIT0gQG9yZGVyX1xuICAgICAgICAgICAgICAgIEBvcmRlcl8gPSBvXG4gICAgICAgICAgICAgICAgQHBhcmVudD8ubmVlZHNTb3J0ID0gdHJ1ZVxuICAgICAgICBnZXQ6IC0+IEBvcmRlcl9cbiAgICAgICAgXG4gICAgI1xuICAgICMgR2V0cyBvciBzZXRzIGlmIGFuIG9iamVjdHMgbmVlZHMgYW4gdXBkYXRlLiBJZiB0cnVlLCB0aGUgcGFyZW50IHdpbGwgdXBkYXRlXG4gICAgIyB0aGUgb2JqZWN0IGluIHRoZSBuZXh0IHVwZGF0ZSBhbmQgcmVzZXRzIHRoZSBuZWVkc1VwZGF0ZSBwcm9wZXJ0eSBiYWNrXG4gICAgIyB0byBmYWxzZS5cbiAgICAjXG4gICAgIyBAcHJvcGVydHkgbmVlZHNVcGRhdGVcbiAgICAjIEB0eXBlIGJvb2xlYW5cbiAgICAjXG4gICAgQGFjY2Vzc29ycyBcIm5lZWRzVXBkYXRlXCIsIFxuICAgICAgICBzZXQ6ICh2KSAtPlxuICAgICAgICAgICAgQG5lZWRzVXBkYXRlXyA9IHZcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50ID0gQHBhcmVudFxuICAgICAgICAgICAgd2hpbGUgcGFyZW50XG4gICAgICAgICAgICAgICAgcGFyZW50Lm5lZWRzVXBkYXRlXyA9IHllc1xuICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICNpZiB2XG4gICAgICAgICAgICAjICAgIEBwYXJlbnQ/Lm5lZWRzVXBkYXRlID0geWVzXG4gICAgICAgICAgICAjaWYgdlxuICAgICAgICAgICAgIyAgICBmb3Igb2JqZWN0IGluIEBzdWJPYmplY3RzXG4gICAgICAgICAgICAjICAgICAgICBvYmplY3QubmVlZHNVcGRhdGVfID0gdlxuICAgICAgICAgICAgaWYgdlxuICAgICAgICAgICAgICAgIEByZXF1ZXN0U3ViVXBkYXRlKClcbiAgICAgICAgZ2V0OiAtPiByZXR1cm4gQG5lZWRzVXBkYXRlXyB8fCBTY2VuZU1hbmFnZXIuc2NlbmUucHJlcGFyaW5nXG4gICAgICAgIFxuICAgIHJlcXVlc3RTdWJVcGRhdGU6IC0+XG4gICAgICAgIGZvciBvYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgIGlmIG9iamVjdFxuICAgICAgICAgICAgICAgIG9iamVjdC5uZWVkc1VwZGF0ZV8gPSB5ZXNcbiAgICAgICAgICAgICAgICBvYmplY3QucmVxdWVzdFN1YlVwZGF0ZSgpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgI1xuICAgICMgR2V0cyBvciBzZXRzIGlmIGFuIG9iamVjdCBuZWVkcyBhIGZ1bGwgdXBkYXRlLiBBIGZ1bGwgdXBkYXRlIHRyaWdnZXJzXG4gICAgIyBhbiB1cGRhdGUgZm9yIGFsbCBzdWItb2JqZWN0cyByZWN1cnNpdmVseS4gXG4gICAgI1xuICAgICMgQHByb3BlcnR5IG5lZWRzRnVsbFVwZGF0ZVxuICAgICMgQHR5cGUgYm9vbGVhblxuICAgICNcbiAgICBAYWNjZXNzb3JzIFwibmVlZHNGdWxsVXBkYXRlXCIsIFxuICAgICAgICBzZXQ6ICh2KSAtPlxuICAgICAgICAgICAgQG5lZWRzVXBkYXRlID0gdlxuICAgICAgICAgICAgaWYgdlxuICAgICAgICAgICAgICAgIGZvciBvYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm5lZWRzRnVsbFVwZGF0ZSA9IHZcbiAgICAgICAgZ2V0OiAtPiBAbmVlZHNVcGRhdGVfXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBUaGUgYmFzZSBjbGFzcyBmb3IgYWxsIGdhbWUgb2JqZWN0cy4gQSBnYW1lIG9iamVjdCBpdHNlbGYgZG9lc24ndCBpbXBsZW1lbnRcbiAgICAqIGFueSBnYW1lIGxvZ2ljIGJ1dCB1c2VzIGNvbXBvbmVudHMgYW5kIHN1Yi1vYmplY3RzIGZvciB0aGF0LlxuICAgICpcbiAgICAqIEBtb2R1bGUgZ3NcbiAgICAqIEBjbGFzcyBPYmplY3RfQmFzZVxuICAgICogQG1lbWJlcm9mIGdzXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAjIyNcbiAgICBjb25zdHJ1Y3RvcjogKCkgLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdWJPYmplY3RzXG4gICAgICAgICogQHR5cGUgZ3MuT2JqZWN0X0Jhc2VbXVxuICAgICAgICAqIEBkZWZhdWx0IFtdXG4gICAgICAgICogQSBsaXN0IG9mIGdhbWUtb2JqZWN0cyBncm91cGVkIHVuZGVyIHRoaXMgZ2FtZSBvYmplY3QuXG4gICAgICAgICMjI1xuICAgICAgICBAc3ViT2JqZWN0cyA9IFtdXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGNvbXBvbmVudHNcbiAgICAgICAgKiBAdHlwZSBncy5Db21wb25lbnRbXVxuICAgICAgICAqIEBkZWZhdWx0IFtdXG4gICAgICAgICogQSBsaXN0IG9mIGNvbXBvbmVudHMgZGVmaW5pbmcgdGhlIGxvZ2ljL2JlaGF2aW9yIGFuZCBhcHBlYXJhbmNlIG9mIHRoZSBnYW1lIG9iamVjdC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBjb21wb25lbnRzID0gW11cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgY29tcG9uZW50c0J5SWRcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgKiBAZGVmYXVsdCBbXVxuICAgICAgICAqIEFsbCBhc3NvY2lhdGVkIGNvbXBvbmVudHMgYnkgdGhlaXIgSUQuXG4gICAgICAgICMjI1xuICAgICAgICBAY29tcG9uZW50c0J5SWQgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBkaXNwb3NlZFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgZ2FtZSBvYmplY3QgaWQgZGlzcG9zZWQuIEEgZGlzcG9zZWQgZ2FtZSBvYmplY3QgY2Fubm90IGJlIHVzZWQgYW55bW9yZS5cbiAgICAgICAgIyMjXG4gICAgICAgIEBkaXNwb3NlZCA9IG5vXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGFjdGl2ZVxuICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGdhbWUgb2JqZWN0IGlzIGFjdGl2ZS4gQW4gaW5hY3RpdmUgZ2FtZSBvYmplY3Qgd2lsbCBub3QgYmUgdXBkYXRlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBhY3RpdmUgPSB5ZXNcbiAgICAgICAgXG4gICAgICAgIEBpbnB1dCA9IG5vXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGlkXG4gICAgICAgICogQHR5cGUgc3RyaW5nXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIFRoZSBnYW1lIG9iamVjdCdzIFVJRCAoVW5pcXVlIElEKVxuICAgICAgICAjIyNcbiAgICAgICAgQGlkID0gbnVsbCBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgZ3JvdXBcbiAgICAgICAgKiBAZGVmYXVsdCBudWxsXG4gICAgICAgICogQHR5cGUgc3RyaW5nXG4gICAgICAgICogVGhlIGdhbWUgb2JqZWN0J3MgZ3JvdXAuIFRvIGdldCBhbGwgb2JqZWN0J3Mgb2YgYSBzcGVjaWZpYyBncm91cCB0aGUgZ3MuT2JqZWN0TWFuYWdlci5vYmplY3RzQnlHcm91cCBwcm9wZXJ0eSBjYW4gYmUgdXNlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBncm91cCA9IG51bGwgXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IHBhcmVudFxuICAgICAgICAqIEB0eXBlIGdzLk9iamVjdF9CYXNlXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIFRoZSBwYXJlbnQgb2JqZWN0IGlmIHRoZSBnYW1lIG9iamVjdCBpcyBhIHN1Yi1vYmplY3Qgb2YgYW5vdGhlciBnYW1lIG9iamVjdC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBwYXJlbnQgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IG9yZGVyXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQGRlZmF1bHQgMFxuICAgICAgICAqIENvbnRyb2xzIHRoZSB1cGRhdGUtb3JkZXIuIFRoZSBzbWFsbGVyIHRoZSB2YWx1ZSB0aGUgZWFybGllciB0aGUgZ2FtZSBvYmplY3QgaXMgdXBkYXRlZCBiZWZvcmUgb3RoZXIgZ2FtZSBvYmplY3RzIGFyZSB1cGRhdGVkLlxuICAgICAgICAjIyNcbiAgICAgICAgQG9yZGVyID0gMFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBySW5kZXhcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgKiBAZGVmYXVsdCAwXG4gICAgICAgICogSG9sZHMgdGhlIHJlbmRlci1pbmRleCBpZiB0aGUgZ2FtZSBvYmplY3QgaGFzIGEgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9uIHNjcmVlbi4gVGhlIHJlbmRlci1pbmRleCBpcyB0aGVcbiAgICAgICAgKiBpbmRleCBvZiB0aGUgZ2FtZSBvYmplY3QncyBncmFwaGljLW9iamVjdChncy5HcmFwaGljT2JqZWN0KSBpbiB0aGUgY3VycmVudCBsaXN0IG9mIGdyYXBoaWMtb2JqZWN0cy4gVGhlIHJlbmRlci1pbmRleFxuICAgICAgICAqIGlzIHJlYWQtb25seS4gU2V0dGluZyB0aGUgcmVuZGVyLWluZGV4IHRvIGEgY2VydGFpbiB2YWx1ZSBoYXMgbm8gZWZmZWN0LlxuICAgICAgICAjIyNcbiAgICAgICAgQHJJbmRleCA9IDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgbmVlZHNTb3J0XG4gICAgICAgICogQHR5cGUgYm9vbGVhblxuICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGxpc3Qgb2Ygc3ViLW9iamVjdHMgbmVlZHMgdG8gYmUgc29ydGVkIGJ5IG9yZGVyIGJlY2F1c2Ugb2YgYSBjaGFuZ2UuXG4gICAgICAgICMjI1xuICAgICAgICBAbmVlZHNTb3J0ID0geWVzXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IG5lZWRzU29ydFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBVSSBvYmplY3QgbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBuZWVkc1VwZGF0ZSA9IHllc1xuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBpbml0aWFsaXplZFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBnYW1lIG9iamVjdCBhbmQgaXRzIGNvbXBvbmVudHMgaGF2ZSBiZWVuIGluaXRpYWxpemVkLlxuICAgICAgICAjIyNcbiAgICAgICAgQGluaXRpYWxpemVkID0gbm9cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tRGF0YVxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAqIEBkZWZhdWx0IHt9XG4gICAgICAgICogQSBjdXN0b20gZGF0YSBvYmplY3Qgd2hpY2ggY2FuIGJlIHVzZWQgdG8gYWRkIGFueSBjdXN0b20gZGF0YS9maWVsZHMgdG8gdGhlIGdhbWVcbiAgICAgICAgKiBvYmplY3QuIEl0IGlzIGFuIGVtcHR5IG9iamVjdCBieSBkZWZhdWx0LlxuICAgICAgICAjIyNcbiAgICAgICAgQGN1c3RvbURhdGEgPSB7fVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8ucmVnaXN0ZXJPYmplY3QodGhpcylcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgdGhlIG9iamVjdCB3aXRoIGFsbCBpdHMgY29tcG9uZW50cyBhbmQgc3ViLW9iamVjdHMuIEEgZGlzcG9zZWQgb2JqZWN0IHdpbGwgYmVcbiAgICAqIHJlbW92ZWQgZnJvbSB0aGUgcGFyZW50IGF1dG9tYXRpY2FsbHkuXG4gICAgKlxuICAgICogQG1ldGhvZCBkaXNwb3NlXG4gICAgIyMjXG4gICAgZGlzcG9zZTogLT5cbiAgICAgICAgaWYgbm90IEBkaXNwb3NlZFxuICAgICAgICAgICAgQGRpc3Bvc2VkID0geWVzXG4gICAgICAgICAgICBAZGlzcG9zZUNvbXBvbmVudHMoKVxuICAgICAgICAgICAgQGRpc3Bvc2VPYmplY3RzKClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8udW5yZWdpc3Rlck9iamVjdCh0aGlzKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgYWxsIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZU9iamVjdHNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyNcbiAgICBkaXNwb3NlT2JqZWN0czogLT5cbiAgICAgICAgZm9yIHN1Yk9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgc3ViT2JqZWN0Py5kaXNwb3NlPygpXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBEaXNwb3NlcyBhbGwgY29tcG9uZW50c1xuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZUNvbXBvbmVudHNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyNcbiAgICBkaXNwb3NlQ29tcG9uZW50czogLT5cbiAgICAgICAgZm9yIGNvbXBvbmVudCBpbiBAY29tcG9uZW50c1xuICAgICAgICAgICAgY29tcG9uZW50Py5kaXNwb3NlPygpXG4gICAgICAgXG4gICAgIyMjKlxuICAgICogQ2FsbHMgc2V0dXAtcm91dGluZSBvbiBhbGwgY29tcG9uZW50cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldHVwXG4gICAgIyMjXG4gICAgc2V0dXA6IC0+XG4gICAgICAgIGZvciBjb21wb25lbnQgaW4gQGNvbXBvbmVudHNcbiAgICAgICAgICAgIGNvbXBvbmVudC5zZXR1cCgpIGlmIG5vdCBjb21wb25lbnQ/LmlzU2V0dXBcbiAgICAgICAgICAgIFxuICAgICAgICBAaW5pdGlhbGl6ZWQgPSB5ZXNcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGVzZXJpYWxpemVzIGNvbXBvbmVudHMgZnJvbSBhIGRhdGEtYnVuZGxlIG9iamVjdC5cbiAgICAqIFxuICAgICogQG1ldGhvZCBjb21wb25lbnRzRnJvbURhdGFCdW5kbGVcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIFRoZSBkYXRhLWJ1bmRsZSBvYmplY3QuXG4gICAgIyMjXG4gICAgY29tcG9uZW50c0Zyb21EYXRhQnVuZGxlOiAoZGF0YSkgLT5cbiAgICAgICAgaWYgZGF0YT8uY29tcG9uZW50c1xuICAgICAgICAgICAgZm9yIGNvbXBvbmVudCBpbiBkYXRhLmNvbXBvbmVudHNcbiAgICAgICAgICAgICAgICBjb21wb25lbnRPYmplY3QgPSBuZXcgZ3NbY29tcG9uZW50LmNsYXNzTmFtZV0oY29tcG9uZW50KVxuICAgICAgICAgICAgICAgIEBhZGRDb21wb25lbnQoY29tcG9uZW50T2JqZWN0KVxuICAgICAgICAgICAgZGVsZXRlIGRhdGEuY29tcG9uZW50c1xuICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXJpYWxpemVzIGNvbXBvbmVudHMgb2YgYSBzcGVjaWZpZWQgdHlwZSB0byBhIGRhdGEtYnVuZGxlLiBBIGNvbXBvbmVudFxuICAgICogbmVlZHMgdG8gaW1wbGVtZW50IHRoZSB0b0RhdGFCdW5kbGUgbWV0aG9kIGZvciBjb3JyZWN0IHNlcmlhbGl6YXRpb24uXG4gICAgKlxuICAgICogQG1ldGhvZCBjb21wb25lbnRzVG9EYXRhQnVuZGxlXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIEEgY29tcG9uZW50IGNsYXNzIG5hbWUuXG4gICAgKiBAcmV0dXJuIEEgZGF0YSBidW5kbGUuXG4gICAgIyMjXG4gICAgY29tcG9uZW50c1RvRGF0YUJ1bmRsZTogKHR5cGUpIC0+XG4gICAgICAgIGNvbXBvbmVudHMgPSBbXVxuICAgICAgICBmb3IgY29tcG9uZW50IGluIEBjb21wb25lbnRzXG4gICAgICAgICAgICBpZiBjb21wb25lbnQgaW5zdGFuY2VvZiB0eXBlXG4gICAgICAgICAgICAgICAgY29udGludWUgdW5sZXNzIGNvbXBvbmVudC50b0RhdGFCdW5kbGU/XG4gICAgICAgICAgICAgICAgYnVuZGxlID0gY29tcG9uZW50LnRvRGF0YUJ1bmRsZSgpXG4gICAgICAgICAgICAgICAgYnVuZGxlLmNsYXNzTmFtZSA9IGNvbXBvbmVudC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKGJ1bmRsZSlcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudHNcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogU3RhcnRzIGEgZnVsbC1yZWZyZXNoIG9uIGFsbCBzdWItb2JqZWN0c1xuICAgICpcbiAgICAqIEBtZXRob2QgZnVsbFJlZnJlc2hcbiAgICAjIyNcbiAgICBmdWxsUmVmcmVzaDogLT5cbiAgICAgICAgZm9yIG9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgaWYgb2JqZWN0XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5lZWRzVXBkYXRlID0geWVzXG4gICAgICAgICAgICAgICAgb2JqZWN0LmZ1bGxSZWZyZXNoKClcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIFxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgdGhlIG9iamVjdCB3aXRoIGFsbCBwYXJlbnQtIGFuZCBzdWItb2JqZWN0cy4gXG4gICAgKlxuICAgICogQG1ldGhvZCBmdWxsVXBkYXRlXG4gICAgIyMjXG4gICAgZnVsbFVwZGF0ZTogLT5cbiAgICAgICAgcGFyZW50ID0gdGhpc1xuICAgICAgICB3aGlsZSBwYXJlbnQgIT0gbnVsbFxuICAgICAgICAgICAgcGFyZW50LnVwZGF0ZSgpXG4gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50XG4gICAgICAgICAgICBcbiAgICAgICAgZm9yIG9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgb2JqZWN0Py51cGRhdGUoKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBVcGRhdGVzIHRoZSBvYmplY3QgYW5kIGFsbCBpdHMgY29tcG9uZW50cy4gVGhpcyBtZXRob2QgaXNcbiAgICAqIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSBwYXJlbnQgb3IgT2JqZWN0TWFuYWdlciBzbyBpbiByZWd1bGFyIGl0IGlzIFxuICAgICogbm90IG5lY2Vzc2FyeSB0byBjYWxsIGl0IG1hbnVhbGx5LlxuICAgICpcbiAgICAqIEBtZXRob2QgdXBkYXRlXG4gICAgIyMjXG4gICAgdXBkYXRlOiAtPlxuICAgICAgICByZXR1cm4gaWYgIUBhY3RpdmVcbiAgICAgICAgaSA9IDBcbiAgICAgICAgd2hpbGUgaSA8IEBjb21wb25lbnRzLmxlbmd0aFxuICAgICAgICAgICAgY29tcG9uZW50ID0gQGNvbXBvbmVudHNbaV1cbiAgICAgICAgICAgIGlmIG5vdCBjb21wb25lbnQuZGlzcG9zZWRcbiAgICAgICAgICAgICAgICBjb21wb25lbnQudXBkYXRlKClcbiAgICAgICAgICAgICAgICBpKytcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBAY29tcG9uZW50cy5zcGxpY2UoaSwgMSlcblxuXG4gICAgICAgIGlmIEBpbnB1dCB0aGVuIElucHV0LmNsZWFyKClcbiAgICAgICAgQGlucHV0ID0gbm9cbiAgICAgICAgXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRDb21wb25lbnRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSBjb21wb25lbnQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgb3IgbnVsbCBpZiBhIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZSBjYW5ub3QgYmUgZm91bmQuXG4gICAgIyMjXG4gICAgZmluZENvbXBvbmVudDogKG5hbWUpIC0+IEBjb21wb25lbnRzLmZpcnN0ICh2KSAtPiB2LmNvbnN0cnVjdG9yLm5hbWUgPT0gbmFtZVxuICAgIFxuICAgICMjIypcbiAgICAqIFNlYXJjaGVzIGZvciBhbGwgY29tcG9uZW50cyB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRDb21wb25lbnRzXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgY29tcG9uZW50cy5cbiAgICAqIEByZXR1cm4ge0FycmF5fSBUaGUgY29tcG9uZW50cyBvciBudWxsIGlmIG5vIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZSBoYXMgYmVlbiBmb3VuZC5cbiAgICAjIyNcbiAgICBmaW5kQ29tcG9uZW50czogKG5hbWUpIC0+IEBjb21wb25lbnRzLndoZXJlICh2KSAtPiB2LmNvbnN0cnVjdG9yLm5hbWUgPT0gbmFtZVxuICAgIFxuICAgICMjIypcbiAgICAqIFNlYXJjaGVzIGZvciB0aGUgY29tcG9uZW50IHdpdGggdGhlIHNwZWNpZmllZCBJRC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRDb21wb25lbnRCeUlkXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBjb21wb25lbnQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgb3IgbnVsbCBpZiBhIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgSUQgY2Fubm90IGJlIGZvdW5kLlxuICAgICMjI1xuICAgIGZpbmRDb21wb25lbnRCeUlkOiAoaWQpIC0+IEBjb21wb25lbnRzQnlJZFtpZF1cbiAgICBcbiAgICAjIyMqXG4gICAgKiBTZWFyY2hlcyBmb3IgdGhlIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gSWYgbXVsdGlwbGUgY29tcG9uZW50cyBoYXZlIHRoZVxuICAgICogc2FtZSBuYW1lLCBpdCB3aWxsIHJldHVybiB0aGUgZmlyc3QgbWF0Y2guXG4gICAgKlxuICAgICogQG1ldGhvZCBmaW5kQ29tcG9uZW50QnlOYW1lXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY29tcG9uZW50IHRvIGZpbmQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgb3IgbnVsbCBpZiBhIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBjYW5ub3QgYmUgZm91bmQuXG4gICAgIyMjXG4gICAgZmluZENvbXBvbmVudEJ5TmFtZTogKG5hbWUpIC0+IEBjb21wb25lbnRzLmZpcnN0ICh2KSAtPiB2Lm5hbWUgPT0gbmFtZVxuICAgIFxuICAgICMjIypcbiAgICAqIFNlYXJjaGVzIGZvciBjb21wb25lbnRzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLlxuICAgICpcbiAgICAqIEBtZXRob2QgZmluZENvbXBvbmVudHNCeU5hbWVcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnRzIHRvIGZpbmQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnRbXX0gQW4gYXJyYXkgb2YgY29tcG9uZW50cyBtYXRjaGluZyB0aGUgc3BlY2lmaWVkIG5hbWUgb3IgbnVsbCBpZiBubyBjb21wb25lbnRzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGV4aXN0LlxuICAgICMjI1xuICAgIGZpbmRDb21wb25lbnRzQnlOYW1lOiAobmFtZSkgLT4gQGNvbXBvbmVudHMud2hlcmUgKHYpIC0+IHYubmFtZSA9PSBuYW1lXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyBhbiBvYmplY3QgdG8gdGhlIGxpc3Qgb2Ygc3ViLW9iamVjdHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBhZGRPYmplY3RcbiAgICAqIEBwYXJhbSB7T2JqZWN0X0Jhc2V9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBhZGRlZC5cbiAgICAjIyNcbiAgICBhZGRPYmplY3Q6IChvYmplY3QpIC0+XG4gICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8ucmVtb3ZlKG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudD8ucmVtb3ZlT2JqZWN0KG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgQHN1Yk9iamVjdHMucHVzaChvYmplY3QpXG4gICAgICAgIEBuZWVkc1NvcnQgPSB5ZXNcbiAgICAgICAgQG5lZWRzVXBkYXRlID0geWVzXG4gICAgXG4gICAgICAgIGlmIG9iamVjdC5pZD9cbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudC5zZXRPYmplY3RCeUlkKG9iamVjdCwgb2JqZWN0LmlkKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBJbnNlcnRzIGFuIG9iamVjdCBpbnRvIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAgKlxuICAgICogQG1ldGhvZCBpbnNlcnRPYmplY3RcbiAgICAqIEBwYXJhbSB7T2JqZWN0X0Jhc2V9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBpbnNlcnRlZC5cbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCBUaGUgaW5kZXguXG4gICAgIyMjXG4gICAgaW5zZXJ0T2JqZWN0OihvYmplY3QsIGluZGV4KSAtPlxuICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQucmVtb3ZlKG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudD8ucmVtb3ZlT2JqZWN0KG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgQHN1Yk9iamVjdHMuc3BsaWNlKGluZGV4LCAwLCBvYmplY3QpXG4gICAgICBcbiAgICAgICAgaWYgb2JqZWN0LmlkP1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQob2JqZWN0LCBvYmplY3QuaWQpXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHN1Yi1vYmplY3QgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldE9iamVjdFxuICAgICogQHBhcmFtIHtPYmplY3RfQmFzZX0gb2JqZWN0IFRoZSBvYmplY3QuXG4gICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4LlxuICAgICMjI1xuICAgIHNldE9iamVjdDogKG9iamVjdCwgaW5kZXgpIC0+XG4gICAgICAgIGlmIG9iamVjdFxuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnJlbW92ZShvYmplY3QpXG4gICAgICAgICAgICBvYmplY3QucGFyZW50Py5yZW1vdmVPYmplY3Qob2JqZWN0KVxuICAgICAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgICAgIFxuICAgICAgICBAc3ViT2JqZWN0c1tpbmRleF0gPSBvYmplY3RcbiAgICAgIFxuICAgICAgICBpZiBvYmplY3Q/LmlkP1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQob2JqZWN0LCBvYmplY3QuaWQpXG4gICAgXG4gICAgIyMjKlxuICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCBmcm9tIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVtb3ZlT2JqZWN0XG4gICAgKiBAcGFyYW0ge09iamVjdF9CYXNlfSBvYmplY3QgVGhlIG9iamVjdCB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZC5cbiAgICAjIyNcbiAgICByZW1vdmVPYmplY3Q6IChvYmplY3QpIC0+XG4gICAgICAgIEBzdWJPYmplY3RzLnJlbW92ZShvYmplY3QpXG4gICAgICAgIG9iamVjdC5wYXJlbnQgPSBudWxsXG4gICAgICAgIEBuZWVkc1VwZGF0ZSA9IHllc1xuICAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBmcm9tIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVtb3ZlT2JqZWN0QXRcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG9iamVjIHRvIHJlbW92ZS5cbiAgICAjIyMgICBcbiAgICByZW1vdmVPYmplY3RBdDogKGluZGV4KSAtPlxuICAgICAgICBvYmplY3QgPSBAc3ViT2JqZWN0c1tpbmRleF1cbiAgICAgICAgQHN1Yk9iamVjdHMuc3BsaWNlKGluZGV4LCAxKVxuICAgICAgICBvYmplY3QucGFyZW50ID0gbnVsbFxuICAgICAgICBAbmVlZHNVcGRhdGUgPSB5ZXNcbiAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIGFsbCBzdWItb2JqZWN0cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlbW92ZUFsbE9iamVjdHNcbiAgICAjIyMgICAgIFxuICAgIHJlbW92ZUFsbE9iamVjdHM6IC0+XG4gICAgICAgIHdoaWxlIEBzdWJPYmplY3RzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgIEByZW1vdmVPYmplY3RBdCgwKVxuICAgIFxuICAgICMjIypcbiAgICAqIEVyYXNlcyB0aGUgb2JqZWN0IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoZSBsaXN0IHNpemVcbiAgICAqIHdpbGwgbm90IGJlIGNoYW5nZWQgYnV0IHRoZSB0aGUgdmFsdWUgYXQgdGhlIGluZGV4IHdpbGwgYmUgc2V0IHRvIG51bGwuXG4gICAgKlxuICAgICogQG1ldGhvZCBlcmFzZU9iamVjdFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBlcmFzZWQuXG4gICAgIyMjXG4gICAgZXJhc2VPYmplY3Q6IChpbmRleCkgLT5cbiAgICAgICAgb2JqZWN0ID0gQHN1Yk9iamVjdHNbaW5kZXhdXG4gICAgICAgIG9iamVjdD8ucGFyZW50ID0gbnVsbFxuICAgICAgICBAc3ViT2JqZWN0c1tpbmRleF0gPSBudWxsXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudCB0byB0aGUgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgYWRkQ29tcG9uZW50XG4gICAgKiBAcGFyYW0ge0NvbXBvbmVudH0gY29tcG9uZW50IFRoZSBjb21wb25lbnRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBBbiBvcHRpb25hbCB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbXBvbmVudC5cbiAgICAjIyNcbiAgICBhZGRDb21wb25lbnQ6IChjb21wb25lbnQsIGlkKSAtPlxuICAgICAgICBpZiBub3QgQGNvbXBvbmVudHMuY29udGFpbnMoY29tcG9uZW50KVxuICAgICAgICAgICAgY29tcG9uZW50Lm9iamVjdCA9IHRoaXNcbiAgICAgICAgICAgIEBjb21wb25lbnRzLnB1c2goY29tcG9uZW50KVxuICAgICAgICAgICAgaWYgaWQ/XG4gICAgICAgICAgICAgICAgQGNvbXBvbmVudHNCeUlkW2lkXSA9IGNvbXBvbmVudFxuICAgICMjIypcbiAgICAqIEluc2VydHMgYSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGluc2VydENvbXBvbmVudFxuICAgICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBUaGUgY29tcG9uZW50LlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4IFRoZSBpbmRleC5cbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBBbiBvcHRpb25hbCB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbXBvbmVudC5cbiAgICAjIyMgICAgXG4gICAgaW5zZXJ0Q29tcG9uZW50OiAoY29tcG9uZW50LCBpbmRleCwgaWQpIC0+XG4gICAgICAgIEBjb21wb25lbnRzLnJlbW92ZShjb21wb25lbnQpXG4gICAgICAgIGNvbXBvbmVudC5vYmplY3QgPSB0aGlzXG4gICAgICAgIEBjb21wb25lbnRzLnNwbGljZShpbmRleCwgMCwgY29tcG9uZW50KVxuICAgICAgICBpZiBpZD9cbiAgICAgICAgICAgIEBjb21wb25lbnRzQnlJZFtpZF0gPSBjb21wb25lbnRcbiAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIGEgY29tcG9uZW50IGZyb20gdGhlIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlbW92ZUNvbXBvbmVudFxuICAgICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHRvIHJlbW92ZS5cbiAgICAjIyMgIFxuICAgIHJlbW92ZUNvbXBvbmVudDogKGNvbXBvbmVudCkgLT4gXG4gICAgICAgIEBjb21wb25lbnRzLnJlbW92ZShjb21wb25lbnQpXG4gICAgICAgIGlmIGlkP1xuICAgICAgICAgICAgZGVsZXRlIEBjb21wb25lbnRzQnlJZFtpZF1cblxuZ3MuT2JqZWN0X0Jhc2UgPSBPYmplY3RfQmFzZSJdfQ==\n//# sourceURL=Object_Base_14.js"
    },
    "summary": [
        "name",
        "type",
        "order"
    ]
}

Commits for Nextrek/s2s/data/19D5B266K1082A4D01S85D0E17BE2BBA69F8.json

Diff revisions: vs.
Revision Author Commited Message
1087 Diff Diff ASorrentino picture ASorrentino Fri 11 May, 2018 23:44:48 +0000

Statistiche corrette

1086 Diff Diff ASorrentino picture ASorrentino Fri 11 May, 2018 21:50:37 +0000
1084 MOliva picture MOliva Fri 11 May, 2018 12:41:55 +0000