[
  {
    "path": ".eslintignore",
    "content": "dist\nclients\nthirdparty\nwebpack.config.js\nclean.js\n"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"ecmaVersion\": 9,\n    \"sourceType\": \"module\",\n    \"project\": [\"./tsconfig.json\"]\n  },\n  \"plugins\": [\n    \"@typescript-eslint\"\n  ],\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:@typescript-eslint/eslint-recommended\",\n    \"plugin:@typescript-eslint/recommended\"\n  ],\n  \"rules\": {\n    \"eol-last\": \"error\",\n    \"@typescript-eslint/indent\": [\n      \"error\",\n      2\n    ],\n    \"no-tabs\": \"error\",\n    \"@typescript-eslint/semi\": \"error\",\n    \"@typescript-eslint/no-extra-semi\": 2,\n    \"prefer-const\": \"error\",\n    \"@typescript-eslint/object-curly-spacing\": [ \"error\", \"always\", { \"arraysInObjects\": false, \"objectsInObjects\": false }],\n    \"array-bracket-spacing\": [\"error\", \"never\"],\n    \"@typescript-eslint/no-unnecessary-type-assertion\": \"error\",\n    \"no-return-await\": \"error\",\n    \"@typescript-eslint/explicit-function-return-type\": \"error\",\n    \"@typescript-eslint/no-unused-vars\": [\"error\", { \"argsIgnorePattern\": \"^_\", \"varsIgnorePattern\": \"^_\" }],\n    \"@typescript-eslint/no-empty-function\": \"warn\",\n    \"no-empty\": \"warn\"\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\ndist\npackage-lock.json"
  },
  {
    "path": ".npmignore",
    "content": ".*\n**/tsconfig.json\n**/webpack.config.js\nnode_modules\nViewer.code-workspace\nViewer.sublime-project\nsrc\nclients\ndist/clients\nclean.js\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "If you want to contribute, here are a few notes:\n\n1) If the changes are related in any way to the viewer itself (parsers that are used, handlers, shaders, etc.), then the unit tests must all pass.\nThis of course doesn't include unit tests that are directly related to the changes, and thus need to be updated.\n\n2) If the changes are related to real-time parts of the code, they should be efficient! There are no such things as real-time heap allocations (e.g. `new`, `[]`, `{}`), typed arrays are generally preferred for data storage over arrays/objects, and so on.\n\n3) Use `npm run dev` to start webpack in watch mode and re-build the source as you write it.\n\n4) Have fun :)\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2021 Chananya Freiman\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "**NO LONGER ACTIVELY MAINTAINED.**\n\nmdx-m3-viewer\n=============\n\nAt the core of it, a 3D model viewer for MDX and M3 models used by the games Warcraft 3 and Starcraft 2 respectively.\n\nThe viewer part handles the following formats:\n* MDX (Warcraft 3 model): extensive support, almost everything should work.\n* M3 (Starcraft 2 model): partial support.\n* W3M/W3X (Warcraft 3 map): partial support.\n* BLP1 (Warcraft 3 texture): extensive support, almost everything should work.\n* TGA (image): extensive support, almost everything should work.\n* DDS (compressed texture): partial support - DXT1/DXT3/DXT5/RGTC.\n* PNG/JPG/GIF/WebP: supported by the browser.\n\nThere are file parsers that the viewer depends on.\\\nThese don't rely on the viewer or indeed on even running in a browser.\\\nThey include:\n* MDX/MDL: read/write.\n* M3: read.\n* BLP1: read.\n* INI: read/write.\n* SLK: read/write.\n* MPQ1: read/write.\n* W3M/W3X/W3N: read/write, including all of the internal files.\n* DDS: read (DXT1/DXT3/DXT5/RGTC).\n* TGA: read.\n\nThere are all sorts of utilities that were made over the years.\\\nThese include things like...\n* The library's unit tester, which compares rendered results against stored images that were generated in the same way.\n* The MDX sanity test, which looks for errors and weird things in MDX models.\n* A Jass context that can...well, run Jass code. That being said, it really runs Lua code converted from Jass, on a JS Lua VM. What a tongue twiser. While it supports some Warcraft 3 natives, don't expect it run whole maps. Maybe in the future 😉\n* A utility that makes it possible to open Warcraft 3 maps in the vanilla World Editor, in cases were said maps used a non-vanilla editor with extended GUI, in which case they crash upon opening in the official editor.\n* etc.\n\nFinally, the library also comes with a bunch of clients.\\\nA \"client\" in this context means external code that uses the library.\\\nMost of these clients are simple and messy, since they were made as side projects while working on the library.\\\nMost of these clients are also just wrappers around the viewer and the utilities, merely giving them an interface on a web page.\\\nThese include things like...\n* A simple example client.\n* The unit tester's page, which allows to run the unit tests, and to download the results.\n* The MDX sanity test's page, which visually shows the results of sanity tests, and other nifty things.\n* etc.\n\n------------------------\n\n#### Building\n\n```\nnpm install mdx-m3-viewer\nnpm run build\n```\nThis will generate the CommonJS, UMD, and the packed clients under `dist`.\n\n------------------------\n\n#### Examples\n\nRun the Webpack dev server with:\n```\nnpm run serve\n```\n\nOnce it compiled the code, open `http://localhost:8080/clients/example/` in the browser, and play with the client's source to see how things change.\n\nYou can also check out the other available clients.\n\n------------------------\n\n#### Importing\n\nYou can import the viewer in different ways:\n```javascript\n// UMD export in the browser.\nnew ModelViewer.viewer.ModelViewer(canvas);\n\n// require/import the library.\nconst ModelViewer = require('mdx-m3-viewer'); // CommonJS.\nimport ModelViewer from 'mdx-m3-viewer'; // ES6.\nnew ModelViewer.viewer.ModelViewer(canvas);\n\n// require/import something directly.\nconst ModelViewer = require('mdx-m3-viewer/src/viewer/viewer'); // CommonJS.\nimport ModelViewer from 'mdx-m3-viewer/src/viewer/viewer'; // ES6.\nnew ModelViewer(canvas);\n```\n\nWhen developing with TypeScript, nothing needs to be done to get correct typings.\nThis is true also when importing specific files, which means a client can import only what it needs from the library.\n\nAll code snippets will use the names as if you imported them directly to avoid some mess. See the examples for actual namespacing.\n\n------------------------\n\n#### Usage\n\nFirst, let's create the viewer:\n```javascript\nlet canvas = ...; // A <canvas> aka HTMLCanvasElement object.\n\nlet viewer = new ModelViewer(canvas);\n```\n\nIf the client doesn't have the WebGL requierments to run the viewer, an exception will be thrown when trying to create it.\n\nNow that we have a viewer, a scene can be created.\nEach scene has its own camera and viewport, and holds a list of things to update and render.\n```javascript\nlet scene = viewer.addScene();\n\n// Move the camera backwards a bit, so we can actually see the origin.\nscene.camera.move([0, 0, 500]);\n```\n\nFinally, we need to actually let the viewer update and render:\n```javascript\n(function step() {\n  requestAnimationFrame(step);\n\n  viewer.updateAndRender();\n}());\n```\n\n---\n\nModels and textures are loaded with the `load` function.\n\nTo load models and textures with `load`, the viewer must have handlers that tell it how to load the different file formats.\\\nIf you want to load an MDX model, the MDX handler must be added to the viewer, and so on.\\\nThis is done with the `addHandler` function, and the different handlers are exported as a part of the library.\n\nLet's add the MDX and BLP handlers:\n```javascript\nviewer.addHandler(handlers.mdx);\nviewer.addHandler(handlers.blp);\n```\n\nNow MDX (and MDL) and BLP files will be accepted by the viewer.\n\nSuppose we have the following directory structure, where `model.mdx` uses `texture.blp`:\n\n```\n├── index.html\n└── Resources\n    ├── model.mdx\n    └── texture.blp\n```\n\nLoading the model is simple:\n```javascript\nlet modelPromise = viewer.load(\"Resources/model.mdx\");\n```\n\nYou get back a promise, which will resolve to either the MDX model, or to undefined if any error occured.\n\nWhen the MDX model loads, it also loads internal resources, like its textures, so the viewer will attempt to fetch `texture.blp`.\\\nIf the server knows this is a relative path to `Resources/` then all is fine.\\\nIt is typically a lot easier and more dynamic to control the paths on the client though.\\\nThis is done with \"path solvers\" - functions that, given a source to load from, such as a path, can modify it and return the actual source to load from.\\\nIt will probably make more sense with code - let's load the model again, with the texture fetch asking for the correct path: `Resources/texture.blp`.\n```javascript\nfunction pathSolver(path) {\n  return \"Resources/\" + path;\n}\n\nlet modelPromise = viewer.load(\"model.mdx\", pathSolver);\n```\n\nHere's the short version of what happens:\n\n1. `pathSolver` is called with `\"model.mdx\"` and returns `\"Resources/model.mdx\"`.\n2. The viewer starts the fetch, and emits the `loadstart` event.\n3. A promise is returned.\n4. ...time passes until the file finishes loading...\n5. The viewer detects the format as MDX based on the file data (the url is irrelevant to this process).\n6. The model is constructed successfuly, or not, with a `load` or `error` event sent respectively, followed by the `loadend` event.\n7. In the case of an MDX model, the previous step will also cause it to load its textures.\n8. `pathSolver` is called with `\"texture.blp\"`, which returns `\"Resources/texture.blp\"`, and we loop back to step 2, but with a texture this time.\n\nPath solvers can return promises which will be waited upon, and they can return models and textures directly for injections.\n\nGenerally speaking, you'll need a simple path solver that expects urls and prepends them by some base directory or API url.\\\nThere are however times when this is not the case, such as loading models with custom textures, and handling both in-memory and fetches in the same solver as done in the map viewer.\n\nOnce the promise is resolved, we have a model, however a model in this context is simply a source of data.\\\nThe next step is to create an instance of this model.\\\nInstances can be rendered, moved, rotated, scaled, parented to other instances or nodes, play animations, and so on.\n```javascript\nlet instance = model.addInstance();\n```\n\nAnd finally add the instance to the scene, so it's updated and rendered:\n```javascript\ninstance.setScene(scene);\n// Equivalent to:\nscene.addInstance(instance);\n```\n\n---\n\nOther resources, such as SLK tables and INI configurations, are loaded with `loadGeneric`.\n\n```javascript\nlet resourcePromise = viewer.loadGeneric(path, dataType[, callback]);\n```\n\nWhere:\n* `path` is an url string.\n* `dataType` is a string with one of these values: `text`, `arrayBuffer`, `blob`, `bytes`, or `image`.\n* `callback` is an optional function that will be called with the data once the fetch is complete, and should return the resource's data.\n\nIf a callback is given, `resource.data` will be whatever the callback returns.\\\nIf a promise is returned, the loader waits for it to resolve, and uses whatever it resolved to.\\\nIf no callback is given, the data will be the fetch data itself, according to the given data type (`bytes` refers to a `Uint8Array`).\n\n`loadGeneric` is a simple layer above the standard `fetch` function.\\\nThe purpose of loading other files through the viewer is to cache the results and avoid multiple loads, while also allowing the viewer itself to handle events correctly.\n\n------------------------\n\n#### Events and Promises\n\nAs mentioned above, there are emitted events, and they can be used with the NodeJS EventEmitter API:\n```javascript\nviewer.on(eventName, listener)\nviewer.off(eventName, listener)\nviewer.once(eventName, listener)\nviewer.emit(eventName[, ...args])\n```\n\nThe built-in names are:\n* `loadstart` - a resource started loading.\n* `load` - a resource successfully loaded.\n* `error` - something bad happened.\n* `loadend` - a resource finished loading, follows both `load` and `error` when loading a resource.\n* `idle` - all loads finished for now.\n\nFor example:\n```javascript\nviewer.on('error', (e) => console.log(e));\n```\n\nIn addition there is `viewer.whenAllLoaded([callback])`, which can be used to run code when nothing is loading.\nIf a callback is given, it will be called, otherwise a promise is returned.\nIf there are no resources currently being loaded, this will happen instantly. Otherwise, it will happen once the `idle` event is emitted.\n```javascript\nviewer.whenAllLoaded((viewer) => {\n  // Nothing is loading!\n});\n\nviewer.whenAllLoaded()\n  .then((viewer) => {\n    // Nothing is loading!\n  });\n```\n\n---\n\nAnd now some more specific information and tips.\n\n#### Team colors, event objects, and Reforged\n\nWhen loading an MDX model that uses team color/glow textures, it will tell the handler to load all of the team textures.\n\nSimilarly, if an MDX model has event objects, it will tell the handler to load the needed SLK files.\n\nThe handler uses `load` much like the client does, and thus the same implications apply - if the server is set for the relative paths, all is fine, otherwise a path solver should be used.\n\nA path solver can be passed when adding the handler:\n```javascript\nviewer.addHandler(handlers.mdx, wc3PathSolver);\n```\n\nThe handler also selects between TFT (16) and Reforged (28) team colors.\\\nThese will be used regardless of whether any specific model being rendered is a TFT or Reforged model.\\\nThe default mode is TFT, and it can be changed by passing true as the third parameter when adding the handler:\n```javascript\nviewer.addHandler(handlers.mdx, wc3PathSolver, true); // Reforged team colors and event objects.\n```\n\n#### Interacting with model instances\n\nModel instances are nodes, and can be transformed as such:\n```javascript\ninstance.setLocation([50, 0, 0]); // Move to the given point.\ninstance.move([50, 0, 0]); // Move by the given offset.\n\ninstance.setRotation([0, 0, 0, 1]); // Set the rotation to the given quaternion.\ninstance.rotate([0, 0, 0, 1]); // Rotate by the given quaternion.\n\ninstance.setScale([2, 2, 2]); // Set the scale to the given vector.\ninstance.scale([2, 2, 2]); // Scale by the given vector.\n\ninstance.setUniformScale(2); // Set the scale to the given number.\ninstance.uniformScale(2); // Scale by the given number.\n\ninstance.face([50, 0, 0], [0, 0, 1]); // Face the given point, with the given \"up\" vector.\n\ninstance.setParent(nodeOrInstance); // Set a parent, making all other transformations relative to it.\ninstance.setParent(); // Remove the parent.\n```\n\nBoth MDX and M3 instances can run animations, have team colors, etc.:\n```javascript\ninstance.setSequence(-1); // No animation.\ninstance.setSequence(0); // First animation.\n\ninstance.setSequenceLoopMode(0); // Never loop animations.\ninstance.setSequenceLoopMode(1); // Loop animations based on the model.\ninstance.setSequenceLoopMode(2); // Always loop animations.\n\ninstance.setTeamColor(0); // First team color.\n\ninstance.setVertexColor([1, 0, 0]); // Red vertex color.\n\nlet node = instance.getAttachment(0); // Get the first attachment point.\n```\n\nMDX instances have `setTexture`, `setParticle2Texture`, and `setEventTexture`, to override textures, particle emitter textures, and event object textures:\n```javascript\ninstance.setTexture(0, myTexture); // Override texture 0.\ninstance.setParticle2Texture(0, myTexture); // Override the texture of particle emitter 0.\ninstance.setEventTexture(0, myTexture); // Override the texture of event emitter 0.\n\ninstance.setTexture(0); // Remove the override, same with the other functions.\n```\n\nM3 instances have `setTexture`:\n```javascript\ninstance.setTexture(1, 0, myTexture); // Override texture 0 of standard material 1.\n```\n\n#### Solver Params: Reforged and the map viewer\n\nIt is in fact possible to send more data to path solvers with `load`.\nThe full signature is as follows:\n```javascript\nlet resourcePromise = viewer.load(src[, pathSolver[, solverParams]]);\n```\nWhere `solverParams` can be anything.\n\nWhen `solverParams` exists, it will be sent to the path solver as the second argument:\n```javascript\nfunction pathSolver(src, solverParams) {\n  // ...\n}\n```\n\nThe MDX handler and the map viewer use `solverParams` to select between SD/HD Reforged resources, and to select specific tileset resources.\n\nThe MDX handler defines the parameters as such: `{reforged?: boolean, hd?: boolean}`.\\\nThe map viewer defines them as such: `{reforged?: boolean, hd?: boolean, tileset: string}`.\n\nIf `reforged` is falsy or doesn't exist, they want a TFT resource.\\\nIf `reforged` is true, they want a Reforged SD resource and...\\\nIf `hd` and `reforged` are true, they want a Reforged HD resource.\n\nFor example, when a new MDX model is being loaded, and it is detected as a Reforged model (version > 800), any internal resources like its textures will be loaded with `solverParams = {reforged: true}`, and if the model is detected to be HD: `solverParams = {reforged: true, hd: true}`.\n\nYou can also manually supply your own parameters.\\\nFor example, let's suppose we want to load the Warcraft 3 Footman model, but with a twist - we want all three versions of it - RoC/TFT, Reforged SD, and Reforged HD.\\\nThe loading code can be something along these lines:\n```js\nlet TFT = viewer.load('Units/Human/Footman/Footman.mdx', mySolver);\nlet SD = viewer.load('Units/Human/Footman/Footman.mdx', mySolver, {reforged: true});\nlet HD = viewer.load('Units/Human/Footman/Footman.mdx', mySolver, {reforged: true, hd: true});\n```\n\nSo what does the path solver do with `solverParams`?\\\nAs always, that depends on the client.\\\nFor example, the solver may append the parameters as url parameters, and the server selects the game based on them.\\\nThe solver can also completely ignore these parameters and return whatever resources it wants.\n\n#### Starcraft 2 models are tiny\n\nSC2 models are tiny compared to WC3 models.\\\nIf a client needs models of both games to co-exist, it's suggested to scale SC2 models by 100.\\\nThis can be done with something along the lines of:\n```javascript\nlet instance = model.addInstance();\n\nif (model instanceof handlers.m3.resource) {\n  instance.uniformScale(100);\n}\n```\n\n#### Loading resources from memory\n\nResources don't have to be fetched - if you have the data, you can load it directly.\\\nNothing special is needed, simply use it as you would an url:\n```javascript\nlet resourcePromise = viewer.load(buffer);\n```\n\nSay a web page wants to load MDX models from local files that are dragged into it.\\\nAfter some event handling, you end up with data such as a `string` or an `ArrayBuffer`.\n\nPractically speaking, most MDX models will attempt to load Warcraft 3 textures.\\\nThis means that if we load the model directly, it will fail to load the textures, unless as always, the server is set for the relative paths.\n\nA path solver can again simplify the load:\n```javascript\nfunction pathSolver(src) {\n  if (src === buffer) {\n    return src;\n  }\n\n  return wc3PathSolver(src);\n}\n\nviewer.load(buffer, pathSolver);\n```\n\nWhen the thing being loaded is the buffer, it will be used, otherwise, e.g. for the textures, the Warcraft 3 path solver will be used instead.\n\n#### Primitive shapes\n\nIt is possible to construct primitive shapes with `createPrimitive`, which is available under `utils.mdlx.createPrimitive`.\n\nThe function expects an object describing a primitive geometry, which can be obtained via the different functions in `utils.mdlx.primitives`.\n\nAn optional material can be given, which can control the render mode between polygons and lines, the color, texture, and such.\n\nFor example:\n```javascript\nlet modelPromise = createPrimitive(viewer, primitives.createUnitCube(), { color: [1, 0, 0] });\n```\n\nNote that this loads a standard MDX model which can be used like any other MDX model.\n\n#### Sounds\n\nMDX models have sound emitters, and the viewer supports them.\n\nIf sound is desired, `viewer.audioEnabled` should be set to true BEFORE loading models.\\\nThis signals to the MDX handler that sound is desired, and it will load the neccessary sound files when loading models.\\\nIf `audioEnabled` isn't true, the sound files aren't downloaded in the first place to reduce file fetching.\n\nTo get the sounds to actually run, you must call `scene.enableAudio()`, which returns a promise that resolves to whether audio was actually enabled.\\\nThere are two reasons for it to fail - either because the browser simply does not support audio, or because the browser did not want to enable audio.\\\nThe latter will happen if you attempt to enable audio before the user made any interaction with the page (like clicking something). This is a browser policy and there is no control over it.\n\nIf audio was enabled, you will hear familiar sounds when running animations, like attack sounds, death sounds, and so on.\\\nNot enough work was put into them to have the same feel as Warcraft 3, but it's sometimes a fun surprise to suddenly hear a model making sounds in the browser.\n\n#### Scene composition\n\nYou can have any number of scenes you want.\n\nEach scene offers the following to control how it's composed on the canvas:\n* `viewport` - the position and size of the scene in pixels (defaults to the entire canvas).\n* `alpha` - determines whether the scene has a background, or can be seen through (defaults to false - has a background).\n* `color` - the background color, which is used when `alpha` is false (defaults to black).\n\n```javascript\nscene.viewport[0] = 100; // X offset from the left side of the canvas.\nscene.viewport[1] = 100; // Y offset from the bottom side of the canvas.\nscene.viewport[2] = 200; // Width.\nscene.viewport[3] = 200; // Height.\n\nscene.alpha = false; // Opaque, i.e. has a background (and also the default).\n\nscene.color[0] = 1; // Red background.\nscene.color[1] = 0;\nscene.color[2] = 0;\n```\n\nThe order in which the scenes are drawn is based on the order of creation, but you can manually move scenes around in `viewer.scenes`.\n\nFor example, let's say we want to mimic how Warcraft 3 looks. This could be done with 3 scenes:\n1) The game world.\n2) The UI with `alpha = true` so that where the UI isn't drawn, the game world will be seen through.\n3) The selected portrait, moved and sized to be on the correct portion of the UI.\n\n#### Everything is blurry\n\nWebGL uses a canvas as its back buffer, meaning it has the same amount of pixels as the canvas does. Surprising, right?\\\nWhat may actually surprise you, however, is that the canvas back buffer isn't neccassarily the size it is drawn at, due to CSS styling.\\\nFor example, you can have a canvas that is scaled via CSS to the entire page, but if you never set its actual size, it will probably be a 100x100 pixel canvas (or whatever default size the browser uses), stretched to the page size.\\\nIf you want to set the size of the back buffer, i.e. the real resolution of the canvas, use the `width` and `height` properties of the canvas, rather than CSS properties such as `clientWidth` and `clientHeight`.\n\n```javascript\n// Could be a static size.\ncanvas.width = 512;\ncanvas.height = 512;\n\n// Or perhaps scaled with CSS, if you put this in a resize event listener.\ncanvas.width = canvas.clientWidth;\ncanvas.height = canvas.clientHeight;\n\n// This however only changes the CSS size, not the canvas resolution!\ncanvas.clientWidth = 512;\ncanvas.clientHeight = 512;\n\n// Nor does this.\ncanvas.style.width = '512px';\ncanvas.style.height = '512px';\n```\n\n#### Variable frames per second\n\n`ModelViewer.update()` and `ModelViewer.updateAndRender()` have an optional `dt` argument.\n\n`dt` controls how much time in miliseconds to advance the animations.\n\nBy default, `dt` is set for 60FPS, or `1000 / 60`.\n\nIf a client runs on a >60Hz monitor, and uses `requestAnimationFrame` for its main loop as it should, animations will run faster than they should.\n\nIn other cases, a client might have too many things rendering and it slows down, causing animations to go slow motion.\n\nTo support a variable FPS while keeping the same animation speed, `dt` can be controlled dynamically, for example:\n\n```javascript\n let lastTime = performance.now();\n\n(function step() {\n  requestAnimationFrame(step);\n\n  let now = performance.now();\n\n  // The faster the FPS, the lower dt will be.\n  // Twice the FPS? half the dt.\n  // There are more frames per second, so every frame advances the animation less.\n  // And the other way is also true.\n  // Half the FPS? twice the dt.\n  // There are less frames per second, so every frame advances the animation more.\n  let dt = now - lastTime;\n\n  lastTime = now;\n\n  viewer.updateAndRender(dt);\n}());\n```\n"
  },
  {
    "path": "Viewer.code-workspace",
    "content": "{\n\t\"folders\": [\n\t\t{\n\t\t\t\"path\": \".\"\n\t\t}\n\t],\n\t\"settings\": {\n\t\t\"editor.tabSize\": 2,\n\t\t\"files.eol\": \"\\n\",\n\t\t\"typescript.preferences.quoteStyle\": \"single\",\n\t\t\"typescript.validate.enable\": true,\n\t\t\"editor.formatOnSave\": true,\n\t\t\"eslint.lintTask.enable\": true,\n\t\t\"eslint.validate\": [\n\t\t\t\"typescript\"\n\t\t],\n\t\t\"workbench.editor.enablePreview\": false,\n\t\t\"typescript.tsdk\": \"node_modules\\\\typescript\\\\lib\"\n\t}\n}"
  },
  {
    "path": "Viewer.sublime-project",
    "content": "{\n    \"folders\":\n    [\n        {\n            \"path\": \".\"\n        }\n    ],\n    \"tab_size\": 2,\n    \"translate_tabs_to_spaces\": true,\n    \"use_tab_stops\": true,\n}\n"
  },
  {
    "path": "clean.js",
    "content": "// See https://stackoverflow.com/a/52526549/2503048\n\nvar fs = require('fs');\n\nfunction deleteFolderRecursive(path) {\n  if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {\n    fs.readdirSync(path).forEach(function (file, index) {\n      var curPath = path + \"/\" + file;\n\n      if (fs.lstatSync(curPath).isDirectory()) { // recurse\n        deleteFolderRecursive(curPath);\n      } else { // delete file\n        fs.unlinkSync(curPath);\n      }\n    });\n\n    console.log(`Deleting directory \"${path}\"...`);\n    fs.rmdirSync(path);\n  }\n}\n\nconsole.log(\"Cleaning build files...\");\n\ndeleteFolderRecursive(\"./dist/cjs\");\ndeleteFolderRecursive(\"./dist/umd\");\n\nconsole.log(\"Successfully cleaned the build files!\");\nconsole.log(\"Running TSC and Webpack, it might take a while...\");\n"
  },
  {
    "path": "clients/README.md",
    "content": "Over the years, many different clients were made with this library. Most of them have gone into the pages of forgotten history, but some remain.\n\nI present them as-is, in their messy state, so that they may perhaps help anyone who wants to use the library, or for anyone wanting to improve them.\n\nNote that if the web page you open doesn't point to `127.0.0.1` (e.g. you are using a remote server, or using `localhost` instead), all downloads will be redirected to the Hiveworkshop. Once upon a time Ralle, the Hive's owner, said he's ok with this. If at any point this changes, I will remove this information from the repository.\nDue to this, for the time being, all of the clients should run out of the box.\n"
  },
  {
    "path": "clients/downgrader/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title></title>\n    <meta charset=\"utf-8\" />\n</head>\n\n<body>\n    <div>\n        Drag & Drop a Warcraft 3 \"new\" map (~1.29 and onwards) to downgrade it back to an \"old\" map (~1.28 and\n        backwards).\n    </div>\n    <div> This currently handles the map information, doodads/destructibles, and units/items.</div>\n    <div>\n        Triggers of Reforged maps (1.32) will be deleted, because my code doesn't (yet?) support Reforged triggers.\n    </div>\n\n    <script src=\"../thirdparty/filesaver.js\"></script>\n    <script src=\"/clients/downgrader.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/downgrader/index.js",
    "content": "import War3Map from '../../src/parsers/w3x/map';\nimport War3MapW3i from '../../src/parsers/w3x/w3i/file';\nimport War3MapDoo from '../../src/parsers/w3x/doo/file';\nimport War3MapUnitsDoo from '../../src/parsers/w3x/unitsdoo/file';\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  const file = e.dataTransfer.files[0];\n  const reader = new FileReader();\n\n  reader.addEventListener('loadend', (e) => {\n    const buffer = e.target.result;\n    const map = new War3Map();\n\n    map.load(buffer);\n\n    const w3i = new War3MapW3i();\n    w3i.load(map.get('war3map.w3i').arrayBuffer());\n\n    if (w3i.version > 25) {\n      console.log(`war3map.w3i version ${w3i.version} => 25`);\n\n      w3i.version = 25;\n      map.set('war3map.w3i', w3i.save());\n    }\n\n    const buildVersion = w3i.getBuildVersion();\n\n    if (buildVersion > 131) {\n      console.log(`war3map.doo buildVersion ${buildVersion} => 0`);\n\n      const doo = new War3MapDoo();\n      doo.load(map.get('war3map.doo').arrayBuffer(), buildVersion);\n      console.log(doo)\n      map.set('war3map.doo', doo.save(0));\n\n      console.log(`war3mapUnits.doo buildVersion ${buildVersion} => 0`);\n\n      const unitsDoo = new War3MapUnitsDoo();\n      unitsDoo.load(map.get('war3mapUnits.doo').arrayBuffer(), buildVersion);\n      console.log(unitsDoo)\n      map.set('war3mapUnits.doo', unitsDoo.save(0));\n\n      console.log('Deleting the triggers, because this is a Reforged map, and my code does not support Reforged triggers (yet?)');\n\n      map.delete('war3map.wtg');\n    }\n\n    saveAs(new Blob([map.save().buffer], { type: 'application/octet-stream' }), 'downgraded_' + file.name);\n  });\n\n  reader.readAsArrayBuffer(file);\n});\n"
  },
  {
    "path": "clients/example/README.md",
    "content": "A simple example client.\n\nThanks to Frank from the HiveWorkshop for the MDX model and BLP texture!\n"
  },
  {
    "path": "clients/example/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>MDX Example</title>\n    <meta charset=\"utf-8\" />\n</head>\n\n<body>\n    <canvas id=\"canvas\"></canvas>\n\n    <script src=\"/clients/example.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/example/index.js",
    "content": "import * as ModelViewer from '../../src/';\nimport { setupCamera } from '../shared/camera';\nconst handlers = ModelViewer.viewer.handlers;\n\nlet canvas = document.getElementById('canvas');\n\ncanvas.width = 800;\ncanvas.height = 600;\n\n// Create the viewer!\nlet viewer = new ModelViewer.viewer.ModelViewer(canvas);\n\n// Create a new scene. Each scene has its own camera, and a list of things to render.\nlet scene = viewer.addScene();\n\n// Check camera.js!\nsetupCamera(scene);\n\n// Events.\nviewer.on('loadstart', (e) => console.log(e));\nviewer.on('load', (e) => console.log('load', e));\nviewer.on('loadend', (e) => console.log('loadend', e));\nviewer.on('error', (e) => console.log('error', e));\n\n// Add the MDX handler.\n// Note that this also loads all of the team colors/glows.\n// You can optionally supply a path solver (look below) to point the viewer to the right location of the textures.\n// Additionally, a boolean can be given that selects between RoC/TFT and Reforged team colors.\n// For example:\n//   viewer.addHandler(handlers.mdx, pathSolver); // Roc/TFT = 14 teams.\n//   viewer.addHandler(handlers.mdx, pathSolver, true); // Reforged = 28 teams.\n// In the case of this example, team colors aren't used, so it's fine for their loads to simply fail.\nviewer.addHandler(handlers.mdx);\n\n// Add the BLP handler.\nviewer.addHandler(handlers.blp);\n\n// A path solver is used for every load call.\n// Given a possibly relative source, it should return the actual source to load from.\n// This can be in the form of an URL string, or direct sources from memory (e.g. a previously loaded ArrayBuffer).\nfunction pathSolver(src) {\n  return 'resources/' + src;\n}\n\n// Load our MDX model!\nlet modelPromise = viewer.load('SmileyGW_004.mdx', pathSolver);\n\nmodelPromise.then((model) => {\n  // The promise can return undefined if something went wrong!\n  if (model) {\n    // Create an instance of this model.\n    let instance = model.addInstance();\n\n    // Set the instance's scene.\n    // Equivalent to scene.addInstance(instance)\n    instance.setScene(scene);\n\n    // Want to run the second animation.\n    // 0 is the first animation, and -1 is no animation.\n    instance.setSequence(1);\n\n    // Tell the instance to loop animations forever.\n    // This overrides the setting in the model itself.\n    instance.setSequenceLoopMode(2);\n\n    // Let's create another instance and do other stuff with it.\n    let instance2 = model.addInstance();\n    instance2.setScene(scene);\n    instance2.setSequence(0);\n    instance2.setSequenceLoopMode(2);\n    instance2.move([100, 100, 0]);\n    instance2.uniformScale(0.5);\n\n    // And a third one.\n    let instance3 = model.addInstance();\n    instance3.setScene(scene);\n    instance3.setSequence(2);\n    instance3.setSequenceLoopMode(2);\n    instance3.move([-100, -100, 0]);\n  }\n});\n\n// The viewer has the update(), startFrame(), render(), and updateAndRender() functions.\n// Generally speaking, you will want a simple never ending loop like the one that follows, but who knows. The control is in your hands.\n(function step() {\n  requestAnimationFrame(step);\n\n  viewer.updateAndRender();\n})();\n"
  },
  {
    "path": "clients/map/README.md",
    "content": "A Warcraft 3 map viewer client. Drag and drop a map file (W3X, W3M) into the page.\n"
  },
  {
    "path": "clients/map/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>Map | HIVE</title>\n    <meta charset=\"utf-8\" />\n\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            margin: 0px;\n            color: white;\n        }\n\n        #canvas {\n            position: absolute;\n            left: 0px;\n            top: 0px;\n            width: 100%;\n            height: 100%;\n        }\n\n        #stats {\n            position: absolute;\n            left: 10px;\n            top: 10px;\n            user-select: none;\n            pointer-events: none;\n        }\n\n        #status {\n            position: absolute;\n            left: 10%;\n            top: 10%;\n            width: 80%;\n            height: 80%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            user-select: none;\n            pointer-events: none;\n        }\n    </style>\n</head>\n\n<body>\n    <canvas id=\"canvas\"></canvas>\n\n    <div id=\"status\">Loading the page</div>\n\n    <div id=\"stats\">\n        <div id=\"cells\"></div>\n        <div id=\"instances\"></div>\n        <div id=\"particles\"></div>\n    </div>\n\n    <script src=\"../thirdparty/fpsmeter.min.js\"></script>\n    <script src=\"/clients/map.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/map/index.js",
    "content": "import { basename, extname } from \"../../src/common/path\";\nimport War3MapViewer from '../../src/viewer/handlers/w3x/viewer';\nimport { setupCamera } from \"../shared/camera\";\nimport localOrHive from \"../shared/localorhive\";\n\nlet statusElement = document.getElementById('status');\nstatusElement.textContent = 'Initializing the viewer';\n\nlet canvas = document.getElementById('canvas');\n\n// true because the Reforged Hive API is used in localOrHive.\nlet viewer = new War3MapViewer(canvas, localOrHive, true);\n\nlet thingsLoading = [];\n\nfunction updateStatus() {\n  if (thingsLoading.length) {\n    statusElement.textContent = `Loading ${thingsLoading.join(', ')}`;\n  } else {\n    statusElement.textContent = '';\n  }\n}\n\nfor (let key of viewer.promiseMap.keys()) {\n  thingsLoading.push(basename(key));\n}\n\nupdateStatus();\n\nviewer.on('loadstart', ({ fetchUrl }) => {\n  thingsLoading.push(basename(fetchUrl));\n  updateStatus();\n});\n\nviewer.on('loadend', ({ fetchUrl }) => {\n  let file = basename(fetchUrl);\n  let index = thingsLoading.indexOf(file);\n\n  if (index !== -1) {\n    thingsLoading.splice(index, 1);\n    updateStatus();\n  }\n});\n\nlet meter = new FPSMeter({\n  position: 'absolute',\n  right: '10px',\n  top: '10px',\n  left: 'calc(100% - 130px)',\n  theme: 'transparent',\n  heat: 1,\n  graph: 1\n});\n\nlet cellsElement = document.getElementById('cells');\nlet instancesElement = document.getElementById('instances');\nlet particlesElement = document.getElementById('particles');\n\n(function step() {\n  requestAnimationFrame(step);\n\n  viewer.updateAndRender();\n  meter.tick();\n\n  cellsElement.textContent = `Cells: ${viewer.visibleCells}`;\n  instancesElement.textContent = `Instances: ${viewer.visibleInstances}`;\n  particlesElement.textContent = `Particles: ${viewer.updatedParticles}`;\n}());\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  if (viewer.loadedBaseFiles) {\n    let file = e.dataTransfer.files[0];\n    let name = file.name;\n    let ext = extname(name);\n\n    if (ext === '.w3m' || ext === '.w3x') {\n      let reader = new FileReader();\n\n      reader.addEventListener('loadend', e => {\n        viewer.loadMap(e.target.result);\n\n        setupCamera(viewer.map.worldScene, { distance: 3000 });\n      });\n\n      reader.readAsArrayBuffer(file);\n    }\n  }\n});\n"
  },
  {
    "path": "clients/mdlx/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>MDX &lt;-&gt; MDL</title>\n    <meta charset=\"utf-8\" />\n\n    <style>\n        #status {\n            width: 500px;\n            height: 100px;\n            position: absolute;\n            top: 0;\n            bottom: 0;\n            left: 0;\n            right: 0;\n            margin: auto;\n            user-select: none;\n            pointer-events: none;\n        }\n    </style>\n</head>\n\n<body>\n    <div id=\"status\">Drop any combination of models (.mdl, .mdx) to convert them</div>\n\n    <script src=\"../thirdparty/filesaver.js\"></script>\n    <script src=\"/clients/mdlx.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/mdlx/index.js",
    "content": "import { extname } from \"../../src/common/path\";\nimport { version } from \"../../src/version\";\nimport Model from '../../src/parsers/mdlx/model';\n\nconsole.log('Viewer version', version);\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  for (let file of e.dataTransfer.files) {\n    let name = file.name;\n    let ext = extname(name);\n\n    if (ext === '.mdx' || ext === '.mdl') {\n      let reader = new FileReader();\n\n      reader.addEventListener('loadend', (e) => {\n        let model = new Model();\n        model.load(e.target.result);\n\n        let buffer;\n        let type;\n\n        if (ext === '.mdl') {\n          buffer = model.saveMdx().buffer;\n          type = 'application/octet-stream';\n          ext = 'mdx';\n        } else {\n          buffer = model.saveMdl();\n          type = 'text/plain';\n          ext = 'mdl'\n        }\n\n        saveAs(new Blob([buffer], { type }), name.slice(0, -3) + ext);\n      });\n\n      if (ext === '.mdl') {\n        reader.readAsText(file);\n      } else {\n        reader.readAsArrayBuffer(file);\n      }\n    }\n  }\n});\n"
  },
  {
    "path": "clients/mdlxoptimizer/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>MDLX Optimizer</title>\n    <meta charset=\"utf-8\" />\n</head>\n\n<body>\n    <script src=\"../thirdparty/filesaver.js\"></script>\n    <script src=\"/clients/mdlxoptimizer.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/mdlxoptimizer/index.ts",
    "content": "import { extname } from \"../../src/common/path\";\n// @ts-ignore\nimport { getAllFileEntries, readEntry } from \"../shared/utils\";\nimport MdlxModel from '../../src/parsers/mdlx/model';\nimport AnimatedObject from '../../src/parsers/mdlx/animatedobject';\nimport { Animation } from '../../src/parsers/mdlx/animations';\nimport { getValuesDiff } from '../../src/utils/mdlx/sanitytest/tracks';\n\ntype Value = Uint32Array | Float32Array;\n\ntype Entry = [number, Value, Value, Value];\nconst FRAME = 0;\nconst VALUE = 1;\nconst INTAN = 2;\nconst OUTTAN = 3;\n\nfunction optimizeAnimation(model: MdlxModel, animation: Animation) {\n  const sequences = model.sequences;\n  const { interpolationType, globalSequenceId, frames, values, inTans, outTans } = animation;\n\n  if (globalSequenceId !== -1) {\n    console.error('NEED TO ADD GLOBAL ANIMATION SUPPORT');\n    return 0;\n  }\n  \n  // Map the keyframes to entries, and remove duplicated frames while we're at it.\n  const entryMap = new Map<number, Entry>();\n\n  for (let i = 0, l = frames.length; i < l; i++) {\n    entryMap.set(frames[i], [frames[i], values[i], inTans[i], outTans[i]])\n  }\n\n  // Now back to an array.\n  const entries: Entry[] = [...entryMap.values()];\n\n  // And sort it.\n  entries.sort((a, b) => a[FRAME] - b[FRAME]);\n\n  // Get all of the edge entries.\n  // In other words, the frames of the current first and last entries for every sequence.\n  const edges = new Set<number>();\n\n  for (const sequence of sequences) {\n    const [start, end] = sequence.interval;\n    let startFrame = Infinity;\n    let endFrame = Infinity;\n\n    for (const entry of entries) {\n      const frame = entry[FRAME];\n\n      if (startFrame === Infinity && frame - start >= 0) {\n        startFrame = frame;\n      }\n\n      if (end - frame >= 0) {\n        endFrame = frame;\n      }\n    }\n\n    edges.add(startFrame);\n    edges.add(endFrame);\n  }\n\n  const keptEntries: Entry[] = [];\n\n  // Now we can iterate over the entries.\n  for (let i = 0, l = entries.length; i < l; i++) {\n    const entry = entries[i];\n    const frame = entry[FRAME];\n\n    // Edge entries are left as-is.\n    if (edges.has(frame)) {\n      keptEntries.push(entry);\n    } else {\n      // Otherwise, let's see if this entry is in any sequence to begin with.\n      for (const sequence of sequences) {\n        const [start, end] = sequence.interval;\n\n        if (frame >= start && frame <= end) {\n          keptEntries.push(entry);\n          break;\n        }\n      }\n    }\n  }\n\n  const finalEntries: Entry[] = [];\n\n  // Now that all of the entries are valid in sequences, we can check for values.\n  if (keptEntries.length >= 2) {\n    for (let i = 0, l = keptEntries.length; i < l; i++) {\n      const entry = keptEntries[i];\n      const frame = entry[FRAME];\n\n      // Once again, don't touch edges.\n      if (edges.has(frame)) {\n        finalEntries.push(entry);\n\n        continue;\n      }\n\n      // Otherwise, if this isn't the first or last entries, check for equal values.\n      if (i > 0 && i < keptEntries.length - 1) {\n        const prevEntry = keptEntries[i - 1];\n        const nextEntry = keptEntries[i + 1];\n        const difference = getValuesDiff(prevEntry[VALUE], entry[VALUE], nextEntry[VALUE]);\n\n        if (difference > 0.0001) {\n          finalEntries.push(entry);\n        }\n      }\n    }\n  }\n\n  const newFrames = [];\n  const newValues = [];\n  const newInTans = [];\n  const newOutTans = [];\n\n  for (const entry of finalEntries) {\n    newFrames.push(entry[FRAME]);\n    newValues.push(entry[VALUE]);\n\n    if (interpolationType > 1) {\n      newInTans.push(entry[INTAN]);\n      newOutTans.push(entry[OUTTAN]);\n    }\n  }\n\n  animation.frames = newFrames;\n  animation.values = newValues;\n  animation.inTans = newInTans;\n  animation.outTans = newOutTans;\n\n  return frames.length - newFrames.length;\n}\n\nfunction optimizeAnimations(model: MdlxModel, animations: Animation[]) {\n  let tracks = 0;\n  \n  for (const animation of animations) {\n    tracks += optimizeAnimation(model, animation);\n  }\n\n  return tracks;\n}\n\nfunction optimizeMaterials(model: MdlxModel) {\n  let tracks = 0;\n\n  for (const material of model.materials) {\n    for (const layer of material.layers) {\n      tracks += optimizeAnimations(model, layer.animations)\n    }\n  }\n\n  return tracks;\n}\n\nfunction optimizeObjects(model: MdlxModel, objects: AnimatedObject[]) {\n  let tracks = 0;\n\n  for (const object of objects) {\n    tracks += optimizeAnimations(model, object.animations);\n  }\n\n  return tracks;\n}\n\nfunction optimizeModel(name: string, buffer: ArrayBuffer) {\n  try {\n    const model = new MdlxModel();\n\n    model.load(buffer);\n\n    let tracks = 0;\n\n    tracks += optimizeMaterials(model);\n    tracks += optimizeObjects(model, model.textureAnimations);\n    tracks += optimizeObjects(model, model.geosetAnimations);\n    tracks += optimizeObjects(model, model.bones);\n    tracks += optimizeObjects(model, model.lights);\n    tracks += optimizeObjects(model, model.helpers);\n    tracks += optimizeObjects(model, model.attachments);\n    tracks += optimizeObjects(model, model.particleEmitters);\n    tracks += optimizeObjects(model, model.particleEmitters2);\n    tracks += optimizeObjects(model, model.particleEmittersPopcorn);\n    tracks += optimizeObjects(model, model.ribbonEmitters);\n    tracks += optimizeObjects(model, model.cameras);\n    tracks += optimizeObjects(model, model.collisionShapes);\n\n    console.log(`Removed ${tracks} tracks`);\n\n    return model.saveMdx();\n  } catch (e) {\n    console.error(`Error for \"${name}\": ${e}`);\n\n    return undefined;\n  }\n}\n\nasync function optimizeDataTransfer(dataTransfer: DataTransfer) {\n  const entries = await getAllFileEntries(dataTransfer);\n  const names = [];\n  const promises = [];\n\n  for (let entry of entries) {\n    const name = entry.name;\n    const ext = extname(name);\n\n    if (ext === '.mdx' || ext === '.mdl') {\n      names.push(name);\n      promises.push(readEntry(entry, ext === '.mdl'));\n    }\n  }\n\n  const buffers = await Promise.all(promises);\n  const optimizedBuffers = [];\n\n  for (let i = 0, l = buffers.length; i < l; i++) {\n    optimizedBuffers.push(optimizeModel(names[i], buffers[i]));\n  }\n\n  for (let i = 0, l = buffers.length; i < l; i++) {\n    const buffer = optimizedBuffers[i];\n\n    if (buffer) {\n      // @ts-ignore\n      saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'opt_' + names[i]);\n    }\n  }\n}\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  if (e.dataTransfer) {\n    optimizeDataTransfer(e.dataTransfer);\n  }\n});\n"
  },
  {
    "path": "clients/melee/README.md",
    "content": "A small tool to fake a map as a Melee map. This changes the map's icon when it is listed in the game. I don't know of any other effects.\n"
  },
  {
    "path": "clients/melee/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n  <title>Melee</title>\n  <meta charset=\"utf-8\" />\n  <style>\n    .center {\n      text-align: center;\n      user-select: none;\n    }\n  </style>\n</head>\n\n<body>\n  <p class=\"center\">Drop a map anywhere</p>\n\n  <script src=\"../../dist/viewer.min.js\"></script>\n  <script src=\"../thirdparty/filesaver.js\"></script>\n  <script src=\"index.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/melee/index.js",
    "content": "let w3x = ModelViewer.default.parsers.w3x;\n\nfunction onLocalLoaded(e, name) {\n    let buffer = e.target.result;\n\n    console.log('Reading the map');\n\n    let map = new w3x.Map();\n    map.load(buffer);\n\n    console.log('Setting the map melee flag');\n\n    map.flags |= 0x4;\n\n    console.log('Reading war3map.w3i');\n\n    let w3i = new w3x.w3i.File();\n    w3i.load(map.get('war3map.w3i').arrayBuffer());\n\n    console.log('Setting the w3i melee flag');\n\n    w3i.flags |= 0x4;\n\n    console.log('Saving war3map.w3i');\n\n    map.set('war3map.w3i', w3i.save());\n\n    let newName = `${name.substr(0, name.length - 4)}_melee${name.substr(-4)}`;\n\n    console.log(`Saving the map as \"${newName}\"`);\n\n    saveAs(new Blob([map.save().buffer], { type: 'application/octet-stream' }), newName);\n\n}\n\nfunction onFileDrop(e) {\n    let file = e.dataTransfer.files[0];\n    let name = file.name.toLowerCase();\n\n    if (file && (name.endsWith('.w3m') || name.endsWith('.w3x'))) {\n        let reader = new FileReader();\n\n        reader.addEventListener('loadend', (e) => onLocalLoaded(e, file.name));\n\n        reader.readAsArrayBuffer(file);\n    }\n}\n\ndocument.addEventListener('dragover', (e) => {\n    e.preventDefault();\n});\n\ndocument.addEventListener('dragend', (e) => {\n    e.preventDefault();\n    onFileDrop(e);\n});\n\ndocument.addEventListener('drop', (e) => {\n    e.preventDefault();\n    onFileDrop(e);\n});\n"
  },
  {
    "path": "clients/rebuild/README.md",
    "content": "This is a small proof of concept of rebuilding a \"protected\" map.\nThis is done by running the map's Jass script with a virtual machine, and keeping track of created objects (e.g. units and doodads).\nThe objects are then re-created in their \"un-protected\" files, e.g. `war3mapUnits.doo`.\nNote that this is, indeed, merely a proof of concept, not a complete implementation.\n"
  },
  {
    "path": "clients/rebuild/components/rebuilder.js",
    "content": "import { extname } from \"../../../src/common/path\";\nimport War3Map from \"../../../src/parsers/w3x/map\";\nimport UnitsDooFile from \"../../../src/parsers/w3x/unitsdoo/file\";\nimport UnitsDooUnit from \"../../../src/parsers/w3x/unitsdoo/unit\";\nimport Context from '../../../src/utils/jass2/context';\nimport JassUnit from '../../../src/utils/jass2/types/unit';\nimport Component from \"../../shared/component\";\nimport { createElement } from \"../../shared/domutils\";\nimport localOrHive from \"../../shared/localorhive\";\nimport { aFrame } from \"../../shared/utils\";\n\nexport default class Rebuilder extends Component {\n  constructor(parentElement) {\n    super();\n\n    this.commonjText = '';\n    this.blizzardjText = '';\n    this.ready = false;\n\n    this.load();\n\n    parentElement.appendChild(this.container);\n  }\n\n  async load() {\n    this.text('Fetching files: \"Scripts\\\\common.j\", \"Scripts\\\\Blizzard.j\"');\n    this.text('Please wait...');\n\n    let [commonjResponse, blizzardjResponse] = await Promise.all([\n      fetch('https://www.hiveworkshop.com/data/static_assets/mpq/tft/scripts/common.j'),\n      fetch('https://www.hiveworkshop.com/data/static_assets/mpq/tft/scripts/blizzard.j'),\n    ]);\n\n    let [commonjText, blizzardjText] = await Promise.all([\n      commonjResponse.text(),\n      blizzardjResponse.text(),\n    ]);\n\n    this.commonjText = commonjText;\n    this.blizzardjText = blizzardjText;\n\n    this.text('Ready, drag and drop a map (*.w3m, *.w3x) anywhere on the page.');\n  }\n\n  clear() {\n    this.container.innerHTML = '';\n  }\n\n  text(text) {\n    createElement({ textContent: text, container: this.container });\n  }\n\n  rebuildFile(file) {\n    if (file) {\n      let name = file.name;\n      let ext = extname(name);\n      let isMap = ext === '.w3m' || ext === '.w3x';\n\n      this.clear();\n\n      if (isMap) {\n        this.text(`Reading ${name}`);\n\n        let reader = new FileReader();\n\n        reader.addEventListener('loadend', async (e) => {\n          let buffer = e.target.result;\n\n          this.text(`Parsing ${name}`);\n\n          let map = new War3Map();\n\n          try {\n            map.load(buffer);\n          } catch (e) {\n            this.text(`Failed to parse: ${e}`);\n\n            return;\n          }\n\n          let context = new Context();\n\n          this.text('Converting and running common.j');\n          await aFrame();\n          context.run(this.commonjText, true);\n\n          this.text('Converting and running Blizzard.j');\n          await aFrame();\n          context.run(this.blizzardjText, true);\n\n          this.text('Converting and running war3map.j');\n          await aFrame();\n          context.open(map);\n\n          this.text('Running config()');\n          await aFrame();\n          context.call('config');\n\n          this.text('Running main()');\n          await aFrame();\n          context.call('main');\n\n          this.text('Collecting handles');\n          await aFrame();\n\n          let unitsFile = new UnitsDooFile();\n          let units = unitsFile.units;\n\n          for (let handle of context.handles) {\n            if (handle instanceof JassUnit) {\n              let unit = new UnitsDooUnit();\n\n              unit.id = handle.unitId;\n\n              unit.location[0] = handle.x;\n              unit.location[1] = handle.y;\n              // For z need the height of the terrain!\n\n              unit.angle = handle.face / 180 * Math.PI;\n\n              unit.player = handle.player.index;\n\n              unit.targetAcquisition = handle.acquireRange;\n\n              units.push(unit);\n            }\n          }\n\n          this.text(`Saving war3mapUnits.doo with ${units.length} objects`);\n          await aFrame();\n          map.set('war3mapUnits.doo', unitsFile.save(false));\n\n          this.text('Finished');\n\n          saveAs(new Blob([map.get('war3mapUnits.doo').arrayBuffer()], { type: 'application/octet-stream' }), 'war3mapUnits.doo');\n        });\n\n        reader.readAsArrayBuffer(file);\n      } else {\n        this.text(`${name} is not a map`);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/rebuild/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>Rebuilder</title>\n    <meta charset=\"utf-8\" />\n\n    <style>\n        .log {}\n\n        .info {\n            display: block;\n            font-family: monospace;\n            white-space: pre;\n        }\n\n        .warn {\n            color: darkgoldenrod;\n        }\n\n        .error {\n            color: #cc0000;\n        }\n\n        .unused {\n            color: rgb(96, 166, 0);\n        }\n    </style>\n</head>\n\n<body>\n    <script src=\"../thirdparty/filesaver.js\"></script>\n    <script src=\"/clients/rebuild.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/rebuild/index.js",
    "content": "import Rebuilder from './components/rebuilder';\n\nconst rebuilder = new Rebuilder(document.body);\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  rebuilder.rebuildFile(e.dataTransfer.files[0]);\n});\n\n// For debugging etc.\nwindow.rebuilder = rebuilder;\n"
  },
  {
    "path": "clients/recorder/README.md",
    "content": "This client is used to record unit animations into a collection of images, that can be downloaded in a zip file.\n"
  },
  {
    "path": "clients/recorder/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>Recorder | HIVE</title>\n    <meta charset=\"utf-8\" />\n\n    <style>\n        html,\n        body {\n            width: 100%;\n            height: 100%;\n            margin: 0px;\n        }\n\n        .left,\n        .right {\n            position: absolute;\n            width: 50%;\n            height: 100%;\n            padding: 5px;\n            box-sizing: border-box;\n            top: 0;\n        }\n\n        .left {\n            left: 0;\n        }\n\n        .right {\n            right: 0;\n        }\n\n        canvas {\n            width: 100%;\n            height: 100%;\n\n        }\n\n        #controls {\n            position: absolute;\n            left: 0;\n            top: 0;\n            color: white;\n            margin: 8px;\n        }\n    </style>\n</head>\n\n<body>\n    <div class=\"left\">\n        <canvas id=\"canvas\"></canvas>\n        <div id=\"controls\">\n            <p id=\"sequence_name\"></p>\n            <p id=\"frame_counter\"></p>\n        </div>\n    </div>\n\n    <div class=\"right\" id=\"right\">\n        <!--<canvas id=\"output\"></canvas>-->\n    </div>\n\n    <script src=\"../../dist/viewer.min.js\"></script>\n    <script src=\"../thirdparty/jszip.min.js\"></script>\n    <script src=\"../thirdparty/filesaver.js\"></script>\n    <script src=\"../shared/camera.js\"></script>\n    <script src=\"../shared/localorhive.js\"></script>\n    <script src=\"index.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/recorder/index.js",
    "content": "ModelViewer = ModelViewer.default;\n\nlet common = ModelViewer.common;\nlet quat = common.glMatrix.quat;\nlet vec3 = common.glMatrix.vec3;\nlet math = common.math;\nlet geometry = common.geometry;\n\nvar keyboard = {};\nvar mouse = { buttons: [false, false, false], x: 0, y: 0, x2: 0, y2: 0 };\n\nvar canvas = document.getElementById('canvas');\nvar viewer = new ModelViewer.viewer.ModelViewer(canvas, { alpha: true });\nvar instance;\n\nviewer.on('error', (e) => console.error(e));\n\nviewer.addHandler(ModelViewer.viewer.handlers.mdx, localOrHive);\nviewer.addHandler(ModelViewer.viewer.handlers.blp);\nviewer.addHandler(ModelViewer.viewer.handlers.tga);\nviewer.addHandler(ModelViewer.viewer.handlers.dds);\n\nlet backgroundOpaque = true;\nlet turnTable = false;\nlet turnTableSpeed = 0;\nlet turnTableQuat = quat.create();\nlet isRecording = false;\nlet recordingFrame = 0;\nlet oneTimeRecord = false;\nlet zip = new JSZip();\n\nlet frameCounterElement = document.getElementById('frame_counter');\nlet sequenceNameElement = document.getElementById('sequence_name');\n\n(function step() {\n  viewer.updateAndRender();\n\n  if (instance) {\n    instance.rotate(turnTableQuat);\n\n    if (isRecording || oneTimeRecord) {\n      oneTimeRecord = false;\n\n      zip.file(\n        `${recordingFrame++}_${instance.model.name}_${Math.floor(instance.frame)}.png`,\n        viewer.canvas.toDataURL().substring(22),\n        { base64: true }\n      );\n\n      frameCounterElement.textContent = recordingFrame;\n    }\n  }\n\n  requestAnimationFrame(step);\n})();\n\nlet scene = viewer.addScene();\nscene.alpha = true;\nsetupCamera(scene, { distance: 500 });\n\nconsole.log('Viewer version', ModelViewer.version);\n\n// Run the next sequence for the given instance at e.\nfunction runNextSequence(e) {\n  let instance = e.target;\n\n  instance.setSequence((instance.sequence + 1) % instance.model.sequences.length);\n}\n\n// Log load starts to the console.\nviewer.on('loadstart', target => {\n  let path = target.fetchUrl;\n\n  if (path) {\n    console.log('Loading ' + target.fetchUrl);\n  }\n});\n\n// Log load ends to the console.\nviewer.on('load', target => {\n  let path = target.fetchUrl;\n\n  if (path) {\n    console.log('Finished loading ' + target.fetchUrl);\n  }\n});\n\nfunction normalizePath(path) {\n  return path.toLocaleLowerCase().replace(/\\\\/g, '/');\n}\n\n// Load a local file\nfunction onLocalFileLoaded(name, buffer) {\n  if (name.endsWith('.mdx')) {\n    let pathSolver = src => {\n      if (src === buffer) {\n        return src;\n      } else {\n        return localOrHive(normalizePath(src));\n      }\n    };\n\n    turnTableSpeed = 0;\n    quat.identity(turnTableQuat);\n    isRecording = false;\n\n    scene.clear();\n\n    viewer.load(buffer, pathSolver)\n      .then((model) => {\n        instance = model.addInstance();\n\n        instance.setSequenceLoopMode(2);\n        instance.setSequence(0);\n\n        sequenceNameElement.textContent = model.sequences[0].name;\n\n        scene.addInstance(instance);\n      });\n  }\n}\n\ncanvas.addEventListener('contextmenu', function (e) {\n  e.preventDefault();\n});\n\ncanvas.addEventListener('selectstart', function (e) {\n  e.preventDefault();\n});\n\nfunction onFileDrop(e) {\n  let file = e.dataTransfer.files[0];\n\n  if (file) {\n    let name = file.name.toLowerCase();\n\n    if (name.endsWith('.mdx') || name.endsWith('.blp')) {\n      let reader = new FileReader();\n\n      reader.addEventListener('loadend', e => onLocalFileLoaded(name, e.target.result));\n      reader.readAsArrayBuffer(file);\n    }\n  }\n}\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n  onFileDrop(e);\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n  onFileDrop(e);\n});\n\nwindow.addEventListener('keydown', e => {\n  let key = e.key;\n\n  if (instance) {\n    let model = instance.model;\n\n    if (key === ' ') {\n      isRecording = !isRecording;\n    } else if (key === 'ArrowLeft') {\n      if (instance.sequence === 0) {\n        instance.setSequence(model.sequences.length - 1);\n      } else {\n        instance.setSequence(instance.sequence - 1);\n      }\n\n      sequenceNameElement.textContent = model.sequences[instance.sequence].name;\n    } else if (key === 'ArrowRight') {\n      if (instance.sequence === model.sequences.length - 1) {\n        instance.setSequence(0);\n      } else {\n        instance.setSequence(instance.sequence + 1);\n      }\n\n      sequenceNameElement.textContent = model.sequences[instance.sequence].name;\n    } else if (key === 'ArrowUp') {\n      turnTableSpeed += 0.2;\n      quat.setAxisAngle(turnTableQuat, [0, 0, 1], math.degToRad(turnTableSpeed));\n    } else if (key === 'ArrowDown') {\n      turnTableSpeed -= 0.2;\n      quat.setAxisAngle(turnTableQuat, [0, 0, 1], math.degToRad(turnTableSpeed));\n    } else if (key === 'Enter') {\n      oneTimeRecord = true;\n    } else if (key === 'Escape') {\n      if (recordingFrame > 0) {\n        zip.generateAsync({ type: 'blob' }).then(blob => {\n          saveAs(blob, `recorded_frames_${recordingFrame}.zip`);\n\n          zip = new JSZip();\n          recordingFrame = 0;\n          frameCounterElement.textContent = '';\n        });\n      }\n    }\n  }\n\n  if (key === 'b') {\n    backgroundOpaque = !backgroundOpaque;\n\n    if (backgroundOpaque) {\n      viewer.alpha = false;\n\n      sequenceNameElement.style.color = 'white';\n      frameCounterElement.style.color = 'white';\n    } else {\n      viewer.alpha = true;\n      sequenceNameElement.style.color = 'black';\n      frameCounterElement.style.color = 'black';\n    }\n  }\n});\n"
  },
  {
    "path": "clients/sanitytest/README.md",
    "content": "This client runs the MDX sanity tester, and shows the information in a graphical manner.\nIt is used on the Hiveworkshop to find issues with Warcraft 3 models and textures.\n"
  },
  {
    "path": "clients/sanitytest/components/logger.js",
    "content": "import Component from \"../../shared/component\";\nimport Toggle from \"../../shared/components/toggle\";\nimport { createElement, scrolledToBottom, scrollToBottom } from \"../../shared/domutils\";\n\nexport default class Logger extends Component {\n  constructor(options) {\n    super({ ...options, className: 'console' });\n\n    this.messages = [];\n\n    this.tabs = createElement({ className: 'tabs', container: this.container });\n\n    this.logsToggler = new Toggle('Hide Logs', 'Show Logs', (e) => this.filter(), { container: this.tabs });\n    this.infoToggler = new Toggle('Hide Info', 'Show Info', (e) => this.filter(), { container: this.tabs });\n    this.errorsToggler = new Toggle('Hide Errors', 'Show Errors', (e) => this.filter(), { container: this.tabs });\n\n    this.contents = createElement({ className: 'tab-contents', container: this.container });\n\n    // Default to hiding the log spam.\n    this.logsToggler.toggle();\n  }\n\n  message(type, message) {\n    let loggerMessage = new LoggerMessage(type, message);\n\n    loggerMessage.filter(this.logsToggler.clicked, this.infoToggler.clicked, this.errorsToggler.clicked);\n\n    this.messages.push(loggerMessage);\n\n    // If scrolled all the way...\n    let scrolled = scrolledToBottom(this.contents);\n\n    this.contents.appendChild(loggerMessage.container);\n\n    // ...scroll back down after adding the message.\n    if (scrolled) {\n      scrollToBottom(this.contents);\n    }\n  }\n\n  log(message) {\n    this.message('log', message);\n  }\n\n  info(message) {\n    this.message('info', message);\n  }\n\n  error(message) {\n    this.message('error', message);\n  }\n\n  filter() {\n    // If scrolled all the way...\n    let scrolled = scrolledToBottom(this.contents);\n\n    for (let message of this.messages) {\n      message.filter(this.logsToggler.clicked, this.infoToggler.clicked, this.errorsToggler.clicked);\n    }\n\n    // ...scroll down after filtering.\n    if (scrolled) {\n      scrollToBottom(this.contents);\n    }\n  }\n}\n\nclass LoggerMessage extends Component {\n  constructor(type, message) {\n    super({ className: type, textContent: message });\n\n    this.type = type;\n  }\n\n  matchFilters(logs, info, errors) {\n    let type = this.type;\n\n    return (type === 'log' && !logs) || (type === 'info' && !info) || (type === 'error' && !errors);\n  }\n\n  filter(logs, info, errors) {\n    if (this.matchFilters(logs, info, errors)) {\n      this.show();\n    } else {\n      this.hide();\n    }\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/components/mdlview.js",
    "content": "import mdlStructure from \"../../../src/utils/mdlx/mdlstructure\";\nimport Component from \"../../shared/component\";\nimport { createElement } from \"../../shared/domutils\";\n\nexport default class MdlView extends Component {\n  constructor(parser) {\n    super({ className: 'mdl-view' });\n\n    const mdlNodes = mdlStructure(parser);\n\n    this.structureElement = createElement({ className: 'mdl-structure', container: this.container });\n    this.sourceElement = createElement({ tagName: 'pre', className: 'mdl-source', container: this.container });\n\n    this.nodes = [];\n    this.visibleNode = null;\n\n    for (let node of mdlNodes) {\n      this.nodes.push(new MdlViewNode(this, node, this.structureElement));\n    }\n  }\n\n  showNode(node) {\n    if (this.visibleNode) {\n      this.visibleNode.normal();\n    }\n\n    this.visibleNode = node;\n\n    node.highlight();\n\n    this.sourceElement.textContent = node.node.source;\n  }\n}\n\nclass MdlViewNode extends Component {\n  constructor(view, node, parentElement) {\n    super({ className: 'clickable highlightable', textContent: node.name, container: parentElement });\n\n    this.container.addEventListener('click', () => view.showNode(this));\n\n    this.node = node;\n    this.nodes = [];\n\n    if (node.nodes && node.nodes.length) {\n      let container = createElement({ className: 'indent' });\n\n      for (let child of node.nodes) {\n        this.nodes.push(new MdlViewNode(view, child, container));\n      }\n\n      parentElement.appendChild(container);\n    }\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/components/sanitytester.js",
    "content": "import { basename, extname } from \"../../../src/common/path\";\nimport War3Map from \"../../../src/parsers/w3x/map\";\nimport Component from \"../../shared/component\";\nimport Toggle from \"../../shared/components/toggle\";\nimport { createElement, hideElement, showElement } from \"../../shared/domutils\";\nimport localOrHive from \"../../shared/localorhive\";\nimport { getAllFileEntries, readFile, readEntry } from \"../../shared/utils\";\nimport Test from \"../test\";\nimport Logger from \"./logger\";\nimport Viewer from \"./viewer\";\n\nexport default class SanityTester extends Component {\n  constructor(parentElement) {\n    super({ className: 'client' });\n\n    this.tests = [];\n    this.visibleTest = null;\n\n    // Tests header\n    let testsHeader = createElement({ className: 'tests-header', container: this.container });\n    createElement({ tagName: 'h1', textContent: 'Tests', container: testsHeader, container: testsHeader });\n\n    // Tests body\n    let testsBody = createElement({ className: 'tests-body', container: this.container });\n    this.searchTests = createElement({ tagName: 'input', placeholder: 'Search tests', oninput: () => this.filterTests(), container: testsBody });\n    this.testsElement = createElement({ className: 'tests', container: testsBody });\n\n    // Results header\n    let resultsHeader = createElement({ className: 'results-header', container: this.container });\n    createElement({ tagName: 'h1', textContent: 'Test Results', container: resultsHeader, container: resultsHeader });\n    this.unusedToggle = new Toggle('Hide Unused', 'Show Unused', () => this.filterResults(), { container: resultsHeader });\n    this.warningToggle = new Toggle('Hide Warnings', 'Show Warnings', () => this.filterResults(), { container: resultsHeader });\n    this.severeToggler = new Toggle('Hide Severe', 'Show Severe', () => this.filterResults(), { container: resultsHeader });\n    this.errorToggler = new Toggle('Hide Errors', 'Show Errors', () => this.filterResults(), { container: resultsHeader });\n\n    // Results body\n    this.resultsBody = createElement({ className: 'results-body', container: this.container });\n\n    // Viewer/Logger and MDL header\n    let viewerLoggerMdlHeader = createElement({ className: 'viewer-and-mdl-header', container: this.container });\n    let viewerLoggerMdlH1 = createElement({ tagName: 'h1', textContent: '3D View', container: viewerLoggerMdlHeader });\n\n    // Viewer/Logger and MDL body\n    let viewerLoggerMdlBody = createElement({ className: 'viewer-and-mdl-body', container: this.container });\n    let viewerLogger = createElement({ className: 'viewer-and-console', container: viewerLoggerMdlBody });\n    this.mdl = createElement({ className: 'mdl hidden', container: viewerLoggerMdlBody });\n\n    // Viewer/Logger and MDL toggler\n    new Toggle('View in MDL', 'View in 3D', (e) => {\n      if (e.clicked) {\n        viewerLoggerMdlH1.textContent = 'MDL View';\n\n        hideElement(viewerLogger);\n        showElement(this.mdl);\n\n        if (!this.viewer.controls.animationToggle.clicked) {\n          this.viewer.controls.animationToggle.toggle();\n        }\n      } else {\n        viewerLoggerMdlH1.textContent = '3D View';\n\n        showElement(viewerLogger);\n\n        // If the page was resized in MDL view, the camera thinks the size of the canvas is 1x1.\n        // Need to resize now that the canvas is visible again and has a real size.\n        this.viewer.orbitCamera.onResize();\n\n        hideElement(this.mdl);\n      }\n    }, { container: viewerLoggerMdlHeader });\n\n    // Actual Viewer and Logger\n    this.logger = new Logger({ container: viewerLogger });\n    this.viewer = new Viewer(this, { container: viewerLogger });\n\n    // Append at the end to avoid re-renders.\n    parentElement.appendChild(this.container);\n  }\n\n  filterTests() {\n    let term = this.searchTests.value.toLowerCase();\n\n    for (let test of this.tests) {\n      if (test.name.toLowerCase().includes(term)) {\n        test.meta.show();\n      } else {\n        test.meta.hide();\n      }\n    }\n  }\n\n  filterResults() {\n    if (this.visibleTest && this.visibleTest.results) {\n      this.visibleTest.results.filter(this.unusedToggle.clicked, this.warningToggle.clicked, this.severeToggler.clicked, this.errorToggler.clicked);\n    }\n  }\n\n  // pathSolver is used for API tests.\n  test(name, buffer, render, pathSolver) {\n    this.logger.info(`Parsing ${name}`);\n\n    let test;\n\n    try {\n      test = new Test(this, name, buffer, pathSolver);\n    } catch (e) {\n      this.logger.error(`An error occured before the test could finish: ${e.stack}`)\n    }\n\n    this.tests.push(test);\n\n    this.testsElement.appendChild(test.meta.container);\n    test.meta.container.scrollIntoView();\n\n    if (test.results) {\n      this.resultsBody.appendChild(test.results.container);\n    }\n\n    if (test.mdl) {\n      this.mdl.appendChild(test.mdl.container);\n    }\n\n    this.viewer.load(test);\n\n    if (render) {\n      this.render(test);\n    } else {\n      test.hide();\n    }\n  }\n\n  render(test) {\n    if (test !== this.visibleTest) {\n      if (this.visibleTest) {\n        this.visibleTest.hide();\n      }\n\n      this.visibleTest = test;\n      this.filterResults();\n\n      test.show();\n\n      this.viewer.render(test);\n    }\n  }\n\n  loadMap(name, buffer) {\n    this.logger.info(`Parsing ${name}`);\n\n    let map = new War3Map();\n\n    try {\n      map.load(buffer);\n    } catch (e) {\n      this.logger.error(`Failed to parse ${name}: ${e}`);\n\n      return;\n    }\n\n    let pathSolver = (src, params) => {\n      let file = map.get(src);\n\n      if (file) {\n        return file.bytes();\n      }\n\n      return localOrHive(src, params);\n    };\n\n    let render = true;\n\n    for (let importName of map.getImportNames()) {\n      let ext = extname(importName);\n\n      if (ext === '.mdx' || ext === '.mdl' || ext === '.blp' || ext === '.dds' || ext === '.tga') {\n        let file = map.get(importName);\n\n        if (file) {\n          if (ext === '.mdx') {\n            this.test(`${name}:${importName}`, file.arrayBuffer(), render, pathSolver);\n          } else if (ext === '.mdl') {\n            this.test(`${name}:${importName}`, file.text(), render, pathSolver);\n          } else if (ext === '.blp' || ext === '.dds' || ext === '.tga') {\n            this.test(`${name}:${importName}`, file.arrayBuffer(), render);\n          }\n\n          render = false;\n        } else {\n          this.logger.error(`The map says it imports ${importName} but it couldn't be found`);\n        }\n      }\n    }\n  }\n\n  /**\n   * Load a file, e.g. resulting from a Drag & Drop action.\n   */\n  async loadFile(file) {\n    let name = file.name;\n    let ext = extname(name);\n\n    if (ext === '.mdx' || ext === '.mdl' || ext === '.blp' || ext === '.dds' || ext === '.tga' || ext === '.w3x' || ext === '.w3m') {\n      this.logger.info(`Reading ${name}`);\n\n      let buffer = await readFile(file, ext === '.mdl');\n\n      if (ext === '.w3m' || ext === '.w3x') {\n        this.loadMap(name, buffer);\n      } else {\n        this.test(name, buffer, true);\n      }\n    } else {\n      this.logger.info(`${name} is not a supported file, skipping it`);\n    }\n  }\n\n  /**\n   * Load all of the entries from a data transfer, e.g. resulting from a Drag & Drop action.\n   */\n  async loadDataTransfer(dataTransfer) {\n    let entries = await getAllFileEntries(dataTransfer);\n    let names = [];\n    let promises = [];\n\n    // First start reading all of the relevant files.\n    for (let entry of entries) {\n      let name = entry.name;\n      let ext = extname(name);\n\n      if (ext === '.mdx' || ext === '.mdl' || ext === '.blp' || ext === '.dds' || ext === '.tga' || ext === '.w3x' || ext === '.w3m') {\n        this.logger.info(`Reading ${name}`);\n\n        names.push(name.toLowerCase());\n        promises.push(readEntry(entry, ext === '.mdl'));\n      } else {\n        this.logger.info(`${name} is not a supported file, skipping it`);\n      }\n    }\n\n    // Finish reading...\n    let buffers = await Promise.all(promises);\n\n    // Now map from names to buffers.\n    let overrides = new Map();\n\n    for (let i = 0, l = names.length; i < l; i++) {\n      overrides.set(names[i], buffers[i]);\n    }\n\n    // Path solver to see if a resource that needs loading is one of the files in the data transfer.\n    let pathSolver = (src, params) => {\n      let override = overrides.get(basename(src).toLowerCase());\n\n      if (override) {\n        return override;\n      } else {\n        return localOrHive(src, params);\n      }\n    };\n\n    let render = true;\n\n    // Finally load the tests.\n    for (let [name, buffer] of overrides.entries()) {\n      if (name.endsWith('.w3m') || name.endsWith('.w3x')) {\n        this.loadMap(name, buffer);\n      } else {\n        this.test(name, buffer, render, pathSolver);\n      }\n\n      render = false;\n    }\n  }\n\n  /**\n   * Used by the Hiveworkshop to test resources.\n   * \n   * file=url&file=url2&override[path]=url3\n   */\n  loadAPI(api) {\n    if (api !== '') {\n      let files = [];\n      let overrides = new Map();\n\n      for (let param of api.slice(1).split('&')) {\n        let [key, value] = param.split('=');\n\n        if (value !== undefined) {\n          // Test also overrides.\n          files.push(value);\n\n          if (key.startsWith('override')) {\n            // Discord changes \\ to / in urls, ignoring escaping, so escape manually.\n            overrides.set(key.slice(9, -1).replace(/\\//g, '\\\\'), value);\n          }\n        }\n      }\n\n      if (files.length) {\n        let pathSolver = (src, params) => {\n          let override = overrides.get(basename(src).toLowerCase());\n\n          if (override) {\n            return override;\n          } else {\n            return localOrHive(src, params);\n          }\n        };\n\n        let render = true;\n\n        for (let file of files) {\n          fetch(file)\n            .then(async (response) => {\n              let buffer;\n\n              if (file.endsWith('.mdl')) {\n                buffer = await response.text();\n              } else {\n                buffer = await response.arrayBuffer();\n              }\n\n              this.test(file, buffer, render, pathSolver);\n\n              render = false;\n            });\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/components/teamcolors.js",
    "content": "export const TEAM_COLORS = [\n  { name: 'Red', color: '#ff0402' },\n  { name: 'Blue', color: '#0042ff' },\n  { name: 'Teal', color: '#1be6ba' },\n  { name: 'Purple', color: '#540081' },\n  { name: 'Yellow', color: '#fffc00' },\n  { name: 'Orange', color: '#ff8a0d' },\n  { name: 'Green', color: '#20c000' },\n  { name: 'Pink', color: '#e45bb0' },\n  { name: 'Gray', color: '#949697' },\n  { name: 'Light Blue', color: '#7ebff1' },\n  { name: 'Dark Green', color: '#106247' },\n  { name: 'Brown', color: '#4f2a05' },\n  { name: 'Maroon', color: '#9c0000' },\n  { name: 'Navy', color: '#0000c3' },\n  { name: 'Turquoise', color: '#00ebff' },\n  { name: 'Violet', color: '#bd00ff' },\n  { name: 'Wheat', color: '#eccd86' },\n  { name: 'Peach', color: '#f7a48b' },\n  { name: 'Mint', color: '#c0ff80' },\n  { name: 'Lavender', color: '#dcb9ec' },\n  { name: 'Coal', color: '#4f4f55' },\n  { name: 'Snow', color: '#ecf0ff' },\n  { name: 'Emerald', color: '#00781e' },\n  { name: 'Peanut', color: '#a46f33' },\n  { name: 'Neutral', color: '#2e2d2e' },\n];\n"
  },
  {
    "path": "clients/sanitytest/components/testmeta.js",
    "content": "import Component from \"../../shared/component\";\nimport { createElement } from \"../../shared/domutils\";\n\nfunction singleOrPlural(name, count) {\n  if (count === 1) {\n    return name;\n  }\n\n  return `${name}s`;\n}\n\nexport default class TestMeta extends Component {\n  constructor(name, parsingError, results, options) {\n    super({ ...options, className: 'clickable highlightable padded' });\n\n    this.name = createElement({ className: 'bold', textContent: name, container: this.container });\n\n    let container = createElement({ className: 'indent', container: this.container });\n\n    if (parsingError) {\n      createElement({ className: 'error', textContent: 'Parsing failed', container });\n    }\n\n    if (results.errors || results.severe || results.warnings || results.unused) {\n      if (results.errors) {\n        createElement({ className: 'error', textContent: `${results.errors} ${singleOrPlural('error', results.errors)}`, container });\n      }\n\n      if (results.severe) {\n        createElement({ className: 'severe', textContent: `${results.severe} ${singleOrPlural('severe warning', results.severe)}`, container });\n      }\n\n      if (results.warnings) {\n        createElement({ className: 'warning', textContent: `${results.warnings} ${singleOrPlural('warning', results.warnings)}`, container });\n      }\n\n      if (results.unused) {\n        createElement({ className: 'unused', textContent: `${results.unused} unused`, container });\n      }\n    } else {\n      createElement({ className: 'bold', textContent: 'Passed', container });\n    }\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/components/testresults.js",
    "content": "import { imageDataToImage } from \"../../../src/common/canvas\";\nimport Component from \"../../shared/component\";\nimport { createElement } from \"../../shared/domutils\";\nimport getTooltip from \"./tooltips\";\nimport MdlxModel from '../../../src/parsers/mdlx/model';\nimport { BlpImage, CONTENT_JPG } from '../../../src/parsers/blp/image';\nimport { DdsImage, FOURCC_ATI2, FOURCC_DXT1, FOURCC_DXT3, FOURCC_DXT5 } from '../../../src/parsers/dds/image';\nimport TgaImage from '../../../src/parsers/tga/image';\nimport mdlxSanityTest from '../../../src/utils/mdlx/sanitytest/sanitytest';\nimport blpSanityTest from '../../../src/utils/blp/sanitytest';\nimport ddsSanityTest from '../../../src/utils/dds/sanitytest';\n\nexport default class TestResults extends Component {\n  constructor(parser) {\n    super();\n\n    this.nodes = [];\n\n    const container = this.container;\n    const isMdlx = parser instanceof MdlxModel;\n    const isBlp = parser instanceof BlpImage;\n    const isDds = parser instanceof DdsImage;\n    const isTga = parser instanceof TgaImage;\n    const isImage = isBlp || isDds || isTga;\n\n    if (isBlp || isDds || isTga) {\n      createElement({ textContent: `Width: ${parser.width}`, container });\n      createElement({ textContent: `Height: ${parser.height}`, container });\n\n      if (isBlp) {\n        if (parser.content === CONTENT_JPG) {\n          createElement({ textContent: `Content: JPG`, container });\n        } else {\n          createElement({ textContent: `Content: Palette`, container });\n        }\n\n        if (parser.alphaBits > 8) {\n          createElement({ textContent: `Alpha bits: ${parser.alphaBits} (fake)`, container });\n        } else {\n          createElement({ textContent: `Alpha bits: ${parser.alphaBits}`, container });\n        }\n\n        createElement({ textContent: `Mipmaps: ${parser.mipmaps()} (fake: ${parser.fakeMipmaps()})`, container });\n      } else if (isDds) {\n        if (parser.format === FOURCC_DXT1) {\n          createElement({ textContent: `Content: BC1 (DXT1)`, container });\n        } else if (parser.format === FOURCC_DXT3) {\n          createElement({ textContent: `Content: BC2 (DXT3)`, container });\n        } else if (parser.format === FOURCC_DXT5) {\n          createElement({ textContent: `Content: BC3 (DXT5)`, container });\n        } else if (parser.format === FOURCC_ATI2) {\n          createElement({ textContent: `Content: BC5 (ATI2)`, container });\n        } else {\n          createElement({ textContent: `Content: Not supported`, container });\n        }\n\n        createElement({ textContent: `Mipmaps: ${parser.mipmaps()}`, container });\n      }\n\n      createElement({ tagName: 'hr', container });\n    }\n\n    let results;\n\n    if (isMdlx) {\n      results = mdlxSanityTest(parser);\n    } else if (isBlp) {\n      results = blpSanityTest(parser);\n    } else if (isDds) {\n      results = ddsSanityTest(parser);\n    } else {\n      results = {};\n    }\n\n    if (results.nodes && results.nodes.length) {\n      for (let node of results.nodes) {\n        this.nodes.push(new TestResultsNode(node, container));\n      }\n    } else {\n      this.nodes.push(new TestResultsNode({ type: 'bold', message: 'Passed' }, container));\n    }\n\n    this.results = results;\n\n    if (isImage) {\n      createElement({ tagName: 'hr', container });\n\n      if (isBlp || isDds) {\n        for (let i = 0, l = parser.mipmaps(); i < l; i++) {\n          try {\n            let imageData;\n\n            if (isBlp) {\n              imageData = parser.getMipmap(i);\n            } else {\n              imageData = this.getDdsMipmap(parser, i);\n            }\n\n            this.addMipmap(imageData);\n          } catch (e) {\n            if (this.results.errors === undefined) {\n              this.results.errors = 1;\n            } else {\n              this.results.errors += 1;\n            }\n\n            this.nodes.push(new TestResultsNode({ type: 'error', message: `Mipmap ${i}: ${e}` }, this.container));\n          }\n        }\n      } else {\n        this.addMipmap(parser.data);\n      }\n    }\n  }\n\n  getDdsMipmap(parser, i) {\n    const mipmap = parser.getMipmap(i);\n\n    if (parser.format === FOURCC_ATI2) {\n      const imageData = new ImageData(mipmap.width, mipmap.height);\n      const inData = mipmap.data;\n      const outData = imageData.data;\n\n      for (let i = 0, l = mipmap.width * mipmap.height; i < l; i++) {\n        const offset2 = i * 2;\n        const offset4 = i * 4;\n\n        outData[offset4 + 0] = inData[offset2 + 0];\n        outData[offset4 + 1] = inData[offset2 + 1];\n        outData[offset4 + 2] = 0;\n        outData[offset4 + 3] = 255;\n      }\n\n      return imageData;\n    } else {\n      return new ImageData(new Uint8ClampedArray(mipmap.data.buffer), mipmap.width, mipmap.height);\n    }\n  }\n\n  addMipmap(imageData) {\n    const image = imageDataToImage(imageData);\n\n    image.className = 'padded';\n\n    this.container.appendChild(image);\n  }\n\n  filter(unused, warnings, severe, errors) {\n    for (let node of this.nodes) {\n      node.filter(unused, warnings, severe, errors);\n    }\n  }\n}\n\nclass TestResultsNode extends Component {\n  constructor(node, parentElement) {\n    super();\n\n    let className = '';\n    let textContent = '';\n    let tooltip = '';\n\n    if (node.type === 'node') {\n      className = 'bold';\n      textContent = node.name;\n    } else {\n      className = node.type;\n      textContent = node.message;\n      tooltip = getTooltip(textContent);\n\n      if (tooltip.length) {\n        className += ' pointer';\n      }\n    }\n\n    const resultElement = createElement({ className, textContent, title: tooltip, container: this.container });\n\n    if (tooltip.length) {\n      createElement({ tagName: 'span', className: 'info_marker', textContent: 'tooltip', container: resultElement });\n    }\n\n    this.node = node;\n    this.nodes = [];\n\n    if (node.type === 'node') {\n      if (node.nodes.length || node.uses === 0) {\n        let container = createElement({ className: 'indent', container: this.container });\n\n        if (node.uses === 0) {\n          this.nodes.push(new TestResultsNode({ type: 'unused', message: 'Not used' }, container));\n        }\n\n        for (let child of node.nodes) {\n          this.nodes.push(new TestResultsNode(child, container));\n        }\n      }\n    }\n\n    parentElement.appendChild(this.container);\n  }\n\n  filter(unused, warnings, severe, errors) {\n    if (this.matchFilters(unused, warnings, severe, errors)) {\n      if (this.node.type === 'node') {\n        for (let child of this.nodes) {\n          child.filter(unused, warnings, severe, errors);\n        }\n      }\n\n      this.show();\n    } else {\n      this.hide();\n    }\n  }\n\n  matchFilters(unused, warnings, severe, errors) {\n    let node = this.node;\n\n    if (node.type === 'node') {\n      return ((node.unused || node.uses === 0) && !unused) || (node.warnings && !warnings) || (node.severe && !severe) || (node.errors && !errors);\n    } else {\n      let type = node.type;\n\n      return (type === 'unused' && !unused) || (type === 'warning' && !warnings) || (type === 'severe' && !severe) || (type === 'error' && !errors) || type === 'bold';\n    }\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/components/tooltips.js",
    "content": "export default function getTooltip(message) {\n  if (message.includes('does not match the number of sequences')) { // Number of sequence extents (9) does not match the number of sequences (3)\n    return `Having the wrong amount of geoset extents can in some cases crash War 3 Model Editor (Magos).\n\nThis does not affect the game.`;\n  } else if (message.includes('has exactly the same value as tracks')) { // Track 3 at frame 1096 has exactly the same value as tracks 2 and 4\n    return 'A keyframe with the same value as the two keyframes sorrounding it is useless.';\n  } else if (message.includes('has roughly the same value as tracks')) { // Track 3 at frame 1096 has roughly the same value as tracks 2 and 4\n    return 'A keyframe with roughly the same value as the two keyframes sorrounding it is many times useless.';\n  } else if (message.includes('Missing opening track for sequence')) { // Missing opening track for sequence \"Death\" at frame 21000 where it is needed\n    return `When missing the opening keyframe for an animation, the game will wrap the animation and interpolate between the last and first keyframes.\n\nHowever there is a bug in the game which causes the animation values to reverse.\n\nTo fix it, add a keyframe at the beginning of the animation.\n`;\n  } else if (message.includes('has the same frame')) { // Track 7 has the same frame 1267 as track 6\n    return 'Remove one of the keyframes.'\n  } else if (message === 'Missing the Origin attachment point') { // Missing the Origin attachment point\n    return `Missing the Origin attachment stops many in-game effects from attaching to models.\n\nNot relevant to portraits and special effects.`;\n  } else if (message.includes('is not in global sequence')) { // Track 17 at frame 4577 is not in global sequence 2\n    return `This keyframe uses a global sequence, but its frame is outside of the global sequence's range.`;\n  } else if (message === 'Missing \"Stand\" sequence') { // Missing \"Stand\" sequence\n    return `Missing the stand animation can cause issues for models that are used as units.\n\nNot relevant to portraits.`;\n  } else if (message === 'Missing \"Death\" sequence') { // Missing \"Death\" sequence\n    return `Missing the death animation makes particles and other effects linger for a short time after an object using this model dies.\n    \nNot relevant to portraits.`;\n  } else if (message.endsWith('is not in any sequence')) {\n    return 'A keyframe that is not in any animation is useless.';\n  } else if (message.includes('is lower than the track before it at')) {\n    return 'A keyframe is not supposed to have a frame before the previous keyframe.';\n  } else if (message === 'There are no vertices attached to this bone') {\n    return 'Bones with no attached vertices should preferably be converted to helpers.'\n  } else {\n    //console.log('getTooltip', message)\n  }\n\n  return '';\n}\n"
  },
  {
    "path": "clients/sanitytest/components/viewer.js",
    "content": "import ModelViewer from '../../../src/viewer/viewer';\nimport mdxHandler from '../../../src/viewer/handlers/mdx/handler';\nimport blpHandler from '../../../src/viewer/handlers/blp/handler';\nimport ddsHandler from '../../../src/viewer/handlers/dds/handler';\nimport tgaHandler from '../../../src/viewer/handlers/tga/handler';\nimport Component from \"../../shared/component\";\nimport { createElement } from \"../../shared/domutils\";\nimport localOrHive from \"../../shared/localorhive\";\nimport { setupCamera } from \"../../shared/camera\";\nimport ViewerControls from \"./viewercontrols\";\nimport createPrimitive from '../../../src/utils/mdlx/primitives/createprimitive';\nimport { createUnitRectangle, createUnitCube, createUnitSphere } from '../../../src/utils/mdlx/primitives/primitives';\nimport { filename } from '../../../src/common/path';\nimport Model from '../../../src/viewer/model';\nimport Texture from '../../../src/viewer/texture';\nimport MdxModel from '../../../src/viewer/handlers/mdx/model';\nimport { Shape } from '../../../src/parsers/mdlx/collisionshape';\n\nexport default class Viewer extends Component {\n  constructor(tester, options) {\n    super({ ...options, className: 'viewer' });\n\n    this.tester = tester;\n    this.messages = [];\n\n    this.canvas = createElement({ tagName: 'canvas', style: 'width:100%;height:100%', container: this.container });\n    this.controls = new ViewerControls(this, { container: this.container });\n\n    let viewer = new ModelViewer(this.canvas);\n    let scene = viewer.addScene();\n\n    this.viewer = viewer;\n    this.scene = scene;\n\n    this.visibleTest = null;\n\n    this.teamColor = 0;\n\n    scene.color.fill(0.2);\n\n    this.orbitCamera = setupCamera(scene, {\n      onManualChange: () => {\n        this.setCamera(-1);\n        this.controls.setCamera(-1);\n      },\n    });\n\n    viewer.on('loadstart', (e) => {\n      tester.logger.log(`[Viewer] Loading ${e.fetchUrl}`);\n    });\n\n    viewer.on('loadend', (e) => {\n      tester.logger.log(`[Viewer] Loaded ${e.fetchUrl}`);\n    });\n\n    viewer.on('error', (e) => {\n      if (e.fetchUrl) {\n        tester.logger.error(`[Viewer] ${e.error}: ${e.fetchUrl}`);\n      } else {\n        tester.logger.error(`[Viewer] ${e.error}: ${e.reason}`);\n      }\n    });\n\n    viewer.addHandler(mdxHandler, localOrHive, true);\n    viewer.addHandler(blpHandler);\n    viewer.addHandler(ddsHandler);\n    viewer.addHandler(tgaHandler);\n\n    this.textureModel = null;\n    this.boxModel = null;\n    this.sphereModel = null;\n\n    createPrimitive(viewer, createUnitRectangle(), { twoSided: true })\n      .then((model) => {\n        this.textureModel = model;\n      });\n\n    createPrimitive(viewer, createUnitCube(), { lines: true })\n      .then((model) => {\n        this.boxModel = model;\n      });\n\n    createPrimitive(viewer, createUnitSphere(12, 12), { lines: true })\n      .then((model) => {\n        this.sphereModel = model;\n      });\n\n    let lastTime = performance.now();\n\n    let step = () => {\n      requestAnimationFrame(step);\n\n      let now = performance.now();\n      let dt = now - lastTime;\n\n      lastTime = now;\n\n      if (this.controls.animationToggle.clicked) {\n        viewer.updateAndRender(0);\n      } else {\n        viewer.updateAndRender(dt);\n      }\n\n      if (this.visibleTest) {\n        let instance = this.visibleTest.instance;\n\n        if (instance.sequenceEnded) {\n          let sequence = instance.sequence;\n\n          if (!this.controls.cycleToggle.clicked) {\n            sequence += 1;\n\n            if (sequence === instance.model.sequences.length) {\n              sequence = 0;\n            }\n\n            this.setSequence(sequence);\n          }\n        }\n\n        this.controls.frame(instance.frame);\n      }\n    };\n\n    step();\n  }\n\n  async load(test) {\n    const modelOrTexture = await this.viewer.load(test.parser, (src, params) => {\n      if (src === test.parser) {\n        return src;\n      }\n\n      // Used for map and API tests.\n      if (test.pathSolver) {\n        return test.pathSolver(src, params);\n      }\n\n      return localOrHive(src, params);\n    });\n\n    if (!modelOrTexture) {\n      return;\n    }\n\n    let instance;\n\n    if (modelOrTexture instanceof MdxModel) {\n      instance = modelOrTexture.addInstance();\n      instance.setTeamColor(this.teamColor);\n\n      let boundingBox = this.boxModel.addInstance();\n      boundingBox.hide();\n      boundingBox.setScene(this.scene);\n      boundingBox.setParent(instance);\n\n      let boundingSphere = this.sphereModel.addInstance();\n      boundingSphere.hide();\n      boundingSphere.setScene(this.scene);\n      boundingSphere.setParent(instance);\n\n      test.boundingBox = boundingBox;\n      test.boundingSphere = boundingSphere;\n\n      // let cameraPromises = [];\n\n      // for (let camera of modelOrTexture.cameras) {\n      //   console.log(camera)\n      //   cameraPromises.push(ModelViewer.default.utils.mdlx.createPrimitive(this.viewer, ModelViewer.default.utils.mdlx.primitives.createFrustum(camera.fieldOfView, this.canvas.width / this.canvas.height, camera.nearClippingPlane, camera.farClippingPlane), { lines: true }));\n      // }\n\n      // Promise.all(cameraPromises)\n      //   .then((cameraModels) => {\n      //     for (let i = 0, l = cameraModels.length; i < l; i++) {\n      //       let model = cameraModels[i];\n      //       let instance = model.addInstance();\n\n      //       //instance.hide();\n      //       instance.setScene(this.scene);\n\n      //       instance.setLocation(modelOrTexture.cameras[i].position);\n      //       instance.face(modelOrTexture.cameras[i].targetPosition, [0, 0, 1]);\n\n      //       test.cameras.push(instance);\n      //     }\n      //   });\n\n      for (let shape of modelOrTexture.collisionShapes) {\n        if (shape.type === 0) {\n          const shapeInstance = this.boxModel.addInstance();\n          const [min, max] = shape.vertices;\n\n          let x = (max[0] + min[0]) / 2;\n          let y = (max[1] + min[1]) / 2;\n          let z = (max[2] + min[2]) / 2;\n          let w = (max[0] - min[0]) / 2;\n          let d = (max[1] - min[1]) / 2;\n          let h = (max[2] - min[2]) / 2;\n\n          shapeInstance.hide();\n          shapeInstance.setLocation([x, y, z]);\n          shapeInstance.setScale([w, d, h]);\n          shapeInstance.dontInheritScaling = false;\n          shapeInstance.setParent(instance.nodes[shape.index]);\n          shapeInstance.setScene(this.scene);\n\n          test.collisions.push(shapeInstance);\n        } else if (shape.type === 2) {\n          const shapeInstance = this.sphereModel.addInstance();\n\n          shapeInstance.hide();\n          shapeInstance.setParent(instance.nodes[shape.index]);\n          shapeInstance.uniformScale(shape.boundsRadius);\n          shapeInstance.setScene(this.scene);\n\n          test.collisions.push(shapeInstance);\n        } else {\n          console.log('COLLISION SHAPE NOT SUPPOTED', shape)\n        }\n      }\n    } else {\n      instance = this.textureModel.addInstance();\n\n      instance.scale([modelOrTexture.width, modelOrTexture.height, 1]);\n      instance.setTexture(0, modelOrTexture);\n    }\n\n    instance.hide();\n    instance.setSequenceLoopMode(2);\n    instance.setScene(this.scene);\n\n    test.resource = modelOrTexture;\n    test.instance = instance;\n\n    this.tryToInjectCustomTextures(test);\n\n    if (test === this.tester.visibleTest) {\n      this.render(test);\n    }\n  }\n\n  render(test) {\n    if (test.instance) {\n      if (this.visibleTest) {\n        this.visibleTest.instance.hide();\n\n        if (this.visibleTest.boundingBox) {\n          this.visibleTest.boundingBox.hide();\n          this.visibleTest.boundingSphere.hide();\n        }\n\n        // for (let camera of this.visibleTest.cameras) {\n        //   camera.hide();\n        // }\n\n        for (const collision of this.visibleTest.collisions) {\n          collision.hide();\n        }\n      }\n\n      this.visibleTest = test;\n\n      if (test.instance.model.sequences.length) {\n        this.controls.updateInstance(test.instance);\n\n        this.viewer.clearEmittedObjects();\n\n        if (test.instance.sequence === -1) {\n          this.setSequence(0);\n        } else {\n          this.setSequence(test.instance.sequence)\n        }\n\n        this.controls.show();\n      } else {\n        this.controls.hide();\n      }\n\n      test.instance.show();\n\n      this.updateExtents();\n\n      // for (let camera of test.cameras) {\n      //   camera.show();\n      // }\n\n      if (this.controls.collisionsToggle.clicked) {\n        for (const collision of test.collisions) {\n          collision.show();\n        }\n      }\n    }\n  }\n\n  updateExtents() {\n    if (this.visibleTest && this.visibleTest.boundingBox) {\n      let mode = this.controls.extentElement.selectedIndex;\n\n      if (mode === 0 || mode === 2) {\n        this.visibleTest.boundingBox.hide();\n      } else {\n        this.visibleTest.boundingBox.show();\n      }\n\n      if (mode === 0 || mode === 1) {\n        this.visibleTest.boundingSphere.hide();\n      } else {\n        this.visibleTest.boundingSphere.show();\n      }\n    }\n  }\n\n  showCollisions(show) {\n    if (this.visibleTest) {\n      for (const collision of this.visibleTest.collisions) {\n        if (show) {\n          collision.show();\n        } else {\n          collision.hide();\n        }\n      }\n    }\n  }\n\n  setSequence(index) {\n    this.visibleTest.instance.setSequence(index);\n\n    if (this.visibleTest.boundingBox) {\n      let extent;\n\n      if (index === -1) {\n        extent = this.visibleTest.parser.extent;\n      } else {\n        extent = this.visibleTest.parser.sequences[index].extent;\n\n        let { max, min } = extent;\n\n        // If this sequence has no extent, use the model extent instead.\n        if (max[0] === 0 && max[1] === 0 && max[2] === 0 && min[0] === 0 && min[1] === 0 && min[2] === 0) {\n          extent = this.visibleTest.parser.extent;\n        }\n      }\n\n      let { max, min } = extent;\n      let x = (max[0] + min[0]) / 2;\n      let y = (max[1] + min[1]) / 2;\n      let z = (max[2] + min[2]) / 2;\n      let w = (max[0] - min[0]) / 2;\n      let d = (max[1] - min[1]) / 2;\n      let h = (max[2] - min[2]) / 2;\n\n      this.visibleTest.boundingBox.setLocation([x, y, z]);\n      this.visibleTest.boundingBox.setScale([w, d, h]);\n\n      this.visibleTest.boundingSphere.setLocation([x, y, z]);\n      this.visibleTest.boundingSphere.setUniformScale(extent.boundsRadius);\n    }\n\n    this.controls.setSequence(index);\n  }\n\n  setCamera(index) {\n    if (index === -1) {\n      this.orbitCamera.instance = null;\n    } else {\n      this.orbitCamera.applyInstanceCamera(this.visibleTest.instance);\n    }\n  }\n\n  setTeamColor(index) {\n    this.teamColor = index;\n\n    if (this.visibleTest) {\n      this.visibleTest.instance.setTeamColor(this.teamColor);\n    }\n  }\n\n  tryToInjectCustomTextures(customTest) {\n    // If the given test is a texture, inject it into all of the model tests.\n    if (customTest.resource instanceof Texture) {\n      for (let test of this.tester.tests) {\n        if (test !== customTest && test.instance && test.resource instanceof Model) {\n          let textures = test.parser.textures;\n\n          for (let i = 0, l = textures.length; i < l; i++) {\n            let a = filename(textures[i].path).toLowerCase();\n            let b = filename(customTest.name).toLowerCase();\n\n            if (a === b) {\n              test.instance.setTexture(i, customTest.resource);\n\n              this.tester.logger.info(`Injected ${customTest.name} as a custom texture for ${test.name}`);\n            }\n          }\n        }\n      }\n    } else {\n      // Otherwise, if it's a model test, inject all of the texture tests into it.\n      for (let test of this.tester.tests) {\n        if (test !== customTest && test.instance) {\n          if (test.resource instanceof Texture) {\n            let textures = customTest.parser.textures;\n\n            for (let i = 0, l = textures.length; i < l; i++) {\n              let a = filename(textures[i].path).toLowerCase();\n              let b = filename(test.name).toLowerCase();\n\n              if (a === b) {\n                customTest.instance.setTexture(i, test.resource);\n\n                this.tester.logger.info(`Injected ${test.name} as a custom texture for ${customTest.name}`);\n              }\n            }\n          } else {\n            // Inject this model into others.\n            let emitters = test.parser.particleEmitters;\n            let a = filename(customTest.name).toLowerCase();\n\n            for (let i = 0, l = emitters.length; i < l; i++) {\n              let b = filename(emitters[i].path).toLowerCase();\n\n              console.log('inject into other', a, b);\n            }\n\n            // Inject other models into this one.\n            emitters = customTest.parser.particleEmitters;\n            a = filename(customTest.name).toLowerCase();\n\n            for (let i = 0, l = emitters.length; i < l; i++) {\n              let b = filename(emitters[i].path).toLowerCase();\n\n              console.log('inject from other', a, b);\n            }\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/components/viewercontrols.js",
    "content": "import { DebugRenderMode } from '../../../src/viewer/viewer';\nimport Component from \"../../shared/component\";\nimport Toggle from \"../../shared/components/toggle\";\nimport { clearSelect, createElement } from \"../../shared/domutils\";\nimport { TEAM_COLORS } from \"./teamcolors\";\n\nexport default class ViewerControls extends Component {\n  constructor(viewer, options) {\n    super({ ...options, className: 'viewer-controls' });\n\n    this.viewer = viewer;\n\n    // Team colors.\n    let container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Team color:', container });\n\n    this.teamColorElement = createElement({ tagName: 'div', className: 'controls teamcolor', style: 'background-color:red', container });\n\n    this.teamColorsElement = createElement({\n      tagName: 'select', className: 'controls', onchange: () => {\n        this.viewer.setTeamColor(this.teamColorsElement.selectedIndex);\n\n        this.teamColorElement.style.backgroundColor = TEAM_COLORS[this.teamColorsElement.selectedIndex].color;\n      }, container\n    });\n\n    for (let teamColor of TEAM_COLORS) {\n      this.teamColorsElement.add(createElement({ tagName: 'option', textContent: teamColor.name }));\n    }\n\n    // Extents.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Show extents:', container });\n    this.extentElement = createElement({\n      tagName: 'select', className: 'controls', onchange: () => this.viewer.updateExtents(), container\n    });\n\n    this.extentElement.add(createElement({ tagName: 'option', textContent: 'No' }));\n    this.extentElement.add(createElement({ tagName: 'option', textContent: 'Box' }));\n    this.extentElement.add(createElement({ tagName: 'option', textContent: 'Sphere' }));\n    this.extentElement.add(createElement({ tagName: 'option', textContent: 'Both' }));\n    this.extentElement.selectedIndex = 0;\n\n    // Collision shapes.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Show collisions:', container });\n    this.collisionsToggle = new Toggle('No', 'Yes', (e) => {\n      this.viewer.showCollisions(e.clicked);\n    }, { className: 'controls', container });\n\n    // Run animations.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Run Animations:', container });\n    this.animationToggle = new Toggle('Yes', 'No', (e) => {\n      if (e.clicked) {\n        this.viewer.viewer.frameTime = 0;\n      } else {\n        this.viewer.viewer.frameTime = 1000 / 60;\n      }\n    }, { className: 'controls', container });\n\n    // Cycle animations.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Cycle Animations:', container });\n    this.cycleToggle = new Toggle('Yes', 'No', null, { className: 'controls', container });\n\n    // Select animations.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Animations:', container });\n    this.sequencesElement = createElement({\n      tagName: 'select', className: 'controls', onchange: () => {\n        if (!this.cycleToggle.clicked) {\n          this.cycleToggle.toggle();\n        }\n\n        this.viewer.viewer.clearEmittedObjects();\n\n        this.viewer.setSequence(this.sequencesElement.selectedIndex - 1);\n      }, container\n    });\n\n    // Frame.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Frame:', container });\n    this.frameElement = createElement({ container });\n\n    // Camera.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Camera:', container });\n    this.camerasElement = createElement({ tagName: 'select', className: 'controls', onchange: () => this.viewer.setCamera(this.camerasElement.selectedIndex - 1), container });\n\n    // Debug modes.\n    container = createElement({ container: this.container });\n\n    createElement({ textContent: 'Debug Mode:', container });\n    this.debugRenderSelect = createElement({\n      tagName: 'select', className: 'controls', onchange: () => {\n        // Somewhat hacky way to treat an enum.\n        this.viewer.viewer.debugRenderMode = this.debugRenderSelect.selectedIndex;\n      }, container\n    });\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'None' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Diffuse' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Normal map' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Occlusion' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Roughness' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Metallic' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'TC Factor' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Emissive' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'TexCoords' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Normals' }));\n    this.debugRenderSelect.add(createElement({ tagName: 'option', textContent: 'Tangents' }));\n  }\n\n  frame(frame) {\n    this.frameElement.textContent = `${Math.floor(frame)}`;\n  }\n\n  updateInstance(instance) {\n    clearSelect(this.sequencesElement);\n\n    this.sequencesElement.add(createElement({ tagName: 'option', textContent: 'None' }));\n\n    for (let sequence of instance.model.sequences) {\n      this.sequencesElement.add(createElement({ tagName: 'option', textContent: sequence.name }));\n    }\n\n    clearSelect(this.camerasElement);\n\n    this.camerasElement.add(createElement({ tagName: 'option', textContent: 'None' }));\n\n    for (let camera of instance.model.cameras) {\n      this.camerasElement.add(createElement({ tagName: 'option', textContent: camera.name }));\n    }\n  }\n\n  setSequence(sequence) {\n    if (this.sequencesElement.options.length === 1) {\n      sequence = -1;\n    }\n\n    this.sequencesElement.selectedIndex = sequence + 1;\n  }\n\n  setCamera(camera) {\n    this.camerasElement.selectedIndex = camera + 1;\n  }\n}\n"
  },
  {
    "path": "clients/sanitytest/index.css",
    "content": "﻿html,\nbody {\n    padding: 0;\n    margin: 0;\n    font-family: monaco, monospace;\n    font-size: 14px;\n}\n\n.client {\n    display: grid;\n    width: 100%;\n    height: 100vh;\n    grid-template-rows: auto 1fr;\n    grid-template-columns: 200px 0.9fr 1.1fr;\n    grid-template-areas: \"tests-header results-header viewer-and-mdl-header\" \"tests results viewer-and-mdl\";\n    padding: 5px;\n    grid-gap: 5px;\n    box-sizing: border-box;\n    color: #d8cba7;\n    background-color: black;\n}\n\n.client>* {\n    /* Anything inside a grid has min-height: auto and min-width: auto which means it expands to its size, we need to fix that. */\n    min-height: 0;\n    min-width: 0;\n}\n\n.welcome {\n    position: absolute;\n    left: 0;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    background-color: #404040;\n    box-sizing: border-box;\n}\n\n.welcome>* {\n    width: 50%;\n}\n\n.welcome * {\n    padding: 10px;\n}\n\nh1 {\n    font-size: 16px;\n    margin: 0;\n    padding: 0;\n    text-align: center;\n}\n\n.tests-header, .results-header, .viewer-and-mdl-header {\n    background-color: #151515;\n}\n\n.tests-header {\n    grid-area: tests-header;\n}\n\n.tests-body {\n    grid-area: tests;\n    display: grid;\n    grid-template-rows: auto 1fr;\n    grid-auto-columns: 1fr;\n    grid-template-areas: \"search-tests\" \"tests\";\n    grid-gap: 5px;\n    box-sizing: border-box;\n}\n\n.tests {\n    overflow-y: auto;\n    overflow-x: hidden;\n    overflow-wrap: break-word;\n    background-color: #202020;\n}\n\n.results-header {\n    grid-area: results-header;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 5px;\n}\n\n.results-body {\n    grid-area: results;\n    overflow-y: auto;\n    overflow-x: hidden;\n    overflow-wrap: break-word;\n    background-color: #202020;\n    padding: 5px;\n}\n\n.viewer-and-mdl-header {\n    grid-area: viewer-and-mdl-header;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 5px;\n}\n\n.viewer-and-mdl-body {\n    grid-area: viewer-and-mdl;\n}\n\n.viewer-and-console {\n    display: grid;\n    width: 100%;\n    height: 100%;\n    grid-template-rows: 1fr 200px;\n    grid-template-columns: 1fr;\n    grid-template-areas: \"viewer\" \"console\";\n    grid-gap: 5px;\n    box-sizing: border-box;\n}\n\n.viewer-and-console>* {\n    /* Anything inside a grid has min-height: auto and min-width: auto which means it expands to its size, we need to fix that. */\n    min-height: 0;\n    min-width: 0;\n}\n\n.viewer {\n    grid-area: viewer;\n\n    display: grid;\n    grid-auto-columns: 1fr;\n    grid-auto-rows: 1fr;\n    grid-template-areas: 'viewer-and-controls';\n}\n\n.viewer>* {\n    grid-area: viewer-and-controls;\n    min-height: 0;\n    min-width: 0;\n}\n\n.viewer-controls {\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n    z-index: 1;\n    pointer-events: none;\n    background-color: transparent;\n    padding: 5px;\n}\n\n.viewer-controls>* {\n    display: flex;\n    gap: 5px;\n}\n\n.controls {\n    pointer-events: all;\n}\n\n.console {\n    grid-area: console;\n    display: grid;\n    grid-template-rows: auto 1fr;\n    grid-gap: 5px;\n    box-sizing: border-box;\n}\n\n.console .tabs {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    padding: 2px;\n    gap: 5px;\n    background-color: #202020;\n}\n\n.console .tab-contents {\n    min-height: 0;\n    min-width: 0;\n    overflow-y: auto;\n    overflow-x: hidden;\n    overflow-wrap: break-word;\n    background-color: #202020;\n    padding: 5px;\n}\n\n.mdl {\n    width: 100%;\n    height: 100%;\n}\n\n.mdl-view {\n    display: grid;\n    width: 100%;\n    height: 100%;\n    grid-auto-rows: 1fr;\n    grid-template-columns: 40% 1fr;\n    grid-template-areas: \"mdl-structure mdl-source\";\n    grid-gap: 5px;\n    box-sizing: border-box;\n}\n\n.mdl-view>* {\n    /* Anything inside a grid has min-height: auto and min-width: auto which means it expands to its size, we need to fix that. */\n    min-height: 0;\n    min-width: 0;\n}\n\n.mdl-structure {\n    grid-area: mdl-structure;\n    overflow-y: auto;\n    background-color: #202020;\n    padding: 5px;\n}\n\n.mdl-source {\n    grid-area: mdl-source;\n    overflow-y: auto;\n    background-color: #202020;\n    padding: 5px;\n}\n\npre {\n    white-space: pre-wrap;\n    margin: 0;\n}\n\ntable {\n    border-spacing: 0;\n}\n\n.indent {\n    margin-left: 1em;\n}\n\n.bold {\n    font-weight: bold;\n}\n\n.log {\n    color: #777777;\n}\n\n.info {}\n\n.warning {\n    color: rgb(240, 204, 0);\n}\n\n.severe {\n    color: rgb(201, 110, 0);\n}\n\n.error {\n    color: rgb(200, 0, 0);\n}\n\n.unused {\n    color: rgb(80, 136, 2);\n}\n\n.clickable {\n    cursor: pointer;\n}\n\n.highlightable:hover {\n    background-color: #151515;\n}\n\n.highlighted {\n    background-color: #151515;\n    border-left: 3px solid #6f0d10;\n}\n\n.highlighted:hover {\n    background-color: #151515;\n}\n\n.center {\n    text-align: center;\n}\n\n.hidden {\n    display: none;\n}\n\n.padded {\n    padding: 5px;\n}\n\n.teamcolor {\n    width: 20px;\n    height: 20px;\n}\n\n.info_marker {\n    color: grey;\n    padding-left: 5px;\n    font-size: 9px;\n}\n\n.pointer {\n    cursor: pointer;\n}"
  },
  {
    "path": "clients/sanitytest/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>Sanity Test</title>\n    <meta charset=\"utf-8\" />\n    <link href=\"index.css\" rel=\"stylesheet\">\n</head>\n\n<body>\n    <script src=\"/clients/sanitytest.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/sanitytest/index.js",
    "content": "import SanityTester from './components/sanitytester';\n\nconst tester = new SanityTester(document.body);\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  tester.loadDataTransfer(e.dataTransfer);\n});\n\ntester.loadAPI(window.location.search);\n\n// For debugging etc.\nwindow.tester = tester;\n"
  },
  {
    "path": "clients/sanitytest/test.js",
    "content": "import { basename, extname } from \"../../src/common/path\";\nimport MdlxModel from '../../src/parsers/mdlx/model';\nimport { BlpImage } from '../../src/parsers/blp/image';\nimport { DdsImage } from '../../src/parsers/dds/image';\nimport TgaImage from '../../src/parsers/tga/image';\nimport TestResults from \"./components/testresults\";\nimport TestMeta from \"./components/testmeta\";\nimport MdlView from \"./components/mdlview\";\n\nexport default class Test {\n  constructor(tester, name, buffer, pathSolver) {\n    let ext = extname(name);\n    let isMdlx = ext === '.mdx' || ext === '.mdl';\n    let isBlp = ext === '.blp';\n    let isDds = ext === '.dds';\n\n    this.name = name;\n    this.shortName = basename(name);\n    this.parsingError = false;\n    this.results = null;\n    this.mdl = null;\n    this.pathSolver = pathSolver;\n\n    // Loaded and set by the viewer component.\n    this.resource = null;\n    this.instance = null;\n    this.boundingBox = null;\n    this.boundingSphere = null;\n    // this.cameras = [];\n    this.collisions = [];\n\n    if (isMdlx) {\n      this.parser = new MdlxModel();\n    } else if (isBlp) {\n      this.parser = new BlpImage();\n    } else if (isDds) {\n      this.parser = new DdsImage();\n    } else {\n      this.parser = new TgaImage();\n    }\n\n    try {\n      this.parser.load(buffer);\n    } catch (e) {\n      this.parsingError = true;\n\n      tester.logger.error(`Failed to parse ${name}: ${e}. The test will attempt to run on whatever data loaded`);\n    }\n\n    this.results = new TestResults(this.parser);\n\n    if (isMdlx) {\n      this.mdl = new MdlView(this.parser);\n    }\n\n    this.meta = new TestMeta(this.shortName, this.parsingError, this.results.results, { onclick: () => tester.render(this) });\n  }\n\n  show() {\n    this.meta.highlight();\n\n    if (this.results) {\n      this.results.show();\n    }\n\n    if (this.mdl) {\n      this.mdl.show();\n    }\n  }\n\n  hide() {\n    this.meta.normal();\n\n    if (this.results) {\n      this.results.hide();\n    }\n\n    if (this.mdl) {\n      this.mdl.hide();\n    }\n  }\n}"
  },
  {
    "path": "clients/shared/camera.js",
    "content": "import { vec3, quat } from 'gl-matrix';\n\n// Backwards compat with existing clients.\nexport function setupCamera(scene, options = {}) {\n  return new SimpleOrbitCamera(scene, options);\n}\n\nconst vecHeap = vec3.create();\nconst vecHeap2 = vec3.create();\nconst quatHeap = quat.create();\nconst twistHeap = new Float32Array(1);\n\n// Get the vector length between two touches.\nfunction getTouchesLength(touch1, touch2) {\n  let dx = touch2.clientX - touch1.clientX;\n  let dy = touch2.clientY - touch1.clientY;\n\n  return Math.sqrt(dx * dx + dy * dy);\n}\n\n// Touch modes.\nconst TOUCH_MODE_INVALID = -1;\nconst TOUCH_MODE_ROTATE = 0;\nconst TOUCH_MODE_ZOOM = 1;\n\n// An orbit camera setup example.\n// Left mouse button controls the orbit itself.\n// The right mouse button allows to move the camera and the point it's looking at on the XY plane.\n// Scrolling zooms in and out.\nexport class SimpleOrbitCamera {\n  constructor(scene, options = {}) {\n    this.scene = scene;\n    this.canvas = scene.viewer.canvas;\n    this.camera = scene.camera;\n    // Movement per pixel of movement.\n    this.moveSpeed = options.moveSpeed || 2;\n    // Rotation in radians per pixel of movement.\n    this.rotationSpeed = options.rotationSpeed || (Math.PI / 180);\n    // Zoom factor per scroll.\n    this.zoomFactor = options.zoomFactor || 0.1;\n    this.horizontalAngle = options.horizontalAngle || Math.PI / 2;\n    this.verticalAngle = options.verticalAngle || Math.PI / 4;\n    this.distance = options.distance || 500;\n    this.position = options.position || vec3.create();\n    // What the camera is looking at.\n    this.target = options.target || vec3.create();\n    // The twist angle of the camera, which affects the \"up\" direction.\n    // For example, a twist of 180 degrees, i.e. PI, will flip everything upside down.\n    this.twist = options.twist || 0;\n    // Mouse.\n    this.mouse = { buttons: [false, false, false], x: 0, y: 0, x2: 0, y2: 0 };\n    // Touches.\n    this.touchMode = TOUCH_MODE_INVALID;\n    this.touches = [];\n    this.instance = null;\n    this.onManualChange = options.onManualChange || null;\n    this.fov = options.fov || Math.PI / 4;\n    this.nearClipPlane = options.nearClipPlane || 1;\n    this.farClipPlane = options.farClipPlane || 200000;\n\n    this.update();\n\n    window.addEventListener('resize', (e) => this.onResize());\n    setTimeout(() => this.onResize(), 0);\n\n    // Disable the context menu when right-clicking.\n    this.canvas.addEventListener('contextmenu', (e) => e.preventDefault());\n\n    this.canvas.addEventListener('selectstart', (e) => e.preventDefault());\n\n    // Track mouse clicks.\n    this.canvas.addEventListener('mousedown', (e) => {\n      e.preventDefault();\n\n      this.mouse.buttons[e.button] = true;\n    });\n\n    // And mouse unclicks.\n    // On the whole document rather than the canvas to stop annoying behavior when moving the mouse out of the canvas.\n    document.addEventListener('mouseup', (e) => {\n      e.preventDefault();\n\n      this.mouse.buttons[e.button] = false;\n    });\n\n    // Handle rotating and moving the camera when the mouse moves.\n    window.addEventListener('mousemove', (e) => {\n      this.mouse.x2 = this.mouse.x;\n      this.mouse.y2 = this.mouse.y;\n      this.mouse.x = e.clientX;\n      this.mouse.y = e.clientY;\n\n      let dx = this.mouse.x - this.mouse.x2;\n      let dy = this.mouse.y - this.mouse.y2;\n\n      if (this.mouse.buttons[0]) {\n        this.rotate(dx, dy);\n      }\n\n      if (this.mouse.buttons[2]) {\n        this.move(-dx, dy);\n      }\n    });\n\n    // Handle zooming when the mouse scrolls.\n    this.canvas.addEventListener('wheel', (e) => {\n      e.preventDefault();\n\n      let deltaY = e.deltaY;\n\n      if (e.deltaMode === 1) {\n        deltaY = deltaY / 3 * 100;\n      }\n\n      this.zoom(deltaY / 100);\n    });\n\n    // Listen to touches.\n    // Supports 1 or 2 touch points.\n    this.canvas.addEventListener('touchstart', (e) => {\n      e.preventDefault();\n\n      let targetTouches = e.targetTouches;\n\n      if (targetTouches.length === 1) {\n        this.touchMode = TOUCH_MODE_ROTATE;\n      } else if (targetTouches.length == 2) {\n        this.touchMode = TOUCH_MODE_ZOOM;\n      } else {\n        this.touchMode = TOUCH_MODE_INVALID;\n      }\n\n      this.touches.length = 0;\n      this.touches.push(...targetTouches);\n    });\n\n    this.canvas.addEventListener('touchend', (e) => {\n      e.preventDefault();\n\n      this.touchMode = TOUCH_MODE_INVALID;\n    });\n\n    this.canvas.addEventListener('touchcancel', (e) => {\n      e.preventDefault();\n\n      this.touchMode = TOUCH_MODE_INVALID;\n    });\n\n    // Rotate or zoom based on the touch mode.\n    this.canvas.addEventListener('touchmove', (e) => {\n      e.preventDefault();\n\n      let targetTouches = e.targetTouches;\n\n      if (this.touchMode === TOUCH_MODE_ROTATE) {\n        let oldTouch = this.touches[0];\n        let newTouch = targetTouches[0];\n        let dx = newTouch.clientX - oldTouch.clientX;\n        let dy = newTouch.clientY - oldTouch.clientY;\n\n        this.rotate(dx, dy);\n      } else if (this.touchMode === TOUCH_MODE_ZOOM) {\n        let len1 = getTouchesLength(this.touches[0], this.touches[1]);\n        let len2 = getTouchesLength(targetTouches[0], targetTouches[1]);\n\n        this.zoom((len1 - len2) / 50);\n      }\n\n      this.touches.length = 0;\n      this.touches.push(...targetTouches);\n    });\n  }\n\n  update() {\n    if (this.instance) {\n      let instance = this.instance;\n      let mdxCamera = instance.model.cameras[0];\n\n      mdxCamera.getTranslation(vecHeap, instance.sequence, instance.frame, instance.counter);\n      vec3.add(vecHeap, vecHeap, mdxCamera.position);\n\n      mdxCamera.getTargetTranslation(vecHeap2, instance.sequence, instance.frame, instance.counter);\n      vec3.add(vecHeap2, vecHeap2, mdxCamera.targetPosition);\n\n      mdxCamera.getRotation(twistHeap, instance.sequence, instance.frame, instance.counter);\n      this.twist = twistHeap[0];\n\n      // Change to world space in case the instance was moved in any way.\n      // I am not sure how well this will handle scales, twists, and other things.\n      vec3.transformMat4(vecHeap, vecHeap, instance.worldMatrix);\n      vec3.transformMat4(vecHeap2, vecHeap2, instance.worldMatrix);\n\n      this.moveToAndFace(vecHeap, vecHeap2);\n    } else {\n      this.updateInternalCamera();\n    }\n  }\n\n  // Move the camera and the target on the XY plane.\n  move(x, y) {\n    let dirX = this.camera.directionX;\n    let dirY = this.camera.directionY;\n    let w = this.canvas.width;\n    let h = this.canvas.height;\n    let aspect = w / h;\n\n    let sw = (x / w) * this.distance * aspect;\n    let sh = (y / h) * this.distance;\n\n    vec3.add(this.target, this.target, vec3.scale(vecHeap, vec3.normalize(vecHeap, vec3.set(vecHeap, dirX[0], dirX[1], 0)), sw));\n    vec3.add(this.target, this.target, vec3.scale(vecHeap, vec3.normalize(vecHeap, vec3.set(vecHeap, dirY[0], dirY[1], 0)), sh));\n\n    this.manualChange();\n  }\n\n  // Rotate the camera around the target.\n  rotate(x, y) {\n    this.horizontalAngle -= x * this.rotationSpeed;\n    this.verticalAngle -= y * this.rotationSpeed;\n\n    this.manualChange();\n  }\n\n  // Zoom the camera by changing the distance from the target.\n  zoom(factor) {\n    this.distance = Math.max(1, this.distance * (1 + factor * this.zoomFactor));\n\n    this.manualChange();\n  }\n\n  manualChange() {\n    this.updateInternalCamera();\n\n    if (this.instance) {\n      this.instance = null;\n\n      if (this.onManualChange) {\n        this.onManualChange();\n      }\n    }\n  }\n\n  // Resize the canvas automatically and update the camera.\n  onResize() {\n    let width = Math.max(this.canvas.clientWidth, 1);\n    let height = Math.max(this.canvas.clientHeight, 1);\n\n    this.canvas.width = width;\n    this.canvas.height = height;\n\n    this.scene.viewport[2] = width;\n    this.scene.viewport[3] = height;\n\n    this.camera.perspective(this.fov, width / height, this.nearClipPlane, this.farClipPlane);\n  }\n\n  moveToAndFace(position, target) {\n    vec3.sub(vecHeap, position, target);\n\n    let r = vec3.length(vecHeap);\n    let theta = Math.atan2(vecHeap[1], vecHeap[0]);\n    let phi = Math.acos(vecHeap[2] / r);\n\n    vec3.copy(this.target, target);\n\n    this.verticalAngle = phi;\n    this.horizontalAngle = theta + Math.PI / 2;\n    this.distance = r;\n\n    this.updateInternalCamera();\n  }\n\n  updateInternalCamera() {\n    // Limit the vertical angle so it doesn't flip.\n    // Since the camera uses a quaternion, flips don't matter to it, but this feels better.\n    this.verticalAngle = Math.min(Math.max(0.01, this.verticalAngle), Math.PI - 0.01);\n\n    quat.identity(quatHeap);\n    quat.rotateZ(quatHeap, quatHeap, this.horizontalAngle);\n    quat.rotateX(quatHeap, quatHeap, this.verticalAngle);\n\n    vec3.set(this.position, 0, 0, 1);\n    vec3.transformQuat(this.position, this.position, quatHeap);\n    vec3.scale(this.position, this.position, this.distance);\n    vec3.add(this.position, this.position, this.target);\n\n    let twist = this.twist - Math.PI / 2;\n    vec3.set(vecHeap, 0, -Math.cos(twist), -Math.sin(twist));\n\n    this.camera.moveToAndFace(this.position, this.target, vecHeap);\n  }\n\n  applyInstanceCamera(instance) {\n    this.instance = instance;\n    this.fov = instance.model.cameras[0].fieldOfView;\n\n    this.onResize();\n\n    this.update();\n  }\n}\n"
  },
  {
    "path": "clients/shared/component.js",
    "content": "import { createElement, hideElement, showElement } from './domutils';\n\nexport default class Component {\n  constructor(options) {\n    this.container = createElement({ ...options, component: this });\n  }\n\n  hide() {\n    hideElement(this.container);\n  }\n\n  show() {\n    showElement(this.container);\n  }\n\n  highlight() {\n    this.container.classList.add('highlighted');\n  }\n\n  normal() {\n    this.container.classList.remove('highlighted');\n  }\n}\n"
  },
  {
    "path": "clients/shared/components/toggle.js",
    "content": "import Component from \"../component\";\n\nexport default class Toggle extends Component {\n  constructor(offName, onName, callback, options) {\n    super({ ...options, tagName: 'button', textContent: offName, onclick: () => this.toggle() });\n\n    this.offName = offName;\n    this.onName = onName;\n    this.callback = callback;\n    this.clicked = false;\n  }\n\n  toggle() {\n    this.clicked = !this.clicked;\n\n    if (this.clicked) {\n      this.container.textContent = this.onName;\n    } else {\n      this.container.textContent = this.offName;\n    }\n\n    if (this.callback) {\n      this.callback(this);\n    }\n  }\n}\n"
  },
  {
    "path": "clients/shared/domutils.js",
    "content": "export function createElement(options) {\n  let tagName = 'div';\n\n  if (options && options.tagName) {\n    tagName = options.tagName;\n  }\n\n  let element = document.createElement(tagName);\n\n  if (options) {\n    if (options.style) {\n      element.style = options.style;\n    }\n\n    if (options.className) {\n      element.className = options.className;\n    }\n\n    if (options.textContent) {\n      element.textContent = options.textContent;\n    }\n\n    if (options.placeholder) {\n      element.placeholder = options.placeholder;\n    }\n\n    if (options.readonly) {\n      element.readonly = true;\n    }\n\n    if (options.href) {\n      element.href = options.href;\n    }\n\n    if (options.target) {\n      element.target = options.target;\n    }\n\n    if (options.title) {\n      element.title = options.title;\n    }\n\n    if (options.onclick) {\n      element.addEventListener('click', (e) => options.onclick(e, options.component));\n    }\n\n    if (options.onchange) {\n      element.addEventListener('change', (e) => options.onchange(e, options.component));\n    }\n\n    if (options.oninput) {\n      element.addEventListener('input', (e) => options.oninput(e, options.component));\n    }\n\n    if (options.container) {\n      options.container.appendChild(element);\n    }\n  }\n\n  return element;\n}\n\nexport function hideElement(element) {\n  element.classList.add('hidden');\n}\n\nexport function showElement(element) {\n  element.classList.remove('hidden');\n}\n\nexport function scrollToBottom(element) {\n  element.scrollTop = element.scrollHeight;\n}\n\nexport function scrolledToBottom(element) {\n  return element.scrollHeight - element.clientHeight === element.scrollTop;\n}\n\nexport function addTextToRow(row, text) {\n  let cell = row.insertCell();\n\n  cell.appendChild(document.createTextNode(text));\n\n  return cell;\n}\n\nexport function addElementToRow(row, element) {\n  let cell = row.insertCell();\n\n  cell.appendChild(element);\n\n  return cell;\n}\n\nexport function clearSelect(element) {\n  for (let l = element.options.length - 1, i = l; i >= 0; i--) {\n    element.remove(i);\n  }\n}\n"
  },
  {
    "path": "clients/shared/localorhive.js",
    "content": "import urlWithParams from '../../src/common/urlwithparams';\n\nexport default function localOrHive(src, params) {\n  src = src.toLowerCase();\n\n  if (window.location.hostname === '127.0.0.1') {\n    return urlWithParams(`${window.location.origin}/assets?path=${src}`, params);\n  } else {\n    // if (params && (params.reforged || params.sc2)) {\n    return `https://www.hiveworkshop.com/casc-contents?path=${src}`;\n    // } else {\n    //return `https://www.hiveworkshop.com/data/static_assets/mpq/tft/${src}`;\n    // }\n  }\n}\n"
  },
  {
    "path": "clients/shared/utils.js",
    "content": "// Returns a promise that will resolve in the next VM event loop step.\n// Used to force the VM to wait, allowing the DOM to update between heavy operations.\nexport function aFrame() {\n  return new Promise((resolve) => {\n    setTimeout(() => resolve(), 0);\n  });\n}\n\nexport async function getAllFileEntries(dataTransfer) {\n  const items = dataTransfer.items;\n  let files = [];\n  let queue = [];\n\n  for (let i = 0; i < items.length; i++) {\n    queue.push(items[i].webkitGetAsEntry());\n  }\n\n  while (queue.length > 0) {\n    let entry = queue.shift();\n\n    if (entry.isFile) {\n      files.push(entry);\n    } else if (entry.isDirectory) {\n      queue.push(...await readAllDirectoryEntries(entry.createReader()));\n    }\n  }\n\n  return files;\n}\n\nasync function readAllDirectoryEntries(directoryReader) {\n  let entries = [];\n  let readEntries = await readEntriesPromise(directoryReader);\n\n  while (readEntries.length > 0) {\n    entries.push(...readEntries);\n\n    readEntries = await readEntriesPromise(directoryReader);\n  }\n\n  return entries;\n}\n\nasync function readEntriesPromise(directoryReader) {\n  try {\n    return await new Promise((resolve, reject) => {\n      directoryReader.readEntries(resolve, reject);\n    });\n  } catch (err) {\n    console.log(err);\n  }\n}\n\nexport async function readFile(file, asText) {\n  return new Promise((resolve) => {\n    let reader = new FileReader();\n\n    reader.addEventListener('loadend', (e) => {\n      resolve(e.target.result);\n    });\n\n    if (asText) {\n      reader.readAsText(file);\n    } else {\n      reader.readAsArrayBuffer(file);\n    }\n  });\n}\n\nexport async function readEntry(entry, asText) {\n  return new Promise((resolve) => entry.file(async (file) => resolve(await readFile(file, asText))));\n}\n"
  },
  {
    "path": "clients/tests/README.md",
    "content": "The unit tester.\nBy definition, a test is comprised of an input scene, defined by the resources it needs and the setup script, and the output is the rendered image.\nThe output image is compared against a previously generated image, using the same setup, which was created when the viewer was deemed to work \"correctly\".\n"
  },
  {
    "path": "clients/tests/components/unittester.js",
    "content": "import { version } from '../../../src/version';\nimport UnitTester from '../unittester';\nimport Component from '../../shared/component';\nimport { createElement, showElement, hideElement, addElementToRow, addTextToRow } from '../../shared/domutils';\nimport { wc3Solver } from '../solvers';\nimport { mdxTests } from '../tests/mdx';\nimport { mdxPrimitivesTests } from '../tests/mdxprimitives';\nimport { m3Tests } from '../tests/m3';\nimport { baseTests } from '../tests/base';\n\nexport default class UnitTesterComponent extends Component {\n  constructor(parentElement) {\n    super();\n\n    this.mismatchPercentageForFailure = 1;\n    this.passed = 0;\n\n    let unitTester = new UnitTester(wc3Solver);\n\n    unitTester.add(mdxTests);\n    unitTester.add(mdxPrimitivesTests);\n    unitTester.add(m3Tests);\n    unitTester.add(baseTests);\n\n    this.unitTester = unitTester;\n\n    createElement({ tagName: 'b', textContent: `Viewer version ${version}`, container: this.container });\n    createElement({ tagName: 'hr', container: this.container });\n\n    let controls = createElement({ container: this.container });\n\n    this.runButton = createElement({ tagName: 'button', textContent: 'Run', onclick: () => this.run(), container: controls });\n    this.downloadButton = createElement({ tagName: 'button', textContent: 'Download', onclick: () => this.download(), container: controls });\n\n    createElement({ tagName: 'hr', container: this.container });\n\n    this.resultsContainer = createElement({ className: 'hidden', container: this.container });\n\n    this.resultsMeta = createElement({ container: this.resultsContainer });\n\n    let resultsTable = createElement({ tagName: 'table', container: this.resultsContainer });\n\n    this.tbody = resultsTable.createTBody();\n\n    let thead = resultsTable.createTHead();\n\n    let header = thead.insertRow();\n    addElementToRow(header, createElement({ className: 'bold', textContent: 'Name' }));\n    this.headerResult = addElementToRow(header, createElement({ className: 'bold', textContent: 'Result' }));\n    this.headerNew = addElementToRow(header, createElement({ className: 'bold', textContent: 'New' }));\n    this.headerOld = addElementToRow(header, createElement({ className: 'bold', textContent: 'Old' }));\n\n    parentElement.appendChild(this.container);\n  }\n\n  clear() {\n    let section = this.tbody;\n\n    for (let l = section.rows.length - 1, i = l; i >= 0; i--) {\n      section.deleteRow(i);\n    }\n  }\n\n  result(result) {\n    let row = this.tbody.insertRow();\n\n    addTextToRow(row, result.name);\n\n    if (result.mismatchPercentage !== undefined) {\n      let passed = result.mismatchPercentage < this.mismatchPercentageForFailure;\n\n      if (passed) {\n        this.passed += 1;\n      }\n\n      let total = this.unitTester.tests.length;\n      let ran = this.tbody.rows.length;\n\n      let className = 'passed';\n\n      if (this.passed < ran) {\n        className = 'failed';\n      }\n\n      this.resultsMeta.className = className;\n      this.resultsMeta.textContent = `${this.passed} / ${ran} (${total} total)`;\n\n      let name = passed ? 'passed' : 'failed';\n\n      addElementToRow(row, createElement({ className: name, textContent: name }))\n\n      if (result.testImage) {\n        let wrapper = createElement({ tagName: 'a', className: 'center', href: result.testImage.src, target: '_blank' });\n\n        wrapper.appendChild(result.testImage);\n\n        addElementToRow(row, wrapper);\n      } else {\n        addTextToRow(row, '');\n      }\n\n      if (result.comparisonImage) {\n        let wrapper = createElement({ tagName: 'a', className: 'center', href: result.comparisonImage.src, target: '_blank' });\n\n        wrapper.appendChild(result.comparisonImage);\n\n        addElementToRow(row, wrapper);\n      } else {\n        addTextToRow(row, '');\n      }\n    }\n  }\n\n  run() {\n    this.passed = 0;\n\n    this.runButton.disabled = true;\n    this.downloadButton.disabled = true;\n\n    this.clear();\n\n    // In case they were hidden.\n    showElement(this.headerResult);\n    showElement(this.headerNew);\n    showElement(this.headerOld);\n\n    // In case it was hidden.\n    showElement(this.resultsContainer);\n\n    this.unitTester.test((entry) => {\n      if (!entry.done) {\n        let result = entry.value;\n\n        if (result.result < 1) {\n          this.passed++;\n        }\n\n        this.result(result);\n      } else {\n        this.runButton.disabled = false;\n        this.downloadButton.disabled = false;\n      }\n    });\n  }\n\n  download() {\n    this.passed = 0;\n\n    this.runButton.disabled = true;\n    this.downloadButton.disabled = true;\n\n    this.clear();\n\n    // In case they were shown.\n    hideElement(this.headerResult);\n    hideElement(this.headerNew);\n    hideElement(this.headerOld);\n\n    // In case it was hidden.\n    showElement(this.resultsContainer);\n\n    let zip = new JSZip();\n\n    this.unitTester.download((entry) => {\n      if (!entry.done) {\n        let result = entry.value;\n\n        this.result(result);\n\n        if (result.blob) {\n          this.passed++;\n\n          zip.file(`${result.name}.png`, result.blob);\n        } else {\n          console.log(`Skipping ${result.name} because it has no blob`);\n        }\n      } else {\n        this.runButton.disabled = false;\n        this.downloadButton.disabled = false;\n\n        zip.generateAsync({ type: 'blob' })\n          .then((blob) => {\n            saveAs(blob, `compare_${version}.zip`);\n          });\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "clients/tests/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n  <title>Unit Tests</title>\n  <meta charset=\"utf-8\" />\n\n  <style>\n    button {\n      margin-left: 2px;\n      margin-right: 2px;\n    }\n\n    td {\n      padding-left: 4px;\n      padding-right: 4px;\n    }\n\n    .center {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    img {\n      width: 20px;\n      height: 20px;\n    }\n\n    .bold {\n      font-weight: bold;\n    }\n\n    .passed {\n      color: green;\n    }\n\n    .failed {\n      color: red;\n    }\n\n    .hidden {\n      display: none;\n    }\n  </style>\n</head>\n\n<body>\n  <script src=\"../thirdparty/jszip.min.js\"></script>\n  <script src=\"../thirdparty/filesaver.js\"></script>\n  <script src=\"/clients/tests.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/tests/index.js",
    "content": "import UnitTester from './components/unittester';\n\nconst tester = new UnitTester(document.body);\n\n// For debugging etc.\nwindow.tester = tester;\n"
  },
  {
    "path": "clients/tests/solvers.js",
    "content": "import localOrHive from \"../shared/localorhive\";\n\nexport const wc3Solver = (path, params) => {\n  path = localOrHive(path, params);\n\n  // GREAT JOB BLIZZARD. AWESOME PATCHES.\n  if (path.endsWith('orcbloodriderlesswyvernrider.mdx') && path.includes('hiveworkshop')) {\n    path = path.replace('orcbloodriderlesswyvernrider.mdx', 'ordbloodriderlesswyvernrider.mdx');\n  }\n\n  return path;\n};\n\nexport const sc2Solver = localOrHive;\n"
  },
  {
    "path": "clients/tests/tests/base.js",
    "content": "import { wc3Solver, sc2Solver } from \"../solvers\";\n\nexport const baseTests = {\n  name: 'base',\n  tests: [\n    {\n      name: 'attachments',\n      load(viewer) {\n        return [\n          viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver),\n          viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver),\n        ];\n      },\n      test(viewer, scene, camera, models) {\n        let mountainKing = models[0];\n        let baneling = models[1];\n\n        camera.moveToAndFace([450, 0, 160], [0, 0, 160], [0, 0, 1]);\n\n        let instance1 = mountainKing.addInstance().setSequence(1);\n        let instance3 = mountainKing.addInstance().setSequence(1);\n        let instance5 = mountainKing.addInstance().setSequence(1);\n\n        let instance2 = baneling.addInstance().setSequence(0).uniformScale(100);\n        let instance4 = baneling.addInstance().setSequence(0).uniformScale(100);\n        let instance6 = baneling.addInstance().setSequence(0).uniformScale(100);\n\n        instance2.setParent(instance1.getAttachment(3));\n        instance3.setParent(instance2.getAttachment(4));\n        instance4.setParent(instance3.getAttachment(3));\n        instance5.setParent(instance4.getAttachment(4));\n        instance6.setParent(instance5.getAttachment(3));\n\n        scene.addInstance(instance1);\n        scene.addInstance(instance2);\n        scene.addInstance(instance3);\n        scene.addInstance(instance4);\n        scene.addInstance(instance5);\n        scene.addInstance(instance6);\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": "clients/tests/tests/m3.js",
    "content": "import { sc2Solver } from \"../solvers\";\n\nexport const m3Tests = {\n  name: 'm3',\n  tests: [\n    {\n      name: 'base',\n      load(viewer) {\n        return viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 5, 100], [0, 5, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().uniformScale(50);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'sequence',\n      load(viewer) {\n        return viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 5, 100], [0, 5, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().uniformScale(50).setSequence(0);\n\n        instance.frame = 800;\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'team-color',\n      load(viewer) {\n        return viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 5, 100], [0, 5, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().uniformScale(50).setTeamColor(1);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'vertex-color',\n      load(viewer) {\n        return viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 5, 100], [0, 5, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().uniformScale(50).setVertexColor([1, 0, 0, 1]);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'vertex-and-team-colors',\n      load(viewer) {\n        return viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 5, 100], [0, 5, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().uniformScale(50).setVertexColor([1, 0, 0, 1]).setTeamColor(1);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'texture-overriding',\n      load(viewer) {\n        return viewer.load('Assets/Units/Zerg/Baneling/Baneling.m3', sc2Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 5, 140], [0, 5, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().uniformScale(50).move([25, 0, 0]);\n        let instance2 = model.addInstance().uniformScale(50).move([-25, 0, 0]);\n        let material = model.materials[1][0];\n\n        instance.setTexture(0, 0, material.layers[10].texture.texture);\n\n        scene.addInstance(instance);\n        scene.addInstance(instance2);\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": "clients/tests/tests/mdx.js",
    "content": "import { quat } from \"gl-matrix\";\nimport { wc3Solver } from \"../solvers\";\n\nexport const mdxTests = {\n  name: 'mdx',\n  tests: [\n    {\n      name: 'base',\n      load(viewer) {\n        return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([150, 0, 45], [0, 0, 45], [0, 0, 1]);\n\n        let instance = model.addInstance();\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'sequence',\n      load(viewer) {\n        return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([150, 0, 45], [0, 0, 45], [0, 0, 1]);\n\n        let instance = model.addInstance().setSequence(0);\n\n        instance.frame = 800;\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'team-color',\n      load(viewer) {\n        return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([150, 0, 45], [0, 0, 45], [0, 0, 1]);\n\n        let instance = model.addInstance().setTeamColor(1);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'vertex-color',\n      load(viewer) {\n        return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([150, 0, 45], [0, 0, 45], [0, 0, 1]);\n\n        let instance = model.addInstance().setVertexColor([1, 0, 0, 1]);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'vertex-and-team-colors',\n      load(viewer) {\n        return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([150, 0, 45], [0, 0, 45], [0, 0, 1]);\n\n        let instance = model.addInstance().setVertexColor([1, 0, 0, 1]).setTeamColor(1);\n\n        scene.addInstance(instance);\n      },\n    },\n\n    {\n      name: 'texture-animation',\n      tests: [\n        {\n          name: 'translation-and-slot',\n          load(viewer) {\n            return viewer.load('Units/Human/WaterElemental/WaterElemental.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([200, 0, 85], [0, 0, 85], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(0);\n\n            instance.frame = 800;\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'rotation',\n          load(viewer) {\n            return viewer.load('UI/Feedback/Cooldown/UI-Cooldown-Indicator.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([40, 40, 100], [40, 40, 0], [0, 1, 0]);\n\n            let instance = model.addInstance().setSequence(0).uniformScale(2100).setSequenceLoopMode(2);\n\n            instance.frame = 600;\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'scale',\n          load(viewer) {\n            return viewer.load('Abilities/Spells/Other/Volcano/Volcano.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([400, 0, 50], [0, 0, 50], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(1);\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'billboarding',\n      tests: [\n        {\n          name: 'standard',\n          load(viewer) {\n            return viewer.load('Units/Creeps/Gnoll/Gnoll.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([120, -50, 75], [0, 0, 40], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(1).setSequenceLoopMode(2);\n\n            // Rotate also the instance, to be sure billboarding works in all cases.\n            // It happened in a past implementation that billboaring worked as long as the instance isn't rotated.\n            // Needless to say, it took a long time to find that bug.\n            instance.rotate(quat.setAxisAngle([], [0, 1, 0], -0.785398));\n\n            instance.frame = 800;\n\n            scene.addInstance(instance);\n\n            viewer.update();\n          },\n        },\n\n        {\n          name: 'x-axis',\n          load(viewer) {\n            return viewer.load('SharedModels/NEBirth.MDX', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([200, -200, 400], [0, 0, 300], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(0).rotate(quat.setAxisAngle([], [0, 0, 1], -0.785398));\n\n            instance.frame += 30000;\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'attachment-model',\n      load(viewer) {\n        return viewer.load('Buildings/Undead/HauntedMine/HauntedMine.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([0, 0, 620], [0, 0, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().setSequence(0);\n\n        scene.addInstance(instance);\n\n        instance.frame = 20000;\n\n        // update() is used here, because when an attachment becomes visible for the first time, the parent instance resets its sequence.\n        // If the attachment's frame was set without first updating, it will just get reset to the sequence's beginning.\n        viewer.update();\n\n        let attachment = instance.attachments[0].internalInstance;\n\n        attachment.frame = instance.frame;\n      },\n    },\n\n    {\n      name: 'particle-emitter',\n      load(viewer) {\n        return viewer.load('Units/Creeps/AzureDragon/AzureDragon.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([50, -35, 250], [50, -35, 0], [0, 1, 0]);\n\n        let instance = model.addInstance().setSequence(5);\n\n        scene.addInstance(instance);\n\n        for (let i = 0; i < 30; i++) {\n          viewer.update();\n        }\n      },\n    },\n\n    {\n      name: 'particle-2-emitter',\n      tests: [\n        {\n          name: 'base',\n          load(viewer) {\n            return viewer.load('Units/Creeps/AzureDragon/AzureDragon.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([300, 0, -20], [0, 0, -20], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(1);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 90; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'squirt',\n          load(viewer) {\n            return viewer.load('Abilities/Spells/Human/Thunderclap/ThunderclapCaster.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([0, 0, 250], [0, 0, 0], [0, 1, 0]);\n\n            let instance = model.addInstance().setSequence(1);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 4; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'line-emitter',\n          load(viewer) {\n            return viewer.load('Abilities/Spells/Human/Thunderclap/ThunderclapCaster.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([200, 0, 50], [0, 0, 50], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(1);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 4; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'tail',\n          load(viewer) {\n            return viewer.load('Doodads/Dungeon/Props/ForceWall/ForceWall.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([700, 0, 100], [0, 0, 100], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(0).setSequenceLoopMode(2);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 100; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'repeat',\n          load(viewer) {\n            return viewer.load('Doodads/Cinematic/EnergyField/EnergyField.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([0, 600, 100], [0, 0, 50], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(0).setSequenceLoopMode(2);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 50; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'xy-quad',\n          load(viewer) {\n            return viewer.load('Units/Orc/SpiritWyvern/SpiritWyvern.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([0, 300, 100], [0, 0, 50], [0, 0, 1]);\n\n            let instance = model.addInstance().setSequence(9).setSequenceLoopMode(2);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 50; i++) {\n              viewer.update();\n            }\n          },\n        },\n      ],\n\n    },\n\n    {\n      name: 'ribbon-emitter',\n      load(viewer) {\n        return viewer.load('Units/Human/HeroPaladin/HeroPaladin.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([225, -45, 70], [0, 0, 70], [0, 0, 1]);\n\n        let instance = model.addInstance().setSequence(4).setSequenceLoopMode(2);\n\n        scene.addInstance(instance);\n\n        for (let i = 0; i < 24; i++) {\n          viewer.update();\n        }\n      },\n    },\n\n    {\n      name: 'event-object',\n      tests: [\n        {\n          name: 'spn',\n          load(viewer) {\n            return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([-40, 0, 100], [-40, 0, 0], [0, 1, 0]);\n\n            let instance = model.addInstance().setSequence(9);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 50; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'spl',\n          load(viewer) {\n            return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([0, 0, 80], [0, 0, 0], [0, 1, 0]);\n\n            let instance = model.addInstance().setSequence(9);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 170; i++) {\n              viewer.update();\n            }\n          },\n        },\n\n        {\n          name: 'ubr',\n          load(viewer) {\n            return viewer.load('Abilities/Spells/Human/Thunderclap/ThunderclapCaster.mdx', wc3Solver);\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([0, 0, 500], [0, 0, 0], [0, 1, 0]);\n\n            let instance = model.addInstance().setSequence(1);\n\n            scene.addInstance(instance);\n\n            for (let i = 0; i < 20; i++) {\n              viewer.update();\n            }\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'texture-overriding',\n      load(viewer) {\n        return viewer.load('Units/Human/Footman/Footman.mdx', wc3Solver);\n      },\n      test(viewer, scene, camera, model) {\n        camera.moveToAndFace([220, 0, 45], [0, 0, 45], [0, 0, 1]);\n\n        let instance = model.addInstance().move([0, 40, 0]);\n        let instance2 = model.addInstance().move([0, -40, 0]);\n\n        instance.setTexture(0, model.textures[2].texture);\n\n        scene.addInstance(instance);\n        scene.addInstance(instance2);\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": "clients/tests/tests/mdxprimitives.js",
    "content": "import { quat } from \"gl-matrix\";\nimport createPrimitive from \"../../../src/utils/mdlx/primitives/createprimitive\";\nimport { createUnitRectangle, createUnitCube, createUnitSphere, createUnitCylinder, createFrustum } from \"../../../src/utils/mdlx/primitives/primitives\";\n\nexport const mdxPrimitivesTests = {\n  name: 'mdx-primitives',\n  tests: [\n    {\n      name: 'rectangle',\n      tests: [\n        {\n          name: 'faces',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitRectangle());\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edges',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitRectangle(), { lines: true });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'vertex-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitRectangle(), { color: new Float32Array([1, 0, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edge-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitRectangle(), { lines: true, color: new Float32Array([0, 1, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'texture',\n          load(viewer) {\n            let texture = viewer.load('resources/checkers.jpg');\n\n            return createPrimitive(viewer, createUnitRectangle(), { texture });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'cube',\n      tests: [\n        {\n          name: 'faces',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCube());\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 160]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edges',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCube(), { lines: true });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 160]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'vertex-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCube(), { color: new Float32Array([1, 0, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 160]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edge-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCube(), { lines: true, color: new Float32Array([0, 1, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 160]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'texture',\n          load(viewer) {\n            let texture = viewer.load('resources/checkers.jpg');\n\n            return createPrimitive(viewer, createUnitCube(), { texture });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 160]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'sphere',\n      tests: [\n        {\n          name: 'faces',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitSphere(20, 20));\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edges',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitSphere(20, 20), { lines: true });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'vertex-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitSphere(20, 20), { color: new Float32Array([1, 0, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edge-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitSphere(20, 20), { lines: true, color: new Float32Array([0, 1, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'texture',\n          load(viewer) {\n            let texture = viewer.load('resources/checkers.jpg');\n\n            return createPrimitive(viewer, createUnitSphere(20, 20), { texture });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 120]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'cylinder',\n      tests: [\n        {\n          name: 'faces',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCylinder(20));\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 150]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edges',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCylinder(20), { lines: true });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 150]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'vertex-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCylinder(20), { color: new Float32Array([1, 0, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 150]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edge-color',\n          load(viewer) {\n            return createPrimitive(viewer, createUnitCylinder(20), { lines: true, color: new Float32Array([0, 1, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 150]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'texture',\n          load(viewer) {\n            let texture = viewer.load('resources/checkers.jpg');\n\n            return createPrimitive(viewer, createUnitCylinder(), { texture });\n          },\n          test(viewer, scene, camera, model) {\n            camera.move([0, 0, 150]);\n\n            let instance = model.addInstance().uniformScale(40).rotate(quat.setAxisAngle([], [1, 0, 0], Math.PI / 8));\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n\n    {\n      name: 'frustum',\n      tests: [\n        {\n          name: 'faces',\n          load(viewer) {\n            return createPrimitive(viewer, createFrustum(Math.PI / 4, 0.75, 8, 120));\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([150, 0, 200], [0, 0, 60], [0, 0, 1]);\n\n            let instance = model.addInstance();\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edges',\n          load(viewer) {\n            return createPrimitive(viewer, createFrustum(Math.PI / 4, 0.75, 8, 120), { lines: true });\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([150, 0, 200], [0, 0, 60], [0, 0, 1]);\n\n            let instance = model.addInstance();\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'vertex-color',\n          load(viewer) {\n            return createPrimitive(viewer, createFrustum(Math.PI / 4, 0.75, 8, 120), { color: new Float32Array([1, 0, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([150, 0, 200], [0, 0, 60], [0, 0, 1]);\n\n            let instance = model.addInstance();\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'edge-color',\n          load(viewer) {\n            return createPrimitive(viewer, createFrustum(Math.PI / 4, 0.75, 8, 120), { lines: true, color: new Float32Array([0, 1, 0]) });\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([150, 0, 200], [0, 0, 60], [0, 0, 1]);\n\n            let instance = model.addInstance();\n\n            scene.addInstance(instance);\n          },\n        },\n\n        {\n          name: 'texture',\n          load(viewer) {\n            let texture = viewer.load('resources/checkers.jpg');\n\n            return createPrimitive(viewer, createFrustum(Math.PI / 4, 0.75, 8, 120), { texture });\n          },\n          test(viewer, scene, camera, model) {\n            camera.moveToAndFace([150, 0, 200], [0, 0, 60], [0, 0, 1]);\n\n            let instance = model.addInstance();\n\n            scene.addInstance(instance);\n          },\n        },\n      ],\n    },\n  ],\n};\n"
  },
  {
    "path": "clients/tests/unittester.js",
    "content": "import * as resemble from '../thirdparty/resemble';\nimport seededRandom from '../../src/common/seededrandom';\nimport { blobToImage } from '../../src/common/canvas';\nimport ModelViewer from '../../src/viewer/viewer';\nimport mdxHandler from '../../src/viewer/handlers/mdx/handler';\nimport blpHandler from '../../src/viewer/handlers/blp/handler';\nimport ddsHandler from '../../src/viewer/handlers/dds/handler';\nimport tgaHandler from '../../src/viewer/handlers/tga/handler';\nimport m3Handler from '../../src/viewer/handlers/m3/handler';\n\n/**\n * A unit tester designed for the model viewer.\n * The input of each test is a pre-defined scene, and the output is the rendered image.\n * The image is then compared to another image generated from the same test, at a time when rendering it was considered \"correct\".\n */\nexport default class UnitTester {\n  constructor(wc3PathSolver) {\n    let canvas = document.createElement('canvas');\n\n    canvas.width = canvas.height = 256;\n\n    let viewer = new ModelViewer(canvas, { alpha: false, antialias: false });\n\n    viewer.gl.clearColor(0.05, 0.05, 0.05, 1);\n\n    viewer.on('error', (e) => console.log(e));\n\n    viewer.addHandler(mdxHandler, wc3PathSolver);\n    viewer.addHandler(blpHandler);\n    viewer.addHandler(ddsHandler);\n    viewer.addHandler(tgaHandler);\n    viewer.addHandler(m3Handler);\n\n    this.viewer = viewer;\n    this.mathRandom = Math.random;\n    this.tests = [];\n  }\n\n  /**\n   * Add a test or a hierarchy of tests.\n   */\n  add(test) {\n    if (test.tests) {\n      this.addBaseName(test.tests, test.name);\n    } else {\n      this.tests.push({ name: test.name, test });\n    }\n  }\n\n  /**\n   * Run all of the tests that were added.\n   * The callback will be called with the result of each one.\n   * The results look like iterators: {done: true/false, value: undefine/result }.\n   */\n  async test(callback) {\n    for (let test of this.tests) {\n      let testBlob = await this.getTestBlob(test);\n      let comparisonBlob = await this.getComparisonBlob(test);\n\n      if (testBlob && comparisonBlob) {\n        let comparisonResult = await new Promise((resolve) => resemble(testBlob).compareTo(comparisonBlob).ignoreColors().onComplete((data) => resolve(data)));\n        let testImage = await blobToImage(testBlob);\n        let comparisonImage = await blobToImage(comparisonBlob);\n\n        callback({ done: false, value: { name: test.name, testImage, comparisonImage, mismatchPercentage: comparisonResult.rawMisMatchPercentage } });\n      } else {\n        // Fail modes.\n        // 1) The test blob exists, but comparison doesn't. This happens when adding new tests.\n        // 2) The comparison blob exists, but the test doesn't. This happens when having issues with fetching the files needed for the tests.\n        // 3) Neither exists.\n        if (testBlob) {\n          callback({ done: false, value: { name: test.name, testImage: await blobToImage(testBlob), mismatchPercentage: 100 } });\n        } else if (comparisonBlob) {\n          callback({ done: false, value: { name: test.name, comparisonImage: await blobToImage(comparisonBlob), mismatchPercentage: 100 } });\n        } else {\n          callback({ done: false, value: { name: test.name, mismatchPercentage: 100 } });\n        }\n      }\n    }\n\n    callback({ done: true });\n  }\n\n  /**\n   * Run all of the tests that were added, and download them.\n   * The tests are not compared against anything.\n   * This is used to update the \"correct\" results.\n   */\n  async download(callback) {\n    for (let test of this.tests) {\n      let name = test.name;\n      let blob = await this.getTestBlob(test);\n\n      if (blob) {\n        callback({ done: false, value: { name, blob } });\n      } else {\n        callback({ done: false, value: { name } });\n      }\n    }\n\n    callback({ done: true });\n  }\n\n  /**\n   * Is the given resource or array of resources ok?\n   */\n  isDataAGo(data) {\n    if (data) {\n      if (Array.isArray(data)) {\n        for (let resource of data) {\n          if (!resource) {\n            return false;\n          }\n        }\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Given a test, return a promise that will resolve to the blob that resulted from running the test.\n   */\n  async getTestBlob(test) {\n    let loadHandler = test.test.load;\n    let testHandler = test.test.test;\n    let viewer = this.viewer;\n\n    // Clear the viewer\n    viewer.clear();\n\n    let scene = viewer.addScene();\n\n    scene.color.fill(0.05);\n\n    // Start loading the test.\n    let data = loadHandler(viewer);\n\n    // Wait until everything loaded.\n    await viewer.whenAllLoaded();\n\n    if (Array.isArray(data)) {\n      data = await Promise.all(data);\n    } else {\n      data = await data;\n    }\n\n    if (this.isDataAGo(data)) {\n      // Replace Math.random with a custom seeded random generator.\n      // This allows to run the viewer in a deterministic environment for tests.\n      // For example, particles have some randomized data, which can make tests mismatch.\n      Math.random = seededRandom(6);\n\n      // Run the test.\n      testHandler(viewer, scene, scene.camera, data);\n\n      // Update and render.\n      viewer.updateAndRender();\n\n      // Put back Math.random in its place.\n      Math.random = this.mathRandom;\n\n      // Return the viewer's canvas' blob.\n      return await viewer.toBlob();\n    }\n  }\n\n  /**\n   * Given a test, return a promise that will resolve to the comparison image of this test.\n   */\n  async getComparisonBlob(test) {\n    let response = await fetch(`compare/${test.name}.png`);\n\n    if (response.ok) {\n      return await response.blob();\n    }\n  }\n\n  /**\n   * Adds tests from an hierarchy while appending their names.\n   * Called automatically by add() if needed.\n   */\n  addBaseName(tests, baseName) {\n    for (let test of tests) {\n      if (test.tests) {\n        this.addBaseName(test.tests, baseName + '-' + test.name);\n      } else {\n        this.tests.push({ name: baseName + '-' + test.name, test });\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/textureatlas/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n  <title>KEKW</title>\n\n  <meta charset=\"utf-8\" />\n\n  <style>\n    .row {\n      display: flex;\n      flex-direction: row;\n      gap: 5px;\n    }\n\n    .column {\n      display: flex;\n      flex-direction: column;\n      gap: 5px;\n    }\n\n    .padding5 {\n      padding: 5px;\n    }\n\n    .border {\n      border: 1px solid black;\n      box-sizing: border-box;\n    }\n\n    .bold {\n      font-weight: bold;\n    }\n\n    #input_canvas {\n      width: 256px;\n      height: 256px;\n    }\n\n    #work_canvas {\n      width: 100px;\n      height: 100px;\n    }\n\n    #output_canvas {\n      width: 256px;\n      height: 256px;\n    }\n  </style>\n</head>\n\n<body>\n  <div class=\"row\">\n    <div class=\"column\">\n      <div class=\"row\">\n        <div class=\"border padding5\">\n          <canvas id=\"input_canvas\"></canvas>\n        </div>\n\n        <div class=\"column\">\n          <div class=\"column border padding5\">\n            <div class=\"bold\">Input</div>\n\n            <div class=\"row\">\n              Width:\n              <div id=\"input_width\"></div>\n            </div>\n\n            <div class=\"row\">\n              Height:\n              <div id=\"input_height\"></div>\n            </div>\n          </div>\n\n          <div class=\"column border padding5\">\n            <div class=\"bold\">Output</div>\n\n            <div class=\"row\">\n              Width\n              <input id=\"output_width\" type=\"number\" value=\"256\" />\n            </div>\n\n            <div class=\"row\">\n              Height\n              <input id=\"output_height\" type=\"number\" value=\"256\" />\n            </div>\n\n            <div class=\"row\">\n              Columns\n              <input id=\"output_columns\" type=\"number\" value=\"8\" />\n            </div>\n\n            <div class=\"row\">\n              Rows\n              <input id=\"output_rows\" type=\"number\" value=\"8\" />\n            </div>\n\n            <div class=\"row\">\n              Revolutions\n              <input id=\"output_revolutions\" type=\"number\" value=\"1\" />\n            </div>\n\n            <div class=\"row\">\n              Cell Width:\n              <div id=\"output_cell_width\">32px</div>\n            </div>\n\n            <div class=\"row\">\n              Cell Height:\n              <div id=\"output_cell_height\">32px</div>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"row border padding5\">\n        <div id=\"status\"></div>\n      </div>\n    </div>\n\n    <div class=\"border padding5\">\n      <canvas id=\"work_canvas\"></canvas>\n    </div>\n\n    <div class=\"border padding5\">\n      <canvas id=\"output_canvas\"></canvas>\n    </div>\n  </div>\n\n  <script src=\"index.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/textureatlas/index.js",
    "content": "class TextureAtlasGenerator {\n  constructor() {\n    this.inputWidthElement = document.getElementById('input_width');\n    this.inputHeightElement = document.getElementById('input_height');\n    this.outputCellWidthElement = document.getElementById('output_cell_width');\n    this.outputCellHeightElement = document.getElementById('output_cell_height');\n    this.statusElement = document.getElementById('status');\n    this.inputCanvas = document.getElementById('input_canvas');\n    this.workCanvas = document.getElementById('work_canvas');\n    this.outputCanvas = document.getElementById('output_canvas');\n    this.inputCtx = this.inputCanvas.getContext('2d');\n    this.workCtx = this.workCanvas.getContext('2d');\n    this.outputCtx = this.outputCanvas.getContext('2d');\n    this.image = null;\n    this.inputWidth = 0;\n    this.inputHeight = 0;\n    this.width = 256;\n    this.height = 256;\n    this.columns = 8;\n    this.rows = 8;\n    this.revolutions = 1;\n    this.cellWidth = 32;\n    this.cellHeight = 32;\n\n    document.getElementById('output_width').addEventListener('change', (e) => this.setWidth(e.target.value));\n    document.getElementById('output_height').addEventListener('change', (e) => this.setHeight(e.target.value));\n    document.getElementById('output_columns').addEventListener('change', (e) => this.setColumns(e.target.value));\n    document.getElementById('output_rows').addEventListener('change', (e) => this.setRows(e.target.value));\n    document.getElementById('output_revolutions').addEventListener('change', (e) => this.setRevolutions(e.target.value));\n\n    document.addEventListener('dragover', e => {\n      e.preventDefault();\n    });\n\n    document.addEventListener('dragend', e => {\n      e.preventDefault();\n    });\n\n    document.addEventListener('drop', e => {\n      e.preventDefault();\n\n      let file = e.dataTransfer.files[0];\n      let reader = new FileReader();\n\n      reader.addEventListener('loadend', (e) => {\n        let image = new Image();\n\n        image.onload = (e) => this.setImage(image);\n        image.onerror = (e) => this.error('Failed to load the file');\n\n        image.src = e.target.result;\n      });\n\n      reader.readAsDataURL(file);\n    });\n\n    this.status('Drag & drop an image anywhere on the page');\n  }\n\n  status(status) {\n    this.statusElement.textContent = status;\n  }\n\n  error(status) {\n    const { workCtx, workCanvas, outputCtx, outputCanvas } = this;\n\n    workCtx.clearRect(0, 0, workCanvas.width, workCanvas.height);\n    outputCtx.clearRect(0, 0, outputCanvas.width, outputCanvas.height);\n\n    this.status(status);\n  }\n\n  setImage(image) {\n    const { inputCanvas, inputCtx, inputWidthElement, inputHeightElement } = this;\n\n    this.image = image;\n\n    inputCanvas.width = image.width;\n    inputCanvas.height = image.height;\n\n    inputCtx.drawImage(image, 0, 0);\n\n    inputWidthElement.textContent = `${image.width}px`;\n    inputHeightElement.textContent = `${image.height}px`;\n\n    this.update();\n  }\n\n  setWidth(width) {\n    this.width = width;\n    this.update();\n  }\n\n  setHeight(height) {\n    this.height = height;\n    this.update();\n  }\n\n  setColumns(columns) {\n    this.columns = columns;\n    this.update();\n  }\n\n  setRows(rows) {\n    this.rows = rows;\n    this.update();\n  }\n\n  setRevolutions(revolutions) {\n    this.revolutions = revolutions;\n    this.update();\n  }\n\n  update() {\n    const { image, width, height, columns, rows, revolutions } = this;\n\n    if (!image) {\n      this.error('Upload an image');\n      return;\n    }\n\n    if (width < 1 || height < 1 || columns < 1 || rows < 1) {\n      this.error('No negative values');\n      return;\n    }\n\n    this.cellWidth = width / columns;\n    this.cellHeight = height / rows;\n\n    const { outputCellWidthElement, outputCellHeightElement, cellWidth, cellHeight } = this;\n\n    outputCellWidthElement.textContent = `${cellWidth}px`;\n    outputCellHeightElement.textContent = `${cellHeight}px`;\n\n    if (cellWidth !== (cellWidth | 0) || cellHeight !== (cellHeight | 0)) {\n      this.error('No fractional cell sizes');\n      return;\n    }\n\n    const { workCanvas, outputCanvas, workCtx, outputCtx } = this;\n    const step = (revolutions * Math.PI * 2) / (columns * rows);\n\n    workCanvas.width = cellWidth;\n    workCanvas.height = cellHeight;\n\n    outputCanvas.width = width;\n    outputCanvas.height = height;\n\n    let angle = 0;\n\n    for (let y = 0; y < rows; y++) {\n      for (let x = 0; x < columns; x++) {\n        workCtx.clearRect(0, 0, cellWidth, cellHeight);\n\n        workCtx.save();\n        workCtx.translate(cellWidth / 2, cellHeight / 2);\n        workCtx.rotate(angle);\n        workCtx.translate(-cellWidth / 2, -cellHeight / 2);\n        workCtx.drawImage(image, 0, 0, cellWidth, cellHeight);\n        workCtx.restore();\n\n        outputCtx.drawImage(workCanvas, x * cellWidth, y * cellHeight);\n\n        angle += step;\n      }\n    }\n\n    this.status('Right click on the texture atlas to download it, or adjust values and regenerate it');\n  }\n}\n\nnew TextureAtlasGenerator();\n"
  },
  {
    "path": "clients/thirdparty/filesaver.js",
    "content": "/* FileSaver.js\n *  A saveAs() & saveTextAs() FileSaver implementation.\n *  2014-06-24\n *\n *  Modify by Brian Chen\n *  Author: Eli Grey, http://eligrey.com\n *  License: X11/MIT\n *    See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n */\n\n/*global self */\n/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */\n\n/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */\n\nvar saveAs = saveAs\n// IE 10+ (native saveAs)\n|| (typeof navigator !== \"undefined\" &&\n    navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))\n// Everyone else\n|| (function (view) {\n    \"use strict\";\n    // IE <10 is explicitly unsupported\n    if (typeof navigator !== \"undefined\" &&\n        /MSIE [1-9]\\./.test(navigator.userAgent)) {\n        return;\n    }\n    var\n          doc = view.document\n          // only get URL when necessary in case Blob.js hasn't overridden it yet\n        , get_URL = function () {\n            return view.URL || view.webkitURL || view;\n        }\n        , save_link = doc.createElementNS(\"http://www.w3.org/1999/xhtml\", \"a\")\n        , can_use_save_link = !view.externalHost && \"download\" in save_link\n        , click = function (node) {\n            var event = doc.createEvent(\"MouseEvents\");\n            event.initMouseEvent(\n                \"click\", true, false, view, 0, 0, 0, 0, 0\n                , false, false, false, false, 0, null\n            );\n            node.dispatchEvent(event);\n        }\n        , webkit_req_fs = view.webkitRequestFileSystem\n        , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem\n        , throw_outside = function (ex) {\n            (view.setImmediate || view.setTimeout)(function () {\n                throw ex;\n            }, 0);\n        }\n        , force_saveable_type = \"application/octet-stream\"\n        , fs_min_size = 0\n        , deletion_queue = []\n        , process_deletion_queue = function () {\n            var i = deletion_queue.length;\n            while (i--) {\n                var file = deletion_queue[i];\n                if (typeof file === \"string\") { // file is an object URL\n                    get_URL().revokeObjectURL(file);\n                } else { // file is a File\n                    file.remove();\n                }\n            }\n            deletion_queue.length = 0; // clear queue\n        }\n        , dispatch = function (filesaver, event_types, event) {\n            event_types = [].concat(event_types);\n            var i = event_types.length;\n            while (i--) {\n                var listener = filesaver[\"on\" + event_types[i]];\n                if (typeof listener === \"function\") {\n                    try {\n                        listener.call(filesaver, event || filesaver);\n                    } catch (ex) {\n                        throw_outside(ex);\n                    }\n                }\n            }\n        }\n        , FileSaver = function (blob, name) {\n            // First try a.download, then web filesystem, then object URLs\n            var\n                  filesaver = this\n                , type = blob.type\n                , blob_changed = false\n                , object_url\n                , target_view\n                , get_object_url = function () {\n                    var object_url = get_URL().createObjectURL(blob);\n                    deletion_queue.push(object_url);\n                    return object_url;\n                }\n                , dispatch_all = function () {\n                    dispatch(filesaver, \"writestart progress write writeend\".split(\" \"));\n                }\n                // on any filesys errors revert to saving with object URLs\n                , fs_error = function () {\n                    // don't create more object URLs than needed\n                    if (blob_changed || !object_url) {\n                        object_url = get_object_url(blob);\n                    }\n                    if (target_view) {\n                        target_view.location.href = object_url;\n                    } else {\n                        window.open(object_url, \"_blank\");\n                    }\n                    filesaver.readyState = filesaver.DONE;\n                    dispatch_all();\n                }\n                , abortable = function (func) {\n                    return function () {\n                        if (filesaver.readyState !== filesaver.DONE) {\n                            return func.apply(this, arguments);\n                        }\n                    };\n                }\n                , create_if_not_found = { create: true, exclusive: false }\n                , slice\n            ;\n            filesaver.readyState = filesaver.INIT;\n            if (!name) {\n                name = \"download\";\n            }\n            if (can_use_save_link) {\n                object_url = get_object_url(blob);\n                save_link.href = object_url;\n                save_link.download = name;\n                click(save_link);\n                filesaver.readyState = filesaver.DONE;\n                dispatch_all();\n                return;\n            }\n            // Object and web filesystem URLs have a problem saving in Google Chrome when\n            // viewed in a tab, so I force save with application/octet-stream\n            // http://code.google.com/p/chromium/issues/detail?id=91158\n            if (view.chrome && type && type !== force_saveable_type) {\n                slice = blob.slice || blob.webkitSlice;\n                blob = slice.call(blob, 0, blob.size, force_saveable_type);\n                blob_changed = true;\n            }\n            // Since I can't be sure that the guessed media type will trigger a download\n            // in WebKit, I append .download to the filename.\n            // https://bugs.webkit.org/show_bug.cgi?id=65440\n            if (webkit_req_fs && name !== \"download\") {\n                name += \".download\";\n            }\n            if (type === force_saveable_type || webkit_req_fs) {\n                target_view = view;\n            }\n            if (!req_fs) {\n                fs_error();\n                return;\n            }\n            fs_min_size += blob.size;\n            req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) {\n                fs.root.getDirectory(\"saved\", create_if_not_found, abortable(function (dir) {\n                    var save = function () {\n                        dir.getFile(name, create_if_not_found, abortable(function (file) {\n                            file.createWriter(abortable(function (writer) {\n                                writer.onwriteend = function (event) {\n                                    target_view.location.href = file.toURL();\n                                    deletion_queue.push(file);\n                                    filesaver.readyState = filesaver.DONE;\n                                    dispatch(filesaver, \"writeend\", event);\n                                };\n                                writer.onerror = function () {\n                                    var error = writer.error;\n                                    if (error.code !== error.ABORT_ERR) {\n                                        fs_error();\n                                    }\n                                };\n                                \"writestart progress write abort\".split(\" \").forEach(function (event) {\n                                    writer[\"on\" + event] = filesaver[\"on\" + event];\n                                });\n                                writer.write(blob);\n                                filesaver.abort = function () {\n                                    writer.abort();\n                                    filesaver.readyState = filesaver.DONE;\n                                };\n                                filesaver.readyState = filesaver.WRITING;\n                            }), fs_error);\n                        }), fs_error);\n                    };\n                    dir.getFile(name, { create: false }, abortable(function (file) {\n                        // delete file if it already exists\n                        file.remove();\n                        save();\n                    }), abortable(function (ex) {\n                        if (ex.code === ex.NOT_FOUND_ERR) {\n                            save();\n                        } else {\n                            fs_error();\n                        }\n                    }));\n                }), fs_error);\n            }), fs_error);\n        }\n        , FS_proto = FileSaver.prototype\n        , saveAs = function (blob, name) {\n            return new FileSaver(blob, name);\n        }\n    ;\n    FS_proto.abort = function () {\n        var filesaver = this;\n        filesaver.readyState = filesaver.DONE;\n        dispatch(filesaver, \"abort\");\n    };\n    FS_proto.readyState = FS_proto.INIT = 0;\n    FS_proto.WRITING = 1;\n    FS_proto.DONE = 2;\n\n    FS_proto.error =\n    FS_proto.onwritestart =\n    FS_proto.onprogress =\n    FS_proto.onwrite =\n    FS_proto.onabort =\n    FS_proto.onerror =\n    FS_proto.onwriteend =\n        null;\n\n    view.addEventListener(\"unload\", process_deletion_queue, false);\n    saveAs.unload = function () {\n        process_deletion_queue();\n        view.removeEventListener(\"unload\", process_deletion_queue, false);\n    };\n    return saveAs;\n}(\n     typeof self !== \"undefined\" && self\n  || typeof window !== \"undefined\" && window\n  || this.content\n));\n// `self` is undefined in Firefox for Android content script context\n// while `this` is nsIContentFrameMessageManager\n// with an attribute `content` that corresponds to the window\n\nif (typeof module !== \"undefined\" && module !== null) {\n  module.exports = saveAs;\n} else if ((typeof define !== \"undefined\" && define !== null) && (define.amd != null)) {\n  define([], function () {\n      return saveAs;\n  });\n}\n\nString.prototype.endsWithAny = function () {\n  var strArray = Array.prototype.slice.call(arguments),\n      $this = this.toLowerCase().toString();\n  for (var i = 0; i < strArray.length; i++) {\n      if ($this.indexOf(strArray[i], $this.length - strArray[i].length) !== -1) return true;\n  }\n  return false;\n};\n\nvar saveTextAs = saveTextAs\n|| (function (textContent, fileName, charset) {\n  fileName = fileName || 'download.txt';\n  charset = charset || 'utf-8';\n  textContent = (textContent || '').replace(/\\r?\\n/g, \"\\r\\n\");\n  if (saveAs && Blob) {\n      var blob = new Blob([textContent], { type: \"text/plain;charset=\" + charset });\n      saveAs(blob, fileName);\n      return true;\n  } else {//IE9-\n      var saveTxtWindow = window.frames.saveTxtWindow;\n      if (!saveTxtWindow) {\n          saveTxtWindow = document.createElement('iframe');\n          saveTxtWindow.id = 'saveTxtWindow';\n          saveTxtWindow.style.display = 'none';\n          document.body.insertBefore(saveTxtWindow, null);\n          saveTxtWindow = window.frames.saveTxtWindow;\n          if (!saveTxtWindow) {\n              saveTxtWindow = window.open('', '_temp', 'width=100,height=100');\n              if (!saveTxtWindow) {\n                  window.alert('Sorry, download file could not be created.');\n                  return false;\n              }\n          }\n      }\n\n      var doc = saveTxtWindow.document;\n      doc.open('text/html', 'replace');\n      doc.charset = charset;\n      if (fileName.endsWithAny('.htm', '.html')) {\n          doc.close();\n          doc.body.innerHTML = '\\r\\n' + textContent + '\\r\\n';\n      } else {\n          if (!fileName.endsWithAny('.txt')) fileName += '.txt';\n          doc.write(textContent);\n          doc.close();\n      }\n\n      var retValue = doc.execCommand('SaveAs', null, fileName);\n      saveTxtWindow.close();\n      return retValue;\n  }\n})\n"
  },
  {
    "path": "clients/thirdparty/resemble.js",
    "content": "// NOTE: require(\"canvas-prebuilt\") was commented because it makes webpack throw annoying errors, since my code is running in a browser, not nodejs.\n\n/*\nJames Cryer / Huddle\nURL: https://github.com/Huddle/Resemble.js\n*/\n\n(function(root, factory) {\n    \"use strict\";\n    if (typeof define === \"function\" && define.amd) {\n        define([], factory);\n    } else if (typeof module === \"object\" && module.exports) {\n        module.exports = factory();\n    } else {\n        root.resemble = factory();\n    }\n})(this, function() {\n    \"use strict\";\n\n    var Img;\n    var Canvas;\n\n    if (typeof Image !== \"undefined\") {\n        Img = Image;\n    } else {\n        // Canvas = require(\"canvas-prebuilt\"); // eslint-disable-line global-require\n        Img = Canvas.Image;\n    }\n\n    var document =\n        typeof window !== \"undefined\"\n            ? window.document\n            : {\n                createElement: function() {\n                    // This will work as long as only createElement is used on window.document\n                    return new Canvas();\n                }\n            };\n\n    var oldGlobalSettings = {};\n    var globalOutputSettings = oldGlobalSettings;\n\n    function setGlobalOutputSettings(settings) {\n        var msg =\n            \"warning resemble.outputSettings mutates global state, and \" +\n            \"will be removed in 3.0.0\";\n        console.warn(msg);\n        globalOutputSettings = settings;\n        return this;\n    }\n\n    var resemble = function(fileData) {\n        var pixelTransparency = 1;\n\n        var errorPixelColor = {\n            // Color for Error Pixels. Between 0 and 255.\n            red: 255,\n            green: 0,\n            blue: 255,\n            alpha: 255\n        };\n\n        var targetPix = {r: 0, g: 0, b: 0, a: 0}; // isAntialiased\n\n        function colorsDistance(c1, c2) {\n            return (\n                (Math.abs(c1.r - c2.r) +\n                    Math.abs(c1.g - c2.g) +\n                    Math.abs(c1.b - c2.b)) /\n                3\n            );\n        }\n\n        function withinBoundingBox(x, y, width, height, box) {\n            return (\n                x > (box.left || 0) &&\n                x < (box.right || width) &&\n                y > (box.top || 0) &&\n                y < (box.bottom || height)\n            );\n        }\n\n        function withinComparedArea(x, y, width, height) {\n            var isIncluded = true;\n\n            if (\n                boundingBox !== undefined &&\n                !withinBoundingBox(x, y, width, height, boundingBox)\n            ) {\n                isIncluded = false;\n            }\n\n            if (\n                ignoredBox !== undefined &&\n                withinBoundingBox(x, y, width, height, ignoredBox)\n            ) {\n                isIncluded = false;\n            }\n\n            return isIncluded;\n        }\n\n        var errorPixelTransform = {\n            flat: function(px, offset) {\n                px[offset] = errorPixelColor.red;\n                px[offset + 1] = errorPixelColor.green;\n                px[offset + 2] = errorPixelColor.blue;\n                px[offset + 3] = errorPixelColor.alpha;\n            },\n            movement: function(px, offset, d1, d2) {\n                px[offset] =\n                    (d2.r * (errorPixelColor.red / 255) + errorPixelColor.red) /\n                    2;\n                px[offset + 1] =\n                    (d2.g * (errorPixelColor.green / 255) +\n                        errorPixelColor.green) /\n                    2;\n                px[offset + 2] =\n                    (d2.b * (errorPixelColor.blue / 255) +\n                        errorPixelColor.blue) /\n                    2;\n                px[offset + 3] = d2.a;\n            },\n            flatDifferenceIntensity: function(px, offset, d1, d2) {\n                px[offset] = errorPixelColor.red;\n                px[offset + 1] = errorPixelColor.green;\n                px[offset + 2] = errorPixelColor.blue;\n                px[offset + 3] = colorsDistance(d1, d2);\n            },\n            movementDifferenceIntensity: function(px, offset, d1, d2) {\n                var ratio = colorsDistance(d1, d2) / 255 * 0.8;\n\n                px[offset] =\n                    (1 - ratio) * (d2.r * (errorPixelColor.red / 255)) +\n                    ratio * errorPixelColor.red;\n                px[offset + 1] =\n                    (1 - ratio) * (d2.g * (errorPixelColor.green / 255)) +\n                    ratio * errorPixelColor.green;\n                px[offset + 2] =\n                    (1 - ratio) * (d2.b * (errorPixelColor.blue / 255)) +\n                    ratio * errorPixelColor.blue;\n                px[offset + 3] = d2.a;\n            },\n            diffOnly: function(px, offset, d1, d2) {\n                px[offset] = d2.r;\n                px[offset + 1] = d2.g;\n                px[offset + 2] = d2.b;\n                px[offset + 3] = d2.a;\n            }\n        };\n\n        var errorPixel = errorPixelTransform.flat;\n        var errorType;\n        var boundingBox;\n        var ignoredBox;\n        var largeImageThreshold = 1200;\n        var useCrossOrigin = true;\n        var data = {};\n        var images = [];\n        var updateCallbackArray = [];\n\n        var tolerance = {\n            // between 0 and 255\n            red: 16,\n            green: 16,\n            blue: 16,\n            alpha: 16,\n            minBrightness: 16,\n            maxBrightness: 240\n        };\n\n        var ignoreAntialiasing = false;\n        var ignoreColors = false;\n        var scaleToSameSize = false;\n\n        function triggerDataUpdate() {\n            var len = updateCallbackArray.length;\n            var i;\n            for (i = 0; i < len; i++) {\n                if (typeof updateCallbackArray[i] === \"function\") {\n                    updateCallbackArray[i](data);\n                }\n            }\n        }\n\n        function loop(w, h, callback) {\n            var x;\n            var y;\n\n            for (x = 0; x < w; x++) {\n                for (y = 0; y < h; y++) {\n                    callback(x, y);\n                }\n            }\n        }\n\n        function parseImage(sourceImageData, width, height) {\n            var pixelCount = 0;\n            var redTotal = 0;\n            var greenTotal = 0;\n            var blueTotal = 0;\n            var alphaTotal = 0;\n            var brightnessTotal = 0;\n            var whiteTotal = 0;\n            var blackTotal = 0;\n\n            loop(width, height, function(horizontalPos, verticalPos) {\n                var offset = (verticalPos * width + horizontalPos) * 4;\n                var red = sourceImageData[offset];\n                var green = sourceImageData[offset + 1];\n                var blue = sourceImageData[offset + 2];\n                var alpha = sourceImageData[offset + 3];\n                var brightness = getBrightness(red, green, blue);\n\n                if (red === green && red === blue && alpha) {\n                    if (red === 0) {\n                        blackTotal++;\n                    } else if (red === 255) {\n                        whiteTotal++;\n                    }\n                }\n\n                pixelCount++;\n\n                redTotal += red / 255 * 100;\n                greenTotal += green / 255 * 100;\n                blueTotal += blue / 255 * 100;\n                alphaTotal += (255 - alpha) / 255 * 100;\n                brightnessTotal += brightness / 255 * 100;\n            });\n\n            data.red = Math.floor(redTotal / pixelCount);\n            data.green = Math.floor(greenTotal / pixelCount);\n            data.blue = Math.floor(blueTotal / pixelCount);\n            data.alpha = Math.floor(alphaTotal / pixelCount);\n            data.brightness = Math.floor(brightnessTotal / pixelCount);\n            data.white = Math.floor(whiteTotal / pixelCount * 100);\n            data.black = Math.floor(blackTotal / pixelCount * 100);\n\n            triggerDataUpdate();\n        }\n\n        function loadImageData(fileDataForImage, callback) {\n            var fileReader;\n            var hiddenImage = new Img();\n\n            if (!hiddenImage.setAttribute) {\n                hiddenImage.setAttribute = function setAttribute() {};\n            }\n\n            if (useCrossOrigin) {\n                hiddenImage.setAttribute(\"crossorigin\", \"anonymous\");\n            }\n\n            hiddenImage.onerror = function(err) {\n                hiddenImage.onload = null;\n                hiddenImage.onerror = null; // fixes pollution between calls\n                images.push({error: err ? err + \"\" : \"Image load error.\"});\n                callback();\n            };\n\n            hiddenImage.onload = function() {\n                hiddenImage.onload = null; // fixes pollution between calls\n                hiddenImage.onerror = null;\n\n                var hiddenCanvas = document.createElement(\"canvas\");\n                var imageData;\n\n                // don't assign to hiddenImage, see https://github.com/Huddle/Resemble.js/pull/87/commits/300d43352a2845aad289b254bfbdc7cd6a37e2d7\n                var width = hiddenImage.width;\n                var height = hiddenImage.height;\n\n                if (scaleToSameSize && images.length === 1) {\n                    width = images[0].width;\n                    height = images[0].height;\n                }\n\n                hiddenCanvas.width = width;\n                hiddenCanvas.height = height;\n\n                hiddenCanvas\n                    .getContext(\"2d\")\n                    .drawImage(hiddenImage, 0, 0, width, height);\n                imageData = hiddenCanvas\n                    .getContext(\"2d\")\n                    .getImageData(0, 0, width, height);\n\n                images.push(imageData);\n\n                callback(imageData, width, height);\n            };\n\n            if (typeof fileDataForImage === \"string\") {\n                hiddenImage.src = fileDataForImage;\n                if (hiddenImage.complete && hiddenImage.naturalWidth > 0) {\n                    hiddenImage.onload();\n                }\n            } else if (\n                typeof fileDataForImage.data !== \"undefined\" &&\n                typeof fileDataForImage.width === \"number\" &&\n                typeof fileDataForImage.height === \"number\"\n            ) {\n                images.push(fileDataForImage);\n\n                callback(\n                    fileDataForImage,\n                    fileDataForImage.width,\n                    fileDataForImage.height\n                );\n            } else if (\n                typeof Buffer !== \"undefined\" &&\n                fileDataForImage instanceof Buffer\n            ) {\n                // If we have Buffer, assume we're on Node+Canvas and its supported\n                hiddenImage.src = fileDataForImage;\n            } else {\n                fileReader = new FileReader();\n                fileReader.onload = function(event) {\n                    hiddenImage.src = event.target.result;\n                };\n                fileReader.readAsDataURL(fileDataForImage);\n            }\n        }\n\n        function isColorSimilar(a, b, color) {\n            var absDiff = Math.abs(a - b);\n\n            if (typeof a === \"undefined\") {\n                return false;\n            }\n            if (typeof b === \"undefined\") {\n                return false;\n            }\n\n            if (a === b) {\n                return true;\n            } else if (absDiff < tolerance[color]) {\n                return true;\n            }\n            return false;\n        }\n\n        function isPixelBrightnessSimilar(d1, d2) {\n            var alpha = isColorSimilar(d1.a, d2.a, \"alpha\");\n            var brightness = isColorSimilar(\n                d1.brightness,\n                d2.brightness,\n                \"minBrightness\"\n            );\n            return brightness && alpha;\n        }\n\n        function getBrightness(r, g, b) {\n            return 0.3 * r + 0.59 * g + 0.11 * b;\n        }\n\n        function isRGBSame(d1, d2) {\n            var red = d1.r === d2.r;\n            var green = d1.g === d2.g;\n            var blue = d1.b === d2.b;\n            return red && green && blue;\n        }\n\n        function isRGBSimilar(d1, d2) {\n            var red = isColorSimilar(d1.r, d2.r, \"red\");\n            var green = isColorSimilar(d1.g, d2.g, \"green\");\n            var blue = isColorSimilar(d1.b, d2.b, \"blue\");\n            var alpha = isColorSimilar(d1.a, d2.a, \"alpha\");\n\n            return red && green && blue && alpha;\n        }\n\n        function isContrasting(d1, d2) {\n            return (\n                Math.abs(d1.brightness - d2.brightness) >\n                tolerance.maxBrightness\n            );\n        }\n\n        function getHue(red, green, blue) {\n            var r = red / 255;\n            var g = green / 255;\n            var b = blue / 255;\n            var max = Math.max(r, g, b);\n            var min = Math.min(r, g, b);\n            var h;\n            var d;\n\n            if (max === min) {\n                h = 0; // achromatic\n            } else {\n                d = max - min;\n                switch (max) {\n                    case r:\n                        h = (g - b) / d + (g < b ? 6 : 0);\n                        break;\n                    case g:\n                        h = (b - r) / d + 2;\n                        break;\n                    case b:\n                        h = (r - g) / d + 4;\n                        break;\n                    default:\n                        h /= 6;\n                }\n            }\n\n            return h;\n        }\n\n        function isAntialiased(\n            sourcePix,\n            pix,\n            cacheSet,\n            verticalPos,\n            horizontalPos,\n            width\n        ) {\n            var offset;\n            var distance = 1;\n            var i;\n            var j;\n            var hasHighContrastSibling = 0;\n            var hasSiblingWithDifferentHue = 0;\n            var hasEquivalentSibling = 0;\n\n            addHueInfo(sourcePix);\n\n            for (i = distance * -1; i <= distance; i++) {\n                for (j = distance * -1; j <= distance; j++) {\n                    if (i === 0 && j === 0) {\n                        // ignore source pixel\n                    } else {\n                        offset =\n                            ((verticalPos + j) * width + (horizontalPos + i)) *\n                            4;\n\n                        if (!getPixelInfo(targetPix, pix, offset, cacheSet)) {\n                            continue;\n                        }\n\n                        addBrightnessInfo(targetPix);\n                        addHueInfo(targetPix);\n\n                        if (isContrasting(sourcePix, targetPix)) {\n                            hasHighContrastSibling++;\n                        }\n\n                        if (isRGBSame(sourcePix, targetPix)) {\n                            hasEquivalentSibling++;\n                        }\n\n                        if (Math.abs(targetPix.h - sourcePix.h) > 0.3) {\n                            hasSiblingWithDifferentHue++;\n                        }\n\n                        if (\n                            hasSiblingWithDifferentHue > 1 ||\n                            hasHighContrastSibling > 1\n                        ) {\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            if (hasEquivalentSibling < 2) {\n                return true;\n            }\n\n            return false;\n        }\n\n        function copyPixel(px, offset, pix) {\n            if (errorType === \"diffOnly\") {\n                return;\n            }\n\n            px[offset] = pix.r; // r\n            px[offset + 1] = pix.g; // g\n            px[offset + 2] = pix.b; // b\n            px[offset + 3] = pix.a * pixelTransparency; // a\n        }\n\n        function copyGrayScalePixel(px, offset, pix) {\n            if (errorType === \"diffOnly\") {\n                return;\n            }\n\n            px[offset] = pix.brightness; // r\n            px[offset + 1] = pix.brightness; // g\n            px[offset + 2] = pix.brightness; // b\n            px[offset + 3] = pix.a * pixelTransparency; // a\n        }\n\n        function getPixelInfo(dst, pix, offset) {\n            if (pix.length > offset) {\n                dst.r = pix[offset];\n                dst.g = pix[offset + 1];\n                dst.b = pix[offset + 2];\n                dst.a = pix[offset + 3];\n\n                return true;\n            }\n\n            return false;\n        }\n\n        function addBrightnessInfo(pix) {\n            pix.brightness = getBrightness(pix.r, pix.g, pix.b); // 'corrected' lightness\n        }\n\n        function addHueInfo(pix) {\n            pix.h = getHue(pix.r, pix.g, pix.b);\n        }\n\n        function analyseImages(img1, img2, width, height) {\n            var hiddenCanvas = document.createElement(\"canvas\");\n\n            var data1 = img1.data;\n            var data2 = img2.data;\n\n            hiddenCanvas.width = width;\n            hiddenCanvas.height = height;\n\n            var context = hiddenCanvas.getContext(\"2d\");\n            var imgd = context.createImageData(width, height);\n            var pix = imgd.data;\n\n            var mismatchCount = 0;\n            var diffBounds = {\n                top: height,\n                left: width,\n                bottom: 0,\n                right: 0\n            };\n            var updateBounds = function(x, y) {\n                diffBounds.left = Math.min(x, diffBounds.left);\n                diffBounds.right = Math.max(x, diffBounds.right);\n                diffBounds.top = Math.min(y, diffBounds.top);\n                diffBounds.bottom = Math.max(y, diffBounds.bottom);\n            };\n\n            var time = Date.now();\n\n            var skip;\n\n            if (\n                !!largeImageThreshold &&\n                ignoreAntialiasing &&\n                (width > largeImageThreshold || height > largeImageThreshold)\n            ) {\n                skip = 6;\n            }\n\n            var pixel1 = {r: 0, g: 0, b: 0, a: 0};\n            var pixel2 = {r: 0, g: 0, b: 0, a: 0};\n\n            loop(width, height, function(horizontalPos, verticalPos) {\n                if (skip) {\n                    // only skip if the image isn't small\n                    if (\n                        verticalPos % skip === 0 ||\n                        horizontalPos % skip === 0\n                    ) {\n                        return;\n                    }\n                }\n\n                var offset = (verticalPos * width + horizontalPos) * 4;\n                var isWithinComparedArea = withinComparedArea(\n                    horizontalPos,\n                    verticalPos,\n                    width,\n                    height\n                );\n\n                if (\n                    !getPixelInfo(pixel1, data1, offset, 1) ||\n                    !getPixelInfo(pixel2, data2, offset, 2)\n                ) {\n                    return;\n                }\n\n                if (ignoreColors) {\n                    addBrightnessInfo(pixel1);\n                    addBrightnessInfo(pixel2);\n\n                    if (\n                        isPixelBrightnessSimilar(pixel1, pixel2) ||\n                        !isWithinComparedArea\n                    ) {\n                        copyGrayScalePixel(pix, offset, pixel2);\n                    } else {\n                        errorPixel(pix, offset, pixel1, pixel2);\n                        mismatchCount++;\n                        updateBounds(horizontalPos, verticalPos);\n                    }\n                    return;\n                }\n\n                if (isRGBSimilar(pixel1, pixel2) || !isWithinComparedArea) {\n                    copyPixel(pix, offset, pixel1);\n                } else if (\n                    ignoreAntialiasing &&\n                    (addBrightnessInfo(pixel1), // jit pixel info augmentation looks a little weird, sorry.\n                        addBrightnessInfo(pixel2),\n                        isAntialiased(\n                            pixel1,\n                            data1,\n                            1,\n                            verticalPos,\n                            horizontalPos,\n                            width\n                        ) ||\n                        isAntialiased(\n                            pixel2,\n                            data2,\n                            2,\n                            verticalPos,\n                            horizontalPos,\n                            width\n                        ))\n                ) {\n                    if (\n                        isPixelBrightnessSimilar(pixel1, pixel2) ||\n                        !isWithinComparedArea\n                    ) {\n                        copyGrayScalePixel(pix, offset, pixel2);\n                    } else {\n                        errorPixel(pix, offset, pixel1, pixel2);\n                        mismatchCount++;\n                        updateBounds(horizontalPos, verticalPos);\n                    }\n                } else {\n                    errorPixel(pix, offset, pixel1, pixel2);\n                    mismatchCount++;\n                    updateBounds(horizontalPos, verticalPos);\n                }\n            });\n\n            data.rawMisMatchPercentage = mismatchCount / (height * width) * 100;\n            data.misMatchPercentage = data.rawMisMatchPercentage.toFixed(2);\n            data.diffBounds = diffBounds;\n            data.analysisTime = Date.now() - time;\n\n            data.getImageDataUrl = function(text) {\n                var barHeight = 0;\n\n                if (text) {\n                    barHeight = addLabel(text, context, hiddenCanvas);\n                }\n\n                context.putImageData(imgd, 0, barHeight);\n\n                return hiddenCanvas.toDataURL(\"image/png\");\n            };\n\n            if (hiddenCanvas.toBuffer) {\n                data.getBuffer = function(includeOriginal) {\n                    if (includeOriginal) {\n                        var imageWidth = hiddenCanvas.width + 2;\n                        hiddenCanvas.width = imageWidth * 3;\n                        context.putImageData(img1, 0, 0);\n                        context.putImageData(img2, imageWidth, 0);\n                        context.putImageData(imgd, imageWidth * 2, 0);\n                    } else {\n                        context.putImageData(imgd, 0, 0);\n                    }\n                    return hiddenCanvas.toBuffer();\n                };\n            }\n        }\n\n        function addLabel(text, context, hiddenCanvas) {\n            var textPadding = 2;\n\n            context.font = \"12px sans-serif\";\n\n            var textWidth = context.measureText(text).width + textPadding * 2;\n            var barHeight = 22;\n\n            if (textWidth > hiddenCanvas.width) {\n                hiddenCanvas.width = textWidth;\n            }\n\n            hiddenCanvas.height += barHeight;\n\n            context.fillStyle = \"#666\";\n            context.fillRect(0, 0, hiddenCanvas.width, barHeight - 4);\n            context.fillStyle = \"#fff\";\n            context.fillRect(0, barHeight - 4, hiddenCanvas.width, 4);\n\n            context.fillStyle = \"#fff\";\n            context.textBaseline = \"top\";\n            context.font = \"12px sans-serif\";\n            context.fillText(text, textPadding, 1);\n\n            return barHeight;\n        }\n\n        function normalise(img, w, h) {\n            var c;\n            var context;\n\n            if (img.height < h || img.width < w) {\n                c = document.createElement(\"canvas\");\n                c.width = w;\n                c.height = h;\n                context = c.getContext(\"2d\");\n                context.putImageData(img, 0, 0);\n                return context.getImageData(0, 0, w, h);\n            }\n\n            return img;\n        }\n\n        function outputSettings(options) {\n            var key;\n\n            if (options.errorColor) {\n                for (key in options.errorColor) {\n                    if (options.errorColor.hasOwnProperty(key)) {\n                        errorPixelColor[key] =\n                            options.errorColor[key] === void 0\n                                ? errorPixelColor[key]\n                                : options.errorColor[key];\n                    }\n                }\n            }\n\n            if (options.errorType && errorPixelTransform[options.errorType]) {\n                errorPixel = errorPixelTransform[options.errorType];\n                errorType = options.errorType;\n            }\n\n            if (\n                options.errorPixel &&\n                typeof options.errorPixel === \"function\"\n            ) {\n                errorPixel = options.errorPixel;\n            }\n\n            pixelTransparency = isNaN(Number(options.transparency))\n                ? pixelTransparency\n                : options.transparency;\n\n            if (options.largeImageThreshold !== undefined) {\n                largeImageThreshold = options.largeImageThreshold;\n            }\n\n            if (options.useCrossOrigin !== undefined) {\n                useCrossOrigin = options.useCrossOrigin;\n            }\n\n            if (options.boundingBox !== undefined) {\n                boundingBox = options.boundingBox;\n            }\n\n            if (options.ignoredBox !== undefined) {\n                ignoredBox = options.ignoredBox;\n            }\n        }\n\n        function compare(one, two) {\n            if (globalOutputSettings !== oldGlobalSettings) {\n                outputSettings(globalOutputSettings);\n            }\n\n            function onceWeHaveBoth() {\n                var width;\n                var height;\n                if (images.length === 2) {\n                    if (images[0].error || images[1].error) {\n                        data = {};\n                        data.error = images[0].error\n                            ? images[0].error\n                            : images[1].error;\n                        triggerDataUpdate();\n                        return;\n                    }\n                    width =\n                        images[0].width > images[1].width\n                            ? images[0].width\n                            : images[1].width;\n                    height =\n                        images[0].height > images[1].height\n                            ? images[0].height\n                            : images[1].height;\n\n                    if (\n                        images[0].width === images[1].width &&\n                        images[0].height === images[1].height\n                    ) {\n                        data.isSameDimensions = true;\n                    } else {\n                        data.isSameDimensions = false;\n                    }\n\n                    data.dimensionDifference = {\n                        width: images[0].width - images[1].width,\n                        height: images[0].height - images[1].height\n                    };\n\n                    analyseImages(\n                        normalise(images[0], width, height),\n                        normalise(images[1], width, height),\n                        width,\n                        height\n                    );\n\n                    triggerDataUpdate();\n                }\n            }\n\n            images = [];\n            loadImageData(one, onceWeHaveBoth);\n            loadImageData(two, onceWeHaveBoth);\n        }\n\n        function getCompareApi(param) {\n            var secondFileData;\n            var hasMethod = typeof param === \"function\";\n\n            if (!hasMethod) {\n                // assume it's file data\n                secondFileData = param;\n            }\n\n            var self = {\n                scaleToSameSize: function() {\n                    scaleToSameSize = true;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                useOriginalSize: function() {\n                    scaleToSameSize = false;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                ignoreNothing: function() {\n                    tolerance.red = 0;\n                    tolerance.green = 0;\n                    tolerance.blue = 0;\n                    tolerance.alpha = 0;\n                    tolerance.minBrightness = 0;\n                    tolerance.maxBrightness = 255;\n\n                    ignoreAntialiasing = false;\n                    ignoreColors = false;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                ignoreLess: function() {\n                    tolerance.red = 16;\n                    tolerance.green = 16;\n                    tolerance.blue = 16;\n                    tolerance.alpha = 16;\n                    tolerance.minBrightness = 16;\n                    tolerance.maxBrightness = 240;\n\n                    ignoreAntialiasing = false;\n                    ignoreColors = false;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                ignoreAntialiasing: function() {\n                    tolerance.red = 32;\n                    tolerance.green = 32;\n                    tolerance.blue = 32;\n                    tolerance.alpha = 32;\n                    tolerance.minBrightness = 64;\n                    tolerance.maxBrightness = 96;\n\n                    ignoreAntialiasing = true;\n                    ignoreColors = false;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                ignoreColors: function() {\n                    tolerance.alpha = 16;\n                    tolerance.minBrightness = 16;\n                    tolerance.maxBrightness = 240;\n\n                    ignoreAntialiasing = false;\n                    ignoreColors = true;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                ignoreAlpha: function() {\n                    tolerance.red = 16;\n                    tolerance.green = 16;\n                    tolerance.blue = 16;\n                    tolerance.alpha = 255;\n                    tolerance.minBrightness = 16;\n                    tolerance.maxBrightness = 240;\n\n                    ignoreAntialiasing = false;\n                    ignoreColors = false;\n\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                repaint: function() {\n                    if (hasMethod) {\n                        param();\n                    }\n                    return self;\n                },\n                outputSettings: function(options) {\n                    outputSettings(options);\n                    return self;\n                },\n                onComplete: function(callback) {\n                    updateCallbackArray.push(callback);\n\n                    var wrapper = function() {\n                        compare(fileData, secondFileData);\n                    };\n\n                    wrapper();\n\n                    return getCompareApi(wrapper);\n                }\n            };\n\n            return self;\n        }\n\n        var rootSelf = {\n            onComplete: function(callback) {\n                updateCallbackArray.push(callback);\n                loadImageData(fileData, function(imageData, width, height) {\n                    parseImage(imageData.data, width, height);\n                });\n            },\n            compareTo: function(secondFileData) {\n                return getCompareApi(secondFileData);\n            },\n            outputSettings: function(options) {\n                outputSettings(options);\n                return rootSelf;\n            }\n        };\n        return rootSelf;\n    };\n\n    function applyIgnore(api, ignore) {\n        switch (ignore) {\n            case \"nothing\":\n                api.ignoreNothing();\n                break;\n            case \"less\":\n                api.ignoreLess();\n                break;\n            case \"antialiasing\":\n                api.ignoreAntialiasing();\n                break;\n            case \"colors\":\n                api.ignoreColors();\n                break;\n            case \"alpha\":\n                api.ignoreAlpha();\n                break;\n            default:\n                throw new Error(\"Invalid ignore: \" + ignore);\n        }\n    }\n\n    resemble.compare = function(image1, image2, options, cb) {\n        var callback;\n        var opt;\n\n        if (typeof options === \"function\") {\n            callback = options;\n            opt = {};\n        } else {\n            callback = cb;\n            opt = options || {};\n        }\n\n        var res = resemble(image1);\n        var compare;\n\n        if (opt.output) {\n            res.outputSettings(opt.output);\n        }\n\n        compare = res.compareTo(image2);\n\n        if (opt.scaleToSameSize) {\n            compare.scaleToSameSize();\n        }\n\n        if (typeof opt.ignore === \"string\") {\n            applyIgnore(compare, opt.ignore);\n        } else if (opt.ignore && opt.ignore.forEach) {\n            opt.ignore.forEach(function(v) {\n                applyIgnore(compare, v);\n            });\n        }\n\n        compare.onComplete(function(data) {\n            if (data.error) {\n                callback(data.error);\n            } else {\n                callback(null, data);\n            }\n        });\n    };\n\n    resemble.outputSettings = setGlobalOutputSettings;\n    return resemble;\n});\n"
  },
  {
    "path": "clients/weu/README.md",
    "content": "This client is used to recover old maps that were created in 3rd party World Editor applications, such as World Editor Unlimited (hence WEU).\nThese 3rd party editors add custom GUI events, conditions, and actions, which cannot be read by the vanila editor, and cause it to crash.\nSince such 3rd party editors are more or less dead nowadays, it means maps made with them are no longer editable.\nThe weu utility code is used to look for and convert such things back to vanila, when possible, using multiple different tricks.\nIncidently, it can also mostly convert maps made with the Chinese YDWE editor back to something vanila can read (most likely some manual user actions needed, based on the maps).\nWhen given a campaign, this conversion will run for every map in it.\nNOTE: for technical reasons, this only works for TFT maps, aka W3X files.\n"
  },
  {
    "path": "clients/weu/TriggerDataCustom.txt",
    "content": "[TriggerParams]\n\nUnitStateMaxLifeSec=0,unitstate,UNIT_STATE_MAX_LIFE,WESTRING_USTATE_MAXLIFE\n\nSaveLoadOp0=0,integer,0,\"0\"\nSaveLoadOp1=0,integer,1,\"1\"\nSaveLoadOp2=0,integer,2,\"2\"\nSaveLoadOp3=0,integer,3,\"3\"\nSaveLoadOp4=0,integer,4,\"4\"\nSaveLoadOp5=0,integer,5,\"5\"\nSaveLoadOp6=0,integer,6,\"6\"\n\n[TriggerEvents]\n\n[TriggerConditions]\n\n[TriggerActions]\n\n; WchnHidePlayerUnit=0\n\n; WchnSetUnitName=0,unit,string\n; WchnUnitAddBang=0,unit\n; WchnUnitRemoveBang=0,unit\n; WchnUnitAddDes=0,unit,boolean\n; WchnUnitRemoveDes=0,unit\n\n; WchnPauseAllUnit=0\n; WchnResumeAllUnit=0\n\n; WchnAddQuestItem=0,AnyType,AnyType,AnyType\n; WchnFindQuest=0,AnyType\n; WchnUpdtQuest=0,AnyType\n; WchnNewQuestReq=0,AnyType,string,AnyType\n\n; WchnCpltQuest=0,AnyType\n; WchnCpltQuestReq=0,AnyType,AnyType\n\n; WchnDirectMov=0,camerasetup\n; WchnStartMov=0,camerasetup\n; WchnEndMov=0,camerasetup\n\n; WchnPanCmr=0,camerasetup,real,boolean\n; WchnChangeCmr=0,camerasetup\n\n; WchnEndMovCmrBack=0\n\n; WchnWait=0,real\n\n; WchnF2U=0,unit,unit,boolean\n; WchnGoToF2U=0,unit,region,unit\n; WchnGoTo=0,unit,region,boolean\n\n; WchnDlg=0,unit,string,string\n; WchnClearDlg=0\n; WchnDlgAT=0,unit,string,string\n\n; WchnHint=0,string\n\n; WchnEnableSkip=0\n; WchnDisableSkip=0\n\n; WchnWarn=0,string\n; WchnError=0,string\n\n; WchnFadeIn=0,real\n; WchnFadeOut=0,real\n\n[TriggerCalls]\n\n; WchnNewQuest=0,1,AnyType,string,string,boolean,string\n\n; \"Map protection\"\n             =0,1,AnyType,AnyType\n                    =0,1,AnyType,AnyType\n                       =0,1,AnyType,AnyType\n                           =0,1,AnyType,AnyType\n                                  =0,1,AnyType,AnyType\n"
  },
  {
    "path": "clients/weu/TriggerDataPTR129.txt",
    "content": "//***************************************************************************\n[TriggerCategories]\n// Defines categories for organizing trigger functions\n// Key: Arbitrary category identifier\n// Value 0: Display text\n// Value 1: Icon image file\n// Value 2: Optional flag (defaults to 0) indicating to disable display of category name\n//\n\nTC_ARITHMETIC=WESTRING_TRIGCAT_ARITHMETIC,ReplaceableTextures\\WorldEditUI\\Actions-AI,1\nTC_NOTHING=WESTRING_TRIGCAT_NOTHING,ReplaceableTextures\\WorldEditUI\\Actions-Nothing,1\nTC_COMMENT=WESTRING_TRIGCAT_COMMENT,ReplaceableTextures\\WorldEditUI\\Actions-Comment,1\nTC_CUSTOM=WESTRING_TRIGCAT_CUSTOM,ReplaceableTextures\\WorldEditUI\\Actions-Nothing,1\nTC_CONDITION=WESTRING_TRIGCAT_CONDITION,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_WAIT=WESTRING_TRIGCAT_WAIT,ReplaceableTextures\\WorldEditUI\\Actions-Wait,1\nTC_SETVARIABLE=WESTRING_TRIGCAT_SETVARIABLE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables,1\nTC_SKIPACTIONS=WESTRING_TRIGCAT_SKIPACTIONS,ReplaceableTextures\\WorldEditUI\\Actions-Nothing,1\nTC_LOGIC=WESTRING_TRIGCAT_LOGIC,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_FORLOOP=WESTRING_TRIGCAT_FORLOOP,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_LAST=WESTRING_TRIGCAT_LAST,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables,1\nTC_AI=WESTRING_TRIGCAT_AI,ReplaceableTextures\\WorldEditUI\\Actions-AI\nTC_ANIMATION=WESTRING_TRIGCAT_ANIMATION,ReplaceableTextures\\WorldEditUI\\Actions-Animation\nTC_CAMERA=WESTRING_TRIGCAT_CAMERA,ReplaceableTextures\\WorldEditUI\\Actions-Camera\nTC_CINEMATIC=WESTRING_TRIGCAT_CINEMATIC,ReplaceableTextures\\WorldEditUI\\Actions-Camera\nTC_CONVERSION=WESTRING_TRIGCAT_CONVERSION,ReplaceableTextures\\WorldEditUI\\Actions-AI\nTC_TIMER=WESTRING_TRIGCAT_TIMER,ReplaceableTextures\\WorldEditUI\\Events-Time\nTC_DESTRUCT=WESTRING_TRIGCAT_DESTRUCT,ReplaceableTextures\\WorldEditUI\\Actions-Destructibles\nTC_DIALOG=WESTRING_TRIGCAT_DIALOG,ReplaceableTextures\\WorldEditUI\\Actions-Dialog\nTC_ENVIRONMENT=WESTRING_TRIGCAT_ENVIRONMENT,ReplaceableTextures\\WorldEditUI\\Actions-Environment\nTC_EVENTRESPONSE=WESTRING_TRIGCAT_EVENTRESPONSE,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_TEXTTAG=WESTRING_TRIGCAT_TEXTTAG,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_GAME=WESTRING_TRIGCAT_GAME,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_GAMECACHE=WESTRING_TRIGCAT_GAMECACHE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables\nTC_HASHTABLE=WESTRING_TRIGCAT_HASHTABLE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables\nTC_HERO=WESTRING_TRIGCAT_HERO,ReplaceableTextures\\WorldEditUI\\Actions-Hero\nTC_ITEM=WESTRING_TRIGCAT_ITEM,ReplaceableTextures\\WorldEditUI\\Actions-Item\nTC_IMAGE=WESTRING_TRIGCAT_IMAGE,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_LEADERBOARD=WESTRING_TRIGCAT_LEADERBOARD,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_LIGHTNING=WESTRING_TRIGCAT_LIGHTNING,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_MATH=WESTRING_TRIGCAT_MATH,ReplaceableTextures\\WorldEditUI\\Actions-Logical\nTC_MELEE=WESTRING_TRIGCAT_MELEE,ReplaceableTextures\\WorldEditUI\\Actions-Melee\nTC_MULTIBOARD=WESTRING_TRIGCAT_MULTIBOARD,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_NEUTRALBUILDING=WESTRING_TRIGCAT_NEUTRALBUILDING,ReplaceableTextures\\WorldEditUI\\Actions-Goldmine\nTC_PLAYER=WESTRING_TRIGCAT_PLAYER,ReplaceableTextures\\WorldEditUI\\Actions-Player\nTC_PLAYERGROUP=WESTRING_TRIGCAT_PLAYERGROUP,ReplaceableTextures\\WorldEditUI\\Actions-PlayerGroup\nTC_QUEST=WESTRING_TRIGCAT_QUEST,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_REGION=WESTRING_TRIGCAT_REGION,ReplaceableTextures\\WorldEditUI\\Actions-Region\nTC_UNITSEL=WESTRING_TRIGCAT_UNITSEL,ReplaceableTextures\\WorldEditUI\\Actions-UnitSelection\nTC_SOUND=WESTRING_TRIGCAT_SOUND,ReplaceableTextures\\WorldEditUI\\Actions-Sound\nTC_SPECIALEFFECT=WESTRING_TRIGCAT_SPECIALEFFECT,ReplaceableTextures\\WorldEditUI\\Actions-Animation\nTC_TIME=WESTRING_TRIGCAT_TIME,ReplaceableTextures\\WorldEditUI\\Events-Time\nTC_TRIGGER=WESTRING_TRIGCAT_TRIGGER,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_UNIT=WESTRING_TRIGCAT_UNIT,ReplaceableTextures\\WorldEditUI\\Actions-Unit\nTC_UNITGROUP=WESTRING_TRIGCAT_UNITGROUP,ReplaceableTextures\\WorldEditUI\\Actions-UnitGroup\nTC_UBERSPLAT=WESTRING_TRIGCAT_UBERSPLAT,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_VISIBILITY=WESTRING_TRIGCAT_VISIBILITY,ReplaceableTextures\\WorldEditUI\\Actions-Visibility\n//%%% DEBUG - Remove for retail\n//TC_OBSOLETE=WESTRING_TRIGCAT_OBSOLETE,ReplaceableTextures\\WorldEditUI\\Editor-TriggerFunction\n//TC_DEBUG=WESTRING_TRIGCAT_DEBUG,ReplaceableTextures\\WorldEditUI\\Editor-TriggerFunction\n\n// AI Editor only\nTC_AI_TOWN=WESTRING_TRIGCAT_AI_TOWN,none\nTC_AI_HERO=WESTRING_TRIGCAT_AI_HERO,none\nTC_AI_RESOURCES=WESTRING_TRIGCAT_AI_RESOURCES,none\nTC_AI_MISC=WESTRING_TRIGCAT_AI_MISC,none\nTC_AI_UNIT=WESTRING_TRIGCAT_AI_UNIT,none\nTC_AI_UPGRADE=WESTRING_TRIGCAT_AI_UPGRADE,none\nTC_AI_COMMAND=WESTRING_TRIGCAT_AI_COMMAND,none\n\n//***************************************************************************\n[TriggerTypes]\n// Defines all trigger variable types to be used by the Script Editor\n// Key: type name\n// Value 0: first game version in which this type is valid\n// Value 1: flag (0 or 1) indicating if this type can be a global variable\n// Value 2: flag (0 or 1) indicating if this type can be used with comparison operators\n// Value 3: string to display in the editor\n// Value 4: base type, used only for custom types\n// Value 5: import type, for strings which represent files (optional)\n// Value 6: flag (0 or 1) indicating to treat this type as the base type in the editor\n\n// Trigger Variable Types\n// These are sorted so that they appear as such in the Variables dialog.\nabilcode=0,1,1,WESTRING_TRIGTYPE_abilcode,integer\nattacktype=1,1,1,WESTRING_TRIGTYPE_attacktype\nboolean=0,1,1,WESTRING_TRIGTYPE_boolean\nbuffcode=1,1,1,WESTRING_TRIGTYPE_buffcode,integer\ncamerasetup=0,1,0,WESTRING_TRIGTYPE_camerasetup\nweapontype=1,1,1,WESTRING_TRIGTYPE_weapontype\ndamagetype=1,1,1,WESTRING_TRIGTYPE_damagetype\ndestructable=0,1,1,WESTRING_TRIGTYPE_destructable\ndestructablecode=0,1,1,WESTRING_TRIGTYPE_destructablecode,integer\ndefeatcondition=0,1,0,WESTRING_TRIGTYPE_defeatcondition\ndialog=0,1,0,WESTRING_TRIGTYPE_dialog\nbutton=0,1,0,WESTRING_TRIGTYPE_button\neffecttype=1,1,1,WESTRING_TRIGTYPE_effecttype\ntexttag=1,1,0,WESTRING_TRIGTYPE_texttag\ngamecache=0,1,0,WESTRING_TRIGTYPE_gamecache\ngamespeed=0,1,1,WESTRING_TRIGTYPE_gamespeed\nhandle=0,1,0,WESTRING_TRIGTYPE_handle\nhashtable=0,1,0,WESTRING_TRIGTYPE_hashtable\nimage=1,1,1,WESTRING_TRIGTYPE_image\nimagetype=1,1,1,WESTRING_TRIGTYPE_imagetype,integer\ninteger=0,1,1,WESTRING_TRIGTYPE_integer\nitem=0,1,1,WESTRING_TRIGTYPE_item\nitemtype=1,1,1,WESTRING_TRIGTYPE_itemtype\nitemcode=0,1,1,WESTRING_TRIGTYPE_itemcode,integer\nleaderboard=0,1,0,WESTRING_TRIGTYPE_leaderboard\nlightning=1,1,1,WESTRING_TRIGTYPE_lightning\nlightningtype=1,1,1,WESTRING_TRIGTYPE_lightningtype,string\nmultiboard=1,1,0,WESTRING_TRIGTYPE_multiboard\nordercode=0,1,1,WESTRING_TRIGTYPE_ordercode,integer\nplayer=0,1,1,WESTRING_TRIGTYPE_player\nplayercolor=0,1,1,WESTRING_TRIGTYPE_playercolor\nforce=0,1,0,WESTRING_TRIGTYPE_force\nlocation=0,1,1,WESTRING_TRIGTYPE_location\npathingtype=1,1,1,WESTRING_TRIGTYPE_pathingtype\nquest=0,1,0,WESTRING_TRIGTYPE_quest\nquestitem=0,1,0,WESTRING_TRIGTYPE_questitem\nrace=0,1,1,WESTRING_TRIGTYPE_race\nreal=0,1,1,WESTRING_TRIGTYPE_real\nrect=0,1,1,WESTRING_TRIGTYPE_rect\nsound=0,1,0,WESTRING_TRIGTYPE_sound\nsoundtype=1,1,1,WESTRING_TRIGTYPE_soundtype\neffect=0,1,0,WESTRING_TRIGTYPE_effect\nstring=0,1,1,WESTRING_TRIGTYPE_string\ntechcode=0,1,1,WESTRING_TRIGTYPE_techcode,integer\nterraindeformation=1,1,0,WESTRING_TRIGTYPE_terraindeformation\nterrainshape=1,1,1,WESTRING_TRIGTYPE_terrainshape,integer\nterraintype=1,1,1,WESTRING_TRIGTYPE_terraintype,integer\ntimer=0,1,0,WESTRING_TRIGTYPE_timer\ntimerdialog=0,1,0,WESTRING_TRIGTYPE_timerdialog\ntrigger=0,1,1,WESTRING_TRIGTYPE_trigger\nubersplat=1,1,1,WESTRING_TRIGTYPE_ubersplat\nubersplattype=1,1,1,WESTRING_TRIGTYPE_ubersplattype,string\nunit=0,1,1,WESTRING_TRIGTYPE_unit\ngroup=0,1,0,WESTRING_TRIGTYPE_group\nunitcode=0,1,1,WESTRING_TRIGTYPE_unitcode,integer\nfogmodifier=0,1,0,WESTRING_TRIGTYPE_fogmodifier\nweathereffect=0,1,0,WESTRING_TRIGTYPE_weathereffect\n\n// Trigger Non-Variable Types - Atomic (built-in to the language)\ncode=0,0,0,WESTRING_TRIGTYPE_code\n\n// Trigger Non-Variable Types - Basic (from common.j)\nevent=0,0,0,WESTRING_TRIGTYPE_event\ntriggercondition=0,0,0,WESTRING_TRIGTYPE_triggercondition\ntriggeraction=0,0,0,WESTRING_TRIGTYPE_triggeraction\nboolexpr=0,0,0,WESTRING_TRIGTYPE_boolexpr\nunittype=0,0,0,WESTRING_TRIGTYPE_unittype\nalliancetype=0,0,0,WESTRING_TRIGTYPE_alliancetype\nplayerstate=0,0,0,WESTRING_TRIGTYPE_playerstate\nplayerscore=1,0,0,WESTRING_TRIGTYPE_playerscore\nplayergameresult=0,0,0,WESTRING_TRIGTYPE_playergameresult\nunitstate=0,0,0,WESTRING_TRIGTYPE_unitstate\nplayerunitevent=0,0,0,WESTRING_TRIGTYPE_playerunitevent\nunitevent=0,0,0,WESTRING_TRIGTYPE_unitevent\nlimitop=0,0,0,WESTRING_TRIGTYPE_limitop\ngamedifficulty=0,0,1,WESTRING_TRIGTYPE_gamedifficulty\ngameevent=1,0,0,WESTRING_TRIGTYPE_gameevent\naidifficulty=0,0,1,WESTRING_TRIGTYPE_aidifficulty\nmapdensity=0,0,1,WESTRING_TRIGTYPE_mapdensity\nmapcontrol=0,0,1,WESTRING_TRIGTYPE_mapcontrol\nmapflag=0,0,0,WESTRING_TRIGTYPE_mapflag\nplayerslotstate=0,0,1,WESTRING_TRIGTYPE_playerslotstate\ncamerafield=0,0,0,WESTRING_TRIGTYPE_camerafield\nraritycontrol=0,0,0,WESTRING_TRIGTYPE_raritycontrol\nblendmode=0,0,0,WESTRING_TRIGTYPE_blendmode\nfogstate=0,0,0,WESTRING_TRIGTYPE_fogstate\nvolumegroup=0,0,0,WESTRING_TRIGTYPE_volumegroup\n\n// Trigger Non-Variable Types - Utility, only used to simplify triggers\nkeyeventtype=1,0,0,WESTRING_TRIGTYPE_keyeventtype,integer\nkeyeventkey=1,0,0,WESTRING_TRIGTYPE_keyeventkey,integer\nmouseeventtype=1,0,0,WESTRING_TRIGTYPE_mouseeventtype,integer\nmousebuttontype=1,1,1,WESTRING_TRIGTYPE_mousebuttontype,integer\ncolorchangeoption=0,0,0,WESTRING_TRIGTYPE_colorchangeoption,boolean\nplayerchangecoloroption=0,0,0,WESTRING_TRIGTYPE_playerchangecoloroption,boolean\nchatmatchtype=0,0,0,WESTRING_TRIGTYPE_chatmatchtype,boolean\nunitfacingbone=0,0,0,WESTRING_TRIGTYPE_unitfacingbone,string\nincludeoption=0,0,0,WESTRING_TRIGTYPE_inclusionoption,boolean\ncameraapplyoption=0,0,0,WESTRING_TRIGTYPE_cameraapplyoption,boolean\ncameraorientationoption=0,0,0,WESTRING_TRIGTYPE_cameraorientationoption,boolean\ninvulnerableoption=0,0,0,WESTRING_TRIGTYPE_invulnerableoption,boolean\navailabilityoption=0,0,0,WESTRING_TRIGTYPE_availabilityoption,boolean\nshowhideoption=0,0,0,WESTRING_TRIGTYPE_showhideoption,boolean\nminimizeoption=1,0,0,WESTRING_TRIGTYPE_minimizeoption,boolean\nskymodelstring=0,0,0,WESTRING_TRIGTYPE_skymodelstring,string,Model\ncinefiltertexture=0,0,0,WESTRING_TRIGTYPE_cinefiltertexture,string,Image\npathingoption=0,0,0,WESTRING_TRIGTYPE_pathingoption,boolean\npawnableoption=1,0,0,WESTRING_TRIGTYPE_pawnableoption,boolean\ndropnodropoption=0,0,0,WESTRING_TRIGTYPE_dropnodropoption,boolean\ndroppableoption=0,0,0,WESTRING_TRIGTYPE_droppableoption,boolean\nbeforeafteroption=0,0,0,WESTRING_TRIGTYPE_beforeafteroption,boolean\nonoffoption=0,0,0,WESTRING_TRIGTYPE_onoffoption,boolean\nenabledisableoption=0,0,0,WESTRING_TRIGTYPE_enabledisableoption,boolean\nenableddisabledoption=0,0,0,WESTRING_TRIGTYPE_enableddisabledoption,boolean\nrescuableoption=0,0,0,WESTRING_TRIGTYPE_rescuableoption,boolean\nallowdontoption=0,0,0,WESTRING_TRIGTYPE_allowdontoption,boolean\nfadedontoption=0,0,0,WESTRING_TRIGTYPE_fadedontoption,boolean\nunitorderutarg=0,0,0,WESTRING_TRIGTYPE_unitorderutarg,string\nunitorderptarg=0,0,0,WESTRING_TRIGTYPE_unitorderptarg,string\nunitorderdtarg=0,0,0,WESTRING_TRIGTYPE_unitorderdtarg,string\nunitorderitarg=1,0,0,WESTRING_TRIGTYPE_unitorderitarg,string\nunitordernotarg=0,0,0,WESTRING_TRIGTYPE_unitordernotarg,string\nheroskillcode=0,0,0,WESTRING_TRIGTYPE_heroskillcode,integer\nweathereffectcode=0,0,0,WESTRING_TRIGTYPE_weathereffectcode,integer\nalliancesetting=0,0,0,WESTRING_TRIGTYPE_alliancesetting,integer\naddsettooption=0,0,0,WESTRING_TRIGTYPE_addsettooption,integer\nmodifymethod=1,0,0,WESTRING_TRIGTYPE_modifymethod,integer\nwaitdontoption=0,0,0,WESTRING_TRIGTYPE_waitdontoption,boolean\ncratertype=1,0,0,WESTRING_TRIGTYPE_cratertype,boolean\nrippletype=1,0,0,WESTRING_TRIGTYPE_rippletype,boolean\ncreateremoveoption=0,0,0,WESTRING_TRIGTYPE_createremoveoption,boolean\naddremoveoption=0,0,0,WESTRING_TRIGTYPE_addremoveoption,boolean\nquesttypeoption=0,0,0,WESTRING_TRIGTYPE_questtypeoption,integer\nquestmessagetype=0,0,0,WESTRING_TRIGTYPE_questmessagetype,integer\nherostat=1,0,0,WESTRING_TRIGTYPE_herostat,integer\ncompletionoption=0,0,0,WESTRING_TRIGTYPE_completionoption,boolean\nfailureoption=0,0,0,WESTRING_TRIGTYPE_failureoption,boolean\ndiscoveredoption=0,0,0,WESTRING_TRIGTYPE_discoveredoption,boolean\npauseresumeoption=0,0,0,WESTRING_TRIGTYPE_pauseresumeoption,boolean\nperiodicoption=0,0,0,WESTRING_TRIGTYPE_periodicoption,boolean\nleaderboardsortoption=0,0,0,WESTRING_TRIGTYPE_leaderboardsortoption,integer\nascendingoption=0,0,0,WESTRING_TRIGTYPE_ascendingoption,boolean\nsleepwakeoption=0,0,0,WESTRING_TRIGTYPE_sleepwakeoption,boolean\npauseunpauseoption=0,0,0,WESTRING_TRIGTYPE_pauseunpauseoption,boolean\nsharedontoption=0,0,0,WESTRING_TRIGTYPE_sharedontoption,boolean\nfadetypeoption=0,0,0,WESTRING_TRIGTYPE_fadetypeoption,boolean\nbufftype=0,0,0,WESTRING_TRIGTYPE_bufftype,integer\nbuffpolarity=1,0,0,WESTRING_TRIGTYPE_buffpolarity,integer\nbuffresist=1,0,0,WESTRING_TRIGTYPE_buffresist,integer\ncameraboundsadjusttype=0,0,0,WESTRING_TRIGTYPE_cameraboundsadjusttype,integer\navailableoption=0,0,0,WESTRING_TRIGTYPE_availableoption,boolean\nexplodedontoption=0,0,0,WESTRING_TRIGTYPE_explodedontoption,boolean\nsuspendresumeoption=0,0,0,WESTRING_TRIGTYPE_suspendresumeoption,boolean\nmissionindex=0,0,0,WESTRING_TRIGTYPE_missionindex,integer\ncampaignindex=0,0,0,WESTRING_TRIGTYPE_campaignindex,integer\ncinematicindex=0,0,0,WESTRING_TRIGTYPE_cinematicindex,integer\nmusictheme=0,0,0,WESTRING_TRIGTYPE_musictheme,string,Sound\nambientthemeday=0,0,0,WESTRING_TRIGTYPE_ambientthemeday,string\nambientthemenight=0,0,0,WESTRING_TRIGTYPE_ambientthemenight,string\nunitstatemethod=0,0,0,WESTRING_TRIGTYPE_unitstatemethod,string\ncheckingignoringoption=0,0,0,WESTRING_TRIGTYPE_checkingignoringoption,string\nplayerflag=0,0,0,WESTRING_TRIGTYPE_playerflag,playerstate\nplayerresource=1,0,0,WESTRING_TRIGTYPE_playerresource,playerstate\ngateoperation=0,0,0,WESTRING_TRIGTYPE_gateoperation,integer\nelevatorwallop=1,0,0,WESTRING_TRIGTYPE_elevatorwallop,boolean\nelevatorwalltype=1,0,0,WESTRING_TRIGTYPE_elevatorwalltype,integer\nuseskipoption=0,0,0,WESTRING_TRIGTYPE_useskipoption,boolean\nseldeseloption=0,0,0,WESTRING_TRIGTYPE_seldeseloption,boolean\ncachevaluetype=1,0,0,WESTRING_TRIGTYPE_cachevaluetype,integer\nhashtablevaluetype=1,0,0,WESTRING_TRIGTYPE_hashtablevaluetype,integer\nfogstyle=0,0,0,WESTRING_TRIGTYPE_fogstyle,integer\ntimedlifebuffcode=1,0,0,WESTRING_TRIGTYPE_timedlifebuffcode,integer\naicaptaintype=1,0,0,WESTRING_TRIGTYPE_aicaptaintype,boolean\naicommandpop=1,0,0,WESTRING_TRIGTYPE_aicommandpop,boolean\nscriptcode=1,0,0,WESTRING_TRIGTYPE_scriptcode,string\nitemstatus=1,0,0,WESTRING_TRIGTYPE_itemstatus,integer\nitemcodestatus=1,0,0,WESTRING_TRIGTYPE_itemcodestatus,integer\nminimappingstyle=1,0,0,WESTRING_TRIGTYPE_minimappingstyle,integer\ncorpsetype=1,0,0,WESTRING_TRIGTYPE_corpsetype,integer\nstringcaseoption=1,0,0,WESTRING_TRIGTYPE_stringcaseoption,boolean\n\n// Trigger Non-Variable Types - File strings\naiscript=0,0,0,WESTRING_TRIGTYPE_aiscript,string,AIScript,1\nmodelfile=0,0,0,WESTRING_TRIGTYPE_modelfile,string,Model,1\nanyfile=0,0,0,WESTRING_TRIGTYPE_anyfile,string,Any,1\npreloadfile=0,0,0,WESTRING_TRIGTYPE_preloadfile,string,Preload,1\nimagefile=0,0,0,WESTRING_TRIGTYPE_imagefile,string,Image,1\n\n// Trigger Non-Variable Types - Custom (handled internally by the editor)\nStringExt=0,0,0,WESTRING_TRIGTYPE_StringExt,string\nAnyGlobal=0,0,0,WESTRING_TRIGTYPE_AnyGlobal\nAnyType=0,0,0,WESTRING_TRIGTYPE_AnyType\nVarAsString_Real=0,0,0,WESTRING_TRIGTYPE_VarAsString_Real\nArithmeticOperator=0,0,0,WESTRING_TRIGTYPE_ArithmeticOperator\nComparisonOperator=0,0,0,WESTRING_TRIGTYPE_ComparisonOperator\nEqualNotEqualOperator=0,0,0,WESTRING_TRIGTYPE_EqualNotEqualOperator\nboolcall=0,0,0,WESTRING_TRIGTYPE_boolcall\neventcall=1,0,0,WESTRING_TRIGTYPE_eventcall\ndoodadcode=0,0,0,WESTRING_TRIGTYPE_doodadcode,integer\nmusicfile=0,0,0,WESTRING_TRIGTYPE_musicfile,string\nintegervar=1,0,0,WESTRING_TRIGTYPE_integer,integer\n\n\n//***************************************************************************\n[TriggerTypeDefaults]\n// Defines an optional default value for a trigger type used as a global variable\n// Key: variable type\n// Value 0: script text\n// Value 1: display text (if not present, script text will be used)\n//\n// If a type does not have an entry here, it will be set to null if it is a handle\n//\n\nboolean=false,WESTRING_FALSE\ninteger=0\nreal=0\ngroup=CreateGroup(),WESTRING_TRIGDEFAULT_GROUP\nforce=CreateForce(),WESTRING_TRIGDEFAULT_FORCE\ntimer=CreateTimer(),WESTRING_TRIGDEFAULT_TIMER\ndialog=DialogCreate(),WESTRING_TRIGDEFAULT_DIALOG\n\n\n\n//***************************************************************************\n[TriggerParams]\n// Defines possible values for variable types\n// Key: arbitrary text\n// Value 0: first game version in which this parameter is valid\n// Value 1: variable type\n// Value 2: code text (used in script)\n// Value 3: display text\n//\n// Note: If the code text is a literal string, surround it with backward single quotes (`),\n//       and they will be converted to double quotes in the script.\n//\n\n// Operators\nOperatorAdd=0,ArithmeticOperator,\"+\",WESTRING_ARITHMETICOPERATOR_ADD\nOperatorSubtract=0,ArithmeticOperator,\"-\",WESTRING_ARITHMETICOPERATOR_SUBTRACT\nOperatorMultiply=0,ArithmeticOperator,\"*\",WESTRING_ARITHMETICOPERATOR_MULTIPLY\nOperatorDivide=0,ArithmeticOperator,\"/\",WESTRING_ARITHMETICOPERATOR_DIVIDE\n\nOperatorEqual=0,ComparisonOperator,\"==\",WESTRING_COMPARISONOPERATOR_EQUAL\nOperatorNotEqual=0,ComparisonOperator,\"!=\",WESTRING_COMPARISONOPERATOR_NOTEQUAL\nOperatorGreater=0,ComparisonOperator,\">\",WESTRING_COMPARISONOPERATOR_GREATER\nOperatorGreaterEq=0,ComparisonOperator,\">=\",WESTRING_COMPARISONOPERATOR_GREATEREQ\nOperatorLess=0,ComparisonOperator,\"<\",WESTRING_COMPARISONOPERATOR_LESS\nOperatorLessEq=0,ComparisonOperator,\"<=\",WESTRING_COMPARISONOPERATOR_LESSEQ\n\nOperatorEqualENE=0,EqualNotEqualOperator,\"==\",WESTRING_EQUALNOTEQUALOPERATOR_EQUAL\nOperatorNotEqualENE=0,EqualNotEqualOperator,\"!=\",WESTRING_EQUALNOTEQUALOPERATOR_NOTEQUAL\n\n// Reals\nRealQueueDelayQuest=0,real,bj_QUEUE_DELAY_QUEST,WESTRING_QUEUE_DELAY_QUEST\nRealQueueDelayHint=0,real,bj_QUEUE_DELAY_HINT,WESTRING_QUEUE_DELAY_HINT\nRealQueueDelaySecret=0,real,bj_QUEUE_DELAY_SECRET,WESTRING_QUEUE_DELAY_SECRET\nRealHandicapEasy=0,real,bj_HANDICAP_EASY,WESTRING_HANDICAP_EASY\nRealCellWidth=0,real,bj_CELLWIDTH,WESTRING_REAL_CELLWIDTH\nRealUnitFacing=0,real,bj_UNIT_FACING,WESTRING_REAL_UNITFACING\nRealCamDefDistance=0,real,bj_CAMERA_DEFAULT_DISTANCE,WESTRING_CAMDEFAULT_DISTANCE\nRealCamDefFarZ=0,real,bj_CAMERA_DEFAULT_FARZ,WESTRING_CAMDEFAULT_FARZ\nRealCamDefAoA=0,real,bj_CAMERA_DEFAULT_AOA,WESTRING_CAMDEFAULT_AOA\nRealCamDefFoV=0,real,bj_CAMERA_DEFAULT_FOV,WESTRING_CAMDEFAULT_FOV\nRealCamDefRoll=0,real,bj_CAMERA_DEFAULT_ROLL,WESTRING_CAMDEFAULT_ROLL\nRealCamDefRotation=0,real,bj_CAMERA_DEFAULT_ROTATION,WESTRING_CAMDEFAULT_ROTATION\nRealE=0,real,bj_E,WESTRING_REAL_E\nRealPi=0,real,bj_PI,WESTRING_REAL_PI\n\n// Players\nPlayer00=0,player,Player(0),WESTRING_PLAYER_00\nPlayer01=0,player,Player(1),WESTRING_PLAYER_01\nPlayer02=0,player,Player(2),WESTRING_PLAYER_02\nPlayer03=0,player,Player(3),WESTRING_PLAYER_03\nPlayer04=0,player,Player(4),WESTRING_PLAYER_04\nPlayer05=0,player,Player(5),WESTRING_PLAYER_05\nPlayer06=0,player,Player(6),WESTRING_PLAYER_06\nPlayer07=0,player,Player(7),WESTRING_PLAYER_07\nPlayer08=0,player,Player(8),WESTRING_PLAYER_08\nPlayer09=0,player,Player(9),WESTRING_PLAYER_09\nPlayer10=0,player,Player(10),WESTRING_PLAYER_10\nPlayer11=0,player,Player(11),WESTRING_PLAYER_11\nPlayer12=0,player,Player(12),WESTRING_PLAYER_12\nPlayer13=0,player,Player(13),WESTRING_PLAYER_13\nPlayer14=0,player,Player(14),WESTRING_PLAYER_14\nPlayer15=0,player,Player(15),WESTRING_PLAYER_15\nPlayer16=0,player,Player(16),WESTRING_PLAYER_16\nPlayer17=0,player,Player(17),WESTRING_PLAYER_17\nPlayer18=0,player,Player(18),WESTRING_PLAYER_18\nPlayer19=0,player,Player(19),WESTRING_PLAYER_19\nPlayer20=0,player,Player(20),WESTRING_PLAYER_20\nPlayer21=0,player,Player(21),WESTRING_PLAYER_21\nPlayer22=0,player,Player(22),WESTRING_PLAYER_22\nPlayer23=0,player,Player(23),WESTRING_PLAYER_23\nPlayerNA=0,player,Player(PLAYER_NEUTRAL_AGGRESSIVE),WESTRING_PLAYER_NA\nPlayerNV=0,player,Player(bj_PLAYER_NEUTRAL_VICTIM),WESTRING_PLAYER_NV\nPlayerNE=0,player,Player(bj_PLAYER_NEUTRAL_EXTRA),WESTRING_PLAYER_NE\nPlayerNP=0,player,Player(PLAYER_NEUTRAL_PASSIVE),WESTRING_PLAYER_NP\n\n// Forces\nForce00=0,force,bj_FORCE_PLAYER[0],WESTRING_FORCE_00\nForce01=0,force,bj_FORCE_PLAYER[1],WESTRING_FORCE_01\nForce02=0,force,bj_FORCE_PLAYER[2],WESTRING_FORCE_02\nForce03=0,force,bj_FORCE_PLAYER[3],WESTRING_FORCE_03\nForce04=0,force,bj_FORCE_PLAYER[4],WESTRING_FORCE_04\nForce05=0,force,bj_FORCE_PLAYER[5],WESTRING_FORCE_05\nForce06=0,force,bj_FORCE_PLAYER[6],WESTRING_FORCE_06\nForce07=0,force,bj_FORCE_PLAYER[7],WESTRING_FORCE_07\nForce08=0,force,bj_FORCE_PLAYER[8],WESTRING_FORCE_08\nForce09=0,force,bj_FORCE_PLAYER[9],WESTRING_FORCE_09\nForce10=0,force,bj_FORCE_PLAYER[10],WESTRING_FORCE_10\nForce11=0,force,bj_FORCE_PLAYER[11],WESTRING_FORCE_11\nForce12=0,force,bj_FORCE_PLAYER[12],WESTRING_FORCE_12\nForce13=0,force,bj_FORCE_PLAYER[13],WESTRING_FORCE_13\nForce14=0,force,bj_FORCE_PLAYER[14],WESTRING_FORCE_14\nForce15=0,force,bj_FORCE_PLAYER[15],WESTRING_FORCE_15\nForce16=0,force,bj_FORCE_PLAYER[16],WESTRING_FORCE_16\nForce17=0,force,bj_FORCE_PLAYER[17],WESTRING_FORCE_17\nForce18=0,force,bj_FORCE_PLAYER[18],WESTRING_FORCE_18\nForce19=0,force,bj_FORCE_PLAYER[19],WESTRING_FORCE_19\nForce20=0,force,bj_FORCE_PLAYER[20],WESTRING_FORCE_20\nForce21=0,force,bj_FORCE_PLAYER[21],WESTRING_FORCE_21\nForce22=0,force,bj_FORCE_PLAYER[22],WESTRING_FORCE_22\nForce23=0,force,bj_FORCE_PLAYER[23],WESTRING_FORCE_23\nForceNA=0,force,bj_FORCE_PLAYER[PLAYER_NEUTRAL_AGGRESSIVE],WESTRING_FORCE_NA\nForceNV=0,force,bj_FORCE_PLAYER[bj_PLAYER_NEUTRAL_VICTIM],WESTRING_FORCE_NV\nForceNE=0,force,bj_FORCE_PLAYER[bj_PLAYER_NEUTRAL_EXTRA],WESTRING_FORCE_NE\nForceNP=0,force,bj_FORCE_PLAYER[PLAYER_NEUTRAL_PASSIVE],WESTRING_FORCE_NP\n\n// Player colors\nColor00=0,playercolor,PLAYER_COLOR_RED,WESTRING_UNITCOLOR_00\nColor01=0,playercolor,PLAYER_COLOR_BLUE,WESTRING_UNITCOLOR_01\nColor02=0,playercolor,PLAYER_COLOR_CYAN,WESTRING_UNITCOLOR_02\nColor03=0,playercolor,PLAYER_COLOR_PURPLE,WESTRING_UNITCOLOR_03\nColor04=0,playercolor,PLAYER_COLOR_YELLOW,WESTRING_UNITCOLOR_04\nColor05=0,playercolor,PLAYER_COLOR_ORANGE,WESTRING_UNITCOLOR_05\nColor06=0,playercolor,PLAYER_COLOR_GREEN,WESTRING_UNITCOLOR_06\nColor07=0,playercolor,PLAYER_COLOR_PINK,WESTRING_UNITCOLOR_07\nColor08=0,playercolor,PLAYER_COLOR_LIGHT_GRAY,WESTRING_UNITCOLOR_08\nColor09=0,playercolor,PLAYER_COLOR_LIGHT_BLUE,WESTRING_UNITCOLOR_09\nColor10=0,playercolor,PLAYER_COLOR_AQUA,WESTRING_UNITCOLOR_10\nColor11=0,playercolor,PLAYER_COLOR_BROWN,WESTRING_UNITCOLOR_11\nColor12=1,playercolor,ConvertPlayerColor(12),WESTRING_UNITCOLOR_12\n\n// Races\nRaceHuman=0,race,RACE_HUMAN,WESTRING_TRIGRACE_HUMAN\nRaceOrc=0,race,RACE_ORC,WESTRING_TRIGRACE_ORC\nRaceUndead=0,race,RACE_UNDEAD,WESTRING_TRIGRACE_UNDEAD\nRaceNightElf=0,race,RACE_NIGHTELF,WESTRING_TRIGRACE_NIGHTELF\nRaceDemon=0,race,RACE_DEMON,WESTRING_TRIGRACE_DEMON\n\n// Item Classes\nItemTypeAny=1,itemtype,ITEM_TYPE_ANY,WESTRING_ITEMTYPE_ANY\nItemTypePermanent=1,itemtype,ITEM_TYPE_PERMANENT,WESTRING_ITEMTYPE_PERMANENT\nItemTypeCharged=1,itemtype,ITEM_TYPE_CHARGED,WESTRING_ITEMTYPE_CHARGED\nItemTypePowerup=1,itemtype,ITEM_TYPE_POWERUP,WESTRING_ITEMTYPE_POWERUP\nItemTypeArtifact=1,itemtype,ITEM_TYPE_ARTIFACT,WESTRING_ITEMTYPE_ARTIFACT\nItemTypePurchasable=1,itemtype,ITEM_TYPE_PURCHASABLE,WESTRING_ITEMTYPE_PURCHASABLE\nItemTypeCampaign=1,itemtype,ITEM_TYPE_CAMPAIGN,WESTRING_ITEMTYPE_CAMPAIGN\nItemTypeMiscellaneous=1,itemtype,ITEM_TYPE_MISCELLANEOUS,WESTRING_ITEMTYPE_MISCELLANEOUS\nItemTypeUnknown=1,itemtype,ITEM_TYPE_UNKNOWN,WESTRING_ITEMTYPE_UNKNOWN\n\n// Units\nUnitNull=0,unit,null,WESTRING_TRIGUNIT_NULL\n\n// Unit-Types\nUnitTypeNull=0,unitcode,0,WESTRING_TRIGUNITTYPE_NULL\n\n// Items\nItemNull=0,item,null,WESTRING_TRIGITEM_NULL\n\n// Destructables\nDestructableNull=0,destructable,null,WESTRING_TRIGDESTRUCTABLE_NULL\n\n// Rects\nRectNull=0,rect,null,WESTRING_TRIGRECT_NULL\n\n// Sounds\nSoundNull=0,sound,null,WESTRING_TRIGSOUND_NULL\n\n// Music\nMusicFileMusic=0,musicfile,`music`,WESTRING_TRIGMUSICFILE_MUSIC\n\n// Limit operators\nLimitOpEqual=0,limitop,EQUAL,WESTRING_LIMITOP_EQUAL\nLimitOpNotEqual=0,limitop,NOT_EQUAL,WESTRING_LIMITOP_NOTEQUAL\nLimitOpLessThan=0,limitop,LESS_THAN,WESTRING_LIMITOP_LESSTHAN\nLimitOpLessThanOrEqual=0,limitop,LESS_THAN_OR_EQUAL,WESTRING_LIMITOP_LESSTHANOREQUAL\nLimitOpGreaterThan=0,limitop,GREATER_THAN,WESTRING_LIMITOP_GREATERTHAN\nLimitOpGreaterThanOrEqual=0,limitop,GREATER_THAN_OR_EQUAL,WESTRING_LIMITOP_GREATERTHANOREQUAL\n\n// Game results\nGameResultWin=0,playergameresult,PLAYER_GAME_RESULT_VICTORY,WESTRING_VICTORY\nGameResultLose=0,playergameresult,PLAYER_GAME_RESULT_DEFEAT,WESTRING_DEFEAT\nGameResultDraw=0,playergameresult,PLAYER_GAME_RESULT_TIE,WESTRING_DRAW\n\n// Map flags\nMapFlagUseHandicaps=0,mapflag,MAP_USE_HANDICAPS,WESTRING_MAPFLAG_USEHANDICAPS\nMapFlagObservers=0,mapflag,MAP_OBSERVERS,WESTRING_MAPFLAG_OBSERVERS\nMapFlagObserversChat=0,mapflag,MAP_OBSERVERS_ON_DEATH,WESTRING_MAPFLAG_OBSERVERSONDEATH\nMapFlagResourceTradingLock=0,mapflag,MAP_LOCK_RESOURCE_TRADING,WESTRING_MAPFLAG_RESOURCETRADINGLOCK\nMapFlagResourceTradingAllies=0,mapflag,MAP_RESOURCE_TRADING_ALLIES_ONLY,WESTRING_MAPFLAG_RESOURCETRADINGALLIES\nMapFlagAllianceChangesLock=0,mapflag,MAP_LOCK_ALLIANCE_CHANGES,WESTRING_MAPFLAG_ALLIANCECHANGESLOCK\nMapFlagAllianceChangesHidden=0,mapflag,MAP_ALLIANCE_CHANGES_HIDDEN,WESTRING_MAPFLAG_ALLIANCECHANGESHIDDEN\nMapFlagMapReloaded=1,mapflag,MAP_RELOADED,WESTRING_MAPFLAG_MAPRELOADED\nMapFlagRandomHeroes=1,mapflag,MAP_RANDOM_HERO,WESTRING_MAPFLAG_RANDOM_HERO\nMapFlagRandomRaces=1,mapflag,MAP_RANDOM_RACES,WESTRING_MAPFLAG_RANDOM_RACES\nMapFlagFogHideTerrain=1,mapflag,MAP_FOG_HIDE_TERRAIN,WESTRING_MAPFLAG_FOG_HIDE_TERRAIN\nMapFlagFogMapExplored=1,mapflag,MAP_FOG_MAP_EXPLORED,WESTRING_MAPFLAG_FOG_MAP_EXPLORED\nMapFlagFogAlwaysVisible=1,mapflag,MAP_FOG_ALWAYS_VISIBLE,WESTRING_MAPFLAG_FOG_ALWAYS_VISIBLE\n\n// Player states\nPlayerStateGold=0,playerstate,PLAYER_STATE_RESOURCE_GOLD,WESTRING_PSTATE_GOLD\nPlayerStateLumber=0,playerstate,PLAYER_STATE_RESOURCE_LUMBER,WESTRING_PSTATE_LUMBER\nPlayerStateHeroTokens=0,playerstate,PLAYER_STATE_RESOURCE_HERO_TOKENS,WESTRING_PSTATE_HEROTOKENS\nPlayerStateGoldUpkeepRate=0,playerstate,PLAYER_STATE_GOLD_UPKEEP_RATE,WESTRING_PSTATE_UPKEEPGOLD\nPlayerStateLumberUpkeepRate=0,playerstate,PLAYER_STATE_LUMBER_UPKEEP_RATE,WESTRING_PSTATE_UPKEEPLUMBER\nPlayerStateGoldGathered=0,playerstate,PLAYER_STATE_GOLD_GATHERED,WESTRING_PSTATE_GOLDGATHERED\nPlayerStateLumberGathered=0,playerstate,PLAYER_STATE_LUMBER_GATHERED,WESTRING_PSTATE_LUMBER_GATHERED\nPlayerStateFoodUsed=0,playerstate,PLAYER_STATE_RESOURCE_FOOD_USED,WESTRING_PSTATE_FOODUSED\nPlayerStateFoodCap=0,playerstate,PLAYER_STATE_RESOURCE_FOOD_CAP,WESTRING_PSTATE_FOODCAP\nPlayerStateFoodLimit=0,playerstate,PLAYER_STATE_FOOD_CAP_CEILING,WESTRING_PSTATE_FOODCAPLIMIT\nPlayerStateGameResult=0,playerstate,PLAYER_STATE_GAME_RESULT,WESTRING_PSTATE_GAMERESULT\n\n// Player states - resources only\nPlayerResourceGold=1,playerresource,PLAYER_STATE_RESOURCE_GOLD,WESTRING_PRESOURCE_GOLD\nPlayerResourceLumber=1,playerresource,PLAYER_STATE_RESOURCE_LUMBER,WESTRING_PRESOURCE_LUMBER\n\n// Player scores\nPlayerScoreUnitsTrained=1,playerscore,PLAYER_SCORE_UNITS_TRAINED,WESTRING_PSCORE_UNITSTRAINED\nPlayerScoreUnitsKilled=1,playerscore,PLAYER_SCORE_UNITS_KILLED,WESTRING_PSCORE_UNITSKILLED\nPlayerScoreStructBuilt=1,playerscore,PLAYER_SCORE_STRUCT_BUILT,WESTRING_PSCORE_STRUCTBUILT\nPlayerScoreStructRazed=1,playerscore,PLAYER_SCORE_STRUCT_RAZED,WESTRING_PSCORE_STRUCTRAZED\nPlayerScoreTechPercent=1,playerscore,PLAYER_SCORE_TECH_PERCENT,WESTRING_PSCORE_TECHPERCENT\nPlayerScoreFoodProd=1,playerscore,PLAYER_SCORE_FOOD_MAXPROD,WESTRING_PSCORE_FOODPROD\nPlayerScoreFoodUsed=1,playerscore,PLAYER_SCORE_FOOD_MAXUSED,WESTRING_PSCORE_FOODUSED\nPlayerScoreHeroesKilled=1,playerscore,PLAYER_SCORE_HEROES_KILLED,WESTRING_PSCORE_HEROESKILLED\nPlayerScoreItemsGained=1,playerscore,PLAYER_SCORE_ITEMS_GAINED,WESTRING_PSCORE_ITEMSGAINED\nPlayerScoreMercsHired=1,playerscore,PLAYER_SCORE_MERCS_HIRED,WESTRING_PSCORE_MERCSHIRED\nPlayerScoreGoldTotal=1,playerscore,PLAYER_SCORE_GOLD_MINED_TOTAL,WESTRING_PSCORE_GOLDTOTAL\nPlayerScoreGoldUpkeep=1,playerscore,PLAYER_SCORE_GOLD_MINED_UPKEEP,WESTRING_PSCORE_GOLDUPKEEP\nPlayerScoreGoldLostUpkeep=1,playerscore,PLAYER_SCORE_GOLD_LOST_UPKEEP,WESTRING_PSCORE_GOLDLOSTUPKEEP\nPlayerScoreGoldLostTax=1,playerscore,PLAYER_SCORE_GOLD_LOST_TAX,WESTRING_PSCORE_GOLDLOSTTAX\nPlayerScoreGoldGiven=1,playerscore,PLAYER_SCORE_GOLD_GIVEN,WESTRING_PSCORE_GOLDGIVEN\nPlayerScoreGoldReceived=1,playerscore,PLAYER_SCORE_GOLD_RECEIVED,WESTRING_PSCORE_GOLDRECEIVED\nPlayerScoreLumberTotal=1,playerscore,PLAYER_SCORE_LUMBER_TOTAL,WESTRING_PSCORE_LUMBERTOTAL\nPlayerScoreLumberLostUpkeep=1,playerscore,PLAYER_SCORE_LUMBER_LOST_UPKEEP,WESTRING_PSCORE_LUMBERLOSTUPKEEP\nPlayerScoreLumberLostTax=1,playerscore,PLAYER_SCORE_LUMBER_LOST_TAX,WESTRING_PSCORE_LUMBERLOSTTAX\nPlayerScoreLumberGiven=1,playerscore,PLAYER_SCORE_LUMBER_GIVEN,WESTRING_PSCORE_LUMBERGIVEN\nPlayerScoreLumberReceived=1,playerscore,PLAYER_SCORE_LUMBER_RECEIVED,WESTRING_PSCORE_LUMBERECEIVED\nPlayerScoreUnitTotal=1,playerscore,PLAYER_SCORE_UNIT_TOTAL,WESTRING_PSCORE_UNITTOTAL\nPlayerScoreHeroTotal=1,playerscore,PLAYER_SCORE_HERO_TOTAL,WESTRING_PSCORE_HEROTOTAL\nPlayerScoreResourceTotal=1,playerscore,PLAYER_SCORE_RESOURCE_TOTAL,WESTRING_PSCORE_RESOURCETOTAL\nPlayerScoreTotal=1,playerscore,PLAYER_SCORE_TOTAL,WESTRING_PSCORE_TOTAL\n\n// Player flags\nPlayerFlagUnfollowable=0,playerflag,PLAYER_STATE_UNFOLLOWABLE,WESTRING_PFLAG_UNFOLLOWABLE\nPlayerFlagGivesBounty=0,playerflag,PLAYER_STATE_GIVES_BOUNTY,WESTRING_PFLAG_GIVESBOUNTY\nPlayerFlagAlliedVictory=0,playerflag,PLAYER_STATE_ALLIED_VICTORY,WESTRING_PFLAG_ALLIEDVICTORY\n\n// Gate states\nGateOperationClosed=0,gateoperation,bj_GATEOPERATION_CLOSE,WESTRING_GATEOPERATION_CLOSE\nGateOperationOpen=0,gateoperation,bj_GATEOPERATION_OPEN,WESTRING_GATEOPERATION_OPEN\nGateOperationDestroyed=0,gateoperation,bj_GATEOPERATION_DESTROY,WESTRING_GATEOPERATION_DESTROY\n\n// Elevator wall operations\nElevatorWallOpClose=1,elevatorwallop,false,WESTRING_ELEVATORWALLOP_CLOSE\nElevatorWallOpOpen=1,elevatorwallop,true,WESTRING_ELEVATORWALLOP_OPEN\n\n// Elevator wall choices\nElevatorWallTypeAll=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_ALL,WESTRING_ELEVATORWALLTYPE_ALL\nElevatorWallTypeEast=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_EAST,WESTRING_ELEVATORWALLTYPE_EAST\nElevatorWallTypeNorth=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_NORTH,WESTRING_ELEVATORWALLTYPE_NORTH\nElevatorWallTypeSouth=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_SOUTH,WESTRING_ELEVATORWALLTYPE_SOUTH\nElevatorWallTypeWest=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_WEST,WESTRING_ELEVATORWALLTYPE_WEST\n\n// Usage options\nUseSkipOptionUse=0,useskipoption,true,WESTRING_USESKIPOPTION_USE\nUseSkipOptionSkip=0,useskipoption,false,WESTRING_USESKIPOPTION_SKIP\n\n// Selection option\nSelDeselOptionSel=0,seldeseloption,true,WESTRING_SELDESELOPTION_SEL\nSelDeselOptionDesel=0,seldeseloption,false,WESTRING_SELDESELOPTION_DESEL\n\n// AI Captain types\nAICaptainAttack=1,aicaptaintype,true,WESTRING_AICAPTAIN_ATTACK\nAICaptainDefense=1,aicaptaintype,false,WESTRING_AICAPTAIN_DEFENSE\n\n// AI Command Pop options\nAICommandPop=1,aicommandpop,true,WESTRING_AICOMMAND_REMOVE\nAICommandLeave=1,aicommandpop,false,WESTRING_AICOMMAND_LEAVE\n\n// Cache value types\nCacheValueTypeBoolean=1,cachevaluetype,bj_GAMECACHE_BOOLEAN,WESTRING_CACHEVALUETYPE_BOOLEAN\nCacheValueTypeInteger=1,cachevaluetype,bj_GAMECACHE_INTEGER,WESTRING_CACHEVALUETYPE_INTEGER\nCacheValueTypeReal=1,cachevaluetype,bj_GAMECACHE_REAL,WESTRING_CACHEVALUETYPE_REAL\nCacheValueTypeUnit=1,cachevaluetype,bj_GAMECACHE_UNIT,WESTRING_CACHEVALUETYPE_UNIT\nCacheValueTypeString=1,cachevaluetype,bj_GAMECACHE_STRING,WESTRING_CACHEVALUETYPE_STRING\n\n// Hashtable value types (localization stolen from gamecache)\nHashtableValueTypeBoolean=1,hashtablevaluetype,bj_HASHTABLE_BOOLEAN,WESTRING_CACHEVALUETYPE_BOOLEAN\nHashtableValueTypeInteger=1,hashtablevaluetype,bj_HASHTABLE_INTEGER,WESTRING_CACHEVALUETYPE_INTEGER\nHashtableValueTypeReal=1,hashtablevaluetype,bj_HASHTABLE_REAL,WESTRING_CACHEVALUETYPE_REAL\nHashtableValueTypeString=1,hashtablevaluetype,bj_HASHTABLE_STRING,WESTRING_CACHEVALUETYPE_STRING\nHashtableValueTypeHandle=1,hashtablevaluetype,bj_HASHTABLE_HANDLE,WESTRING_CACHEVALUETYPE_HANDLE\n\n// Map Control\nMapControlNone=0,mapcontrol,MAP_CONTROL_NONE,WESTRING_MAPCONTROL_NONE\nMapControlUser=0,mapcontrol,MAP_CONTROL_USER,WESTRING_MAPCONTROL_USER\nMapControlComputer=0,mapcontrol,MAP_CONTROL_COMPUTER,WESTRING_MAPCONTROL_COMPUTER\nMapControlRescuable=0,mapcontrol,MAP_CONTROL_RESCUABLE,WESTRING_MAPCONTROL_RESCUABLE\nMapControlNeutral=0,mapcontrol,MAP_CONTROL_NEUTRAL,WESTRING_MAPCONTROL_NEUTRAL\nMapControlCreep=0,mapcontrol,MAP_CONTROL_CREEP,WESTRING_MAPCONTROL_CREEP\n\n// Player slot states\nPlayerSlotStateEmpty=0,playerslotstate,PLAYER_SLOT_STATE_EMPTY,WESTRING_PSLOT_EMPTY\nPlayerSlotStatePlaying=0,playerslotstate,PLAYER_SLOT_STATE_PLAYING,WESTRING_PSLOT_PLAYING\nPlayerSlotStateLeft=0,playerslotstate,PLAYER_SLOT_STATE_LEFT,WESTRING_PSLOT_LEFT\n\n// Player unit events\nPlayerUnitEventDeath=0,playerunitevent,EVENT_PLAYER_UNIT_DEATH,WESTRING_PUEVENT_DEATH\nPlayerUnitEventDecay=0,playerunitevent,EVENT_PLAYER_UNIT_DECAY,WESTRING_PUEVENT_DECAY\nPlayerUnitEventChangesOwner=1,playerunitevent,EVENT_PLAYER_UNIT_CHANGE_OWNER,WESTRING_PUEVENT_CHANGESOWNER\nPlayerUnitEventHero_Level=0,playerunitevent,EVENT_PLAYER_HERO_LEVEL,WESTRING_PUEVENT_HEROLEVEL\nPlayerUnitEventHero_Skill=0,playerunitevent,EVENT_PLAYER_HERO_SKILL,WESTRING_PUEVENT_HEROSKILL\nPlayerUnitEventHero_Revivable=0,playerunitevent,EVENT_PLAYER_HERO_REVIVABLE,WESTRING_PUEVENT_HEROREVIVABLE\nPlayerUnitEventHeroUseItem=0,playerunitevent,EVENT_PLAYER_UNIT_USE_ITEM,WESTRING_PUEVENT_HEROUSEITEM\nPlayerUnitEventHeroPickUpItem=0,playerunitevent,EVENT_PLAYER_UNIT_PICKUP_ITEM,WESTRING_PUEVENT_HEROPICKUPITEM\nPlayerUnitEventHeroDropItem=0,playerunitevent,EVENT_PLAYER_UNIT_DROP_ITEM,WESTRING_PUEVENT_HERODROPITEM\nPlayerUnitEventSell=1,playerunitevent,EVENT_PLAYER_UNIT_SELL,WESTRING_PUEVENT_SELL\nPlayerUnitEventSellItem=1,playerunitevent,EVENT_PLAYER_UNIT_SELL_ITEM,WESTRING_PUEVENT_SELLITEM\nPlayerUnitEventPawnItem=1,playerunitevent,EVENT_PLAYER_UNIT_PAWN_ITEM,WESTRING_PUEVENT_PAWNITEM\nPlayerUnitEventAttacked=0,playerunitevent,EVENT_PLAYER_UNIT_ATTACKED,WESTRING_PUEVENT_ATTACKED\nPlayerUnitEventRescued=0,playerunitevent,EVENT_PLAYER_UNIT_RESCUED,WESTRING_PUEVENT_RESCUED\nPlayerUnitEventSummoned=0,playerunitevent,EVENT_PLAYER_UNIT_SUMMON,WESTRING_PUEVENT_SUMMONED\nPlayerUnitEventSpellChannel=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_CHANNEL,WESTRING_PUEVENT_SPELLCHANNEL\nPlayerUnitEventSpellCast=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_CAST,WESTRING_PUEVENT_SPELLCAST\nPlayerUnitEventSpellEndCast=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_ENDCAST,WESTRING_PUEVENT_SPELLENDCAST\nPlayerUnitEventSpellEffect=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_EFFECT,WESTRING_PUEVENT_SPELLEFFECT\nPlayerUnitEventSpellFinish=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_FINISH,WESTRING_PUEVENT_SPELLFINISH\nPlayerUnitEventLoaded=0,playerunitevent,EVENT_PLAYER_UNIT_LOADED,WESTRING_PUEVENT_LOADED\nPlayerUnitEventTrain_Start=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_START,WESTRING_PUEVENT_TRAINSTART\nPlayerUnitEventTrain_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_CANCEL,WESTRING_PUEVENT_TRAINCANCEL\nPlayerUnitEventTrain_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_FINISH,WESTRING_PUEVENT_TRAINFINISH\nPlayerUnitEventConstruct_Start=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_START,WESTRING_PUEVENT_CONSTRUCTSTART\nPlayerUnitEventConstruct_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL,WESTRING_PUEVENT_CONSTRUCTCANCEL\nPlayerUnitEventConstruct_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_FINISH,WESTRING_PUEVENT_CONSTRUCTFINISH\nPlayerUnitEventReviveStart=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_START,WESTRING_PUEVENT_REVIVESTART\nPlayerUnitEventReviveCancel=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_CANCEL,WESTRING_PUEVENT_REVIVECANCEL\nPlayerUnitEventReviveFinish=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_FINISH,WESTRING_PUEVENT_REVIVEFINISH\nPlayerUnitEventUpgrade_Start=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_START,WESTRING_PUEVENT_UPGRADESTART\nPlayerUnitEventUpgrade_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_CANCEL,WESTRING_PUEVENT_UPGRADECANCEL\nPlayerUnitEventUpgrade_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_FINISH,WESTRING_PUEVENT_UPGRADEFINISH\nPlayerUnitEventResearch_Start=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_START,WESTRING_PUEVENT_RESEARCHSTART\nPlayerUnitEventResearch_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_CANCEL,WESTRING_PUEVENT_RESEARCHCANCEL\nPlayerUnitEventResearch_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_FINISH,WESTRING_PUEVENT_RESEARCHFINISH\nPlayerUnitEventIssued_Unit_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER,WESTRING_PUEVENT_ISSUEDUNITORDER\nPlayerUnitEventIssued_Point_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,WESTRING_PUEVENT_ISSUEDPOINTORDER\nPlayerUnitEventIssued_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_ORDER,WESTRING_PUEVENT_ISSUEDORDER\n\n// Unit events\nUnitEventDeath=0,unitevent,EVENT_UNIT_DEATH,WESTRING_UEVENT_DEATH\nUnitEventDecay=0,unitevent,EVENT_UNIT_DECAY,WESTRING_UEVENT_DECAY\nUnitEventChangesOwner=1,unitevent,EVENT_UNIT_CHANGE_OWNER,WESTRING_UEVENT_CHANGESOWNER\nUnitEventDamaged=0,unitevent,EVENT_UNIT_DAMAGED,WESTRING_UEVENT_DAMAGED\nUnitEventHeroLevel=0,unitevent,EVENT_UNIT_HERO_LEVEL,WESTRING_UEVENT_HEROLEVEL\nUnitEventHeroSkill=0,unitevent,EVENT_UNIT_HERO_SKILL,WESTRING_UEVENT_HEROSKILL\nUnitEventHeroRevivable=0,unitevent,EVENT_UNIT_HERO_REVIVABLE,WESTRING_UEVENT_HEROREVIVABLE\nUnitEventHeroUseItem=0,unitevent,EVENT_UNIT_USE_ITEM,WESTRING_UEVENT_HEROUSEITEM\nUnitEventHeroPickUpItem=0,unitevent,EVENT_UNIT_PICKUP_ITEM,WESTRING_UEVENT_HEROPICKUPITEM\nUnitEventHeroDropItem=0,unitevent,EVENT_UNIT_DROP_ITEM,WESTRING_UEVENT_HERODROPITEM\nUnitEventSell=1,unitevent,EVENT_UNIT_SELL,WESTRING_UEVENT_SELL\nUnitEventSellItem=1,unitevent,EVENT_UNIT_SELL_ITEM,WESTRING_UEVENT_SELLITEM\nUnitEventPawnItem=1,unitevent,EVENT_UNIT_PAWN_ITEM,WESTRING_UEVENT_PAWNITEM\nUnitEventAttacked=0,unitevent,EVENT_UNIT_ATTACKED,WESTRING_UEVENT_ATTACKED\nUnitEventRescued=0,unitevent,EVENT_UNIT_RESCUED,WESTRING_UEVENT_RESCUED\nUnitEventSelected=0,unitevent,EVENT_UNIT_SELECTED,WESTRING_UEVENT_SELECTED\nUnitEventDeselected=0,unitevent,EVENT_UNIT_DESELECTED,WESTRING_UEVENT_DESELECTED\nUnitEventSpellChannel=1,unitevent,EVENT_UNIT_SPELL_CHANNEL,WESTRING_UEVENT_SPELLCHANNEL\nUnitEventSpellCast=1,unitevent,EVENT_UNIT_SPELL_CAST,WESTRING_UEVENT_SPELLCAST\nUnitEventSpellEndCast=1,unitevent,EVENT_UNIT_SPELL_ENDCAST,WESTRING_UEVENT_SPELLENDCAST\nUnitEventSpellEffect=1,unitevent,EVENT_UNIT_SPELL_EFFECT,WESTRING_UEVENT_SPELLEFFECT\nUnitEventSpellFinish=1,unitevent,EVENT_UNIT_SPELL_FINISH,WESTRING_UEVENT_SPELLFINISH\nUnitEventLoaded=0,unitevent,EVENT_UNIT_LOADED,WESTRING_UEVENT_LOADED\nUnitEventAcquiredTarget=0,unitevent,EVENT_UNIT_ACQUIRED_TARGET,WESTRING_UEVENT_ACQUIREDTARGET\nUnitEventTargetInRange=0,unitevent,EVENT_UNIT_TARGET_IN_RANGE,WESTRING_UEVENT_TARGETINRANGE\nUnitEventTrainStart=0,unitevent,EVENT_UNIT_TRAIN_START,WESTRING_UEVENT_TRAINSTART\nUnitEventTrainCancel=0,unitevent,EVENT_UNIT_TRAIN_CANCEL,WESTRING_UEVENT_TRAINCANCEL\nUnitEventTrainFinish=0,unitevent,EVENT_UNIT_TRAIN_FINISH,WESTRING_UEVENT_TRAINFINISH\nUnitEventReviveStart=0,unitevent,EVENT_UNIT_HERO_REVIVE_START,WESTRING_UEVENT_REVIVESTART\nUnitEventReviveCancel=0,unitevent,EVENT_UNIT_HERO_REVIVE_CANCEL,WESTRING_UEVENT_REVIVECANCEL\nUnitEventReviveFinish=0,unitevent,EVENT_UNIT_HERO_REVIVE_FINISH,WESTRING_UEVENT_REVIVEFINISH\nUnitEventUpgradeStart=0,unitevent,EVENT_UNIT_UPGRADE_START,WESTRING_UEVENT_UPGRADESTART\nUnitEventUpgradeCancel=0,unitevent,EVENT_UNIT_UPGRADE_CANCEL,WESTRING_UEVENT_UPGRADECANCEL\nUnitEventUpgradeFinish=0,unitevent,EVENT_UNIT_UPGRADE_FINISH,WESTRING_UEVENT_UPGRADEFINISH\nUnitEventResearchStart=0,unitevent,EVENT_UNIT_RESEARCH_START,WESTRING_UEVENT_RESEARCHSTART\nUnitEventResearchCancel=0,unitevent,EVENT_UNIT_RESEARCH_CANCEL,WESTRING_UEVENT_RESEARCHCANCEL\nUnitEventResearchFinish=0,unitevent,EVENT_UNIT_RESEARCH_FINISH,WESTRING_UEVENT_RESEARCHFINISH\nUnitEventIssueUnitOrder=0,unitevent,EVENT_UNIT_ISSUED_TARGET_ORDER,WESTRING_UEVENT_ISSUEUNITORDER\nUnitEventIssuePointOrder=0,unitevent,EVENT_UNIT_ISSUED_POINT_ORDER,WESTRING_UEVENT_ISSUEPOINTORDER\nUnitEventIssueOrder=0,unitevent,EVENT_UNIT_ISSUED_ORDER,WESTRING_UEVENT_ISSUEORDER\n\n// Unit states (read-only)\nUnitStateLife=0,unitstate,UNIT_STATE_LIFE,WESTRING_USTATE_LIFE\nUnitStateMaxLife=0,unitstate,UNIT_STATE_MAX_LIFE,WESTRING_USTATE_MAXLIFE\nUnitStateMana=0,unitstate,UNIT_STATE_MANA,WESTRING_USTATE_MANA\nUnitStateMaxMana=0,unitstate,UNIT_STATE_MAX_MANA,WESTRING_USTATE_MAXMANA\n\n// Keyboard Event Types\nKeyEventTypeDepress=1,keyeventtype,bj_KEYEVENTTYPE_DEPRESS,WESTRING_KEYEVENTTYPE_DEPRESS\nKeyEventTypeRelease=1,keyeventtype,bj_KEYEVENTTYPE_RELEASE,WESTRING_KEYEVENTTYPE_RELEASE\n\n// Keyboard Event Keys\nKeyEventKeyLeft=1,keyeventkey,bj_KEYEVENTKEY_LEFT,WESTRING_KEYEVENTKEY_LEFT\nKeyEventKeyRight=1,keyeventkey,bj_KEYEVENTKEY_RIGHT,WESTRING_KEYEVENTKEY_RIGHT\nKeyEventKeyDown=1,keyeventkey,bj_KEYEVENTKEY_DOWN,WESTRING_KEYEVENTKEY_DOWN\nKeyEventKeyUp=1,keyeventkey,bj_KEYEVENTKEY_UP,WESTRING_KEYEVENTKEY_UP\n\n// Mouse Event Types\nMouseEventTypeDown=1,mouseeventtype,bj_MOUSEEVENTTYPE_DOWN,WESTRING_MOUSEEVENTTYPE_DOWN\nMouseEventTypeUp=1,mouseeventtype,bj_MOUSEEVENTTYPE_UP,WESTRING_MOUSEEVENTTYPE_UP\nMouseEventTypeMove=1,mouseeventtype,bj_MOUSEEVENTTYPE_MOVE,WESTRING_MOUSEEVENTTYPE_MOVE\n\n// Mouse Button Types\nMouseButtonTypeLeft=1,mousebuttontype,MOUSE_BUTTON_TYPE_LEFT,WESTRING_MOUSEBUTTONTYPE_LEFT\nMouseButtonTypeMiddle=1,mousebuttontype,MOUSE_BUTTON_TYPE_MIDDLE,WESTRING_MOUSEBUTTONTYPE_MIDDLE\nMouseButtonTypeRight=1,mousebuttontype,MOUSE_BUTTON_TYPE_RIGHT,WESTRING_MOUSEBUTTONTYPE_RIGHT\n\n// Unit types\nUnitTypeStructure=0,unittype,UNIT_TYPE_STRUCTURE,WESTRING_UNITTYPE_STRUCTURE\nUnitTypeHero=0,unittype,UNIT_TYPE_HERO,WESTRING_UNITTYPE_HERO\nUnitTypeGround=0,unittype,UNIT_TYPE_GROUND,WESTRING_UNITTYPE_GROUND\nUnitTypeFlying=0,unittype,UNIT_TYPE_FLYING,WESTRING_UNITTYPE_FLYING\nUnitTypeAttacksGround=0,unittype,UNIT_TYPE_ATTACKS_GROUND,WESTRING_UNITTYPE_ATTACKSGROUND\nUnitTypeAttacksFlying=0,unittype,UNIT_TYPE_ATTACKS_FLYING,WESTRING_UNITTYPE_ATTACKSFLYING\nUnitTypeMeleeAttacker=0,unittype,UNIT_TYPE_MELEE_ATTACKER,WESTRING_UNITTYPE_MELEEATTACKER\nUnitTypeRangedAttacker=0,unittype,UNIT_TYPE_RANGED_ATTACKER,WESTRING_UNITTYPE_RANGEDATTACKER\nUnitTypeSummoned=0,unittype,UNIT_TYPE_SUMMONED,WESTRING_UNITTYPE_SUMMONED\nUnitTypePlagued=0,unittype,UNIT_TYPE_PLAGUED,WESTRING_UNITTYPE_PLAGUED\nUnitTypeSnared=0,unittype,UNIT_TYPE_SNARED,WESTRING_UNITTYPE_SNARED\nUnitTypeStunned=0,unittype,UNIT_TYPE_STUNNED,WESTRING_UNITTYPE_STUNNED\nUnitTypeUndead=0,unittype,UNIT_TYPE_UNDEAD,WESTRING_UNITTYPE_UNDEAD\nUnitTypeMechanical=0,unittype,UNIT_TYPE_MECHANICAL,WESTRING_UNITTYPE_MECHANICAL\nUnitTypeAncient=0,unittype,UNIT_TYPE_ANCIENT,WESTRING_UNITTYPE_ANCIENT\nUnitTypePeon=0,unittype,UNIT_TYPE_PEON,WESTRING_UNITTYPE_PEON\nUnitTypeTownHall=0,unittype,UNIT_TYPE_TOWNHALL,WESTRING_UNITTYPE_TOWNHALL\nUnitTypeSapper=0,unittype,UNIT_TYPE_SAPPER,WESTRING_UNITTYPE_SAPPER\nUnitTypePoisoned=0,unittype,UNIT_TYPE_POISONED,WESTRING_UNITTYPE_POISONED\nUnitTypePolymorphed=0,unittype,UNIT_TYPE_POLYMORPHED,WESTRING_UNITTYPE_POLYMORPHED\nUnitTypeSleeping=0,unittype,UNIT_TYPE_SLEEPING,WESTRING_UNITTYPE_SLEEPING\nUnitTypeResistant=1,unittype,UNIT_TYPE_RESISTANT,WESTRING_UNITTYPE_RESISTANT\nUnitTypeEthereal=1,unittype,UNIT_TYPE_ETHEREAL,WESTRING_UNITTYPE_ETHEREAL\nUnitTypeMagicImmune=0,unittype,UNIT_TYPE_MAGIC_IMMUNE,WESTRING_UNITTYPE_MAGICIMMUNE\n\n// Game speeds\nGameSpeedSlowest=0,gamespeed,MAP_SPEED_SLOWEST,WESTRING_GAMESPEED_SLOWEST\nGameSpeedSlow=0,gamespeed,MAP_SPEED_SLOW,WESTRING_GAMESPEED_SLOW\nGameSpeedNormal=0,gamespeed,MAP_SPEED_NORMAL,WESTRING_GAMESPEED_NORMAL\nGameSpeedFast=0,gamespeed,MAP_SPEED_FAST,WESTRING_GAMESPEED_FAST\nGameSpeedFastest=0,gamespeed,MAP_SPEED_FASTEST,WESTRING_GAMESPEED_FASTEST\n\n// Game difficulties\nGameDifficultyEasy=0,gamedifficulty,MAP_DIFFICULTY_EASY,WESTRING_GAMEDIFFICULTY_EASY\nGameDifficultyNormal=0,gamedifficulty,MAP_DIFFICULTY_NORMAL,WESTRING_GAMEDIFFICULTY_NORMAL\nGameDifficultyHard=0,gamedifficulty,MAP_DIFFICULTY_HARD,WESTRING_GAMEDIFFICULTY_HARD\n\n// Melee AI difficulties\nAIDifficultyNewbie=0,aidifficulty,AI_DIFFICULTY_NEWBIE,WESTRING_AIDIFFICULTY_NEWBIE\nAIDifficultyNormal=0,aidifficulty,AI_DIFFICULTY_NORMAL,WESTRING_AIDIFFICULTY_NORMAL\nAIDifficultyInsane=0,aidifficulty,AI_DIFFICULTY_INSANE,WESTRING_AIDIFFICULTY_INSANE\n\n// Map densities\nMapDensityNone=0,mapdensity,MAP_DENSITY_NONE,WESTRING_MAPDENSITY_NONE\nMapDensityLight=0,mapdensity,MAP_DENSITY_LIGHT,WESTRING_MAPDENSITY_LIGHT\nMapDensityMedium=0,mapdensity,MAP_DENSITY_MEDIUM,WESTRING_MAPDENSITY_MEDIUM\nMapDensityHeavy=0,mapdensity,MAP_DENSITY_HEAVY,WESTRING_MAPDENSITY_HEAVY\n\n// Alliance settings\nAllianceSettingUnallied=0,alliancesetting,bj_ALLIANCE_UNALLIED,WESTRING_ALLIANCE_UNALLIED\nAllianceSettingUnalliedVision=0,alliancesetting,bj_ALLIANCE_UNALLIED_VISION,WESTRING_ALLIANCE_UNALLIEDVISION\nAllianceSettingNeutral=0,alliancesetting,bj_ALLIANCE_NEUTRAL,WESTRING_ALLIANCE_NEUTRAL\nAllianceSettingNeutralVision=1,alliancesetting,bj_ALLIANCE_NEUTRAL_VISION,WESTRING_ALLIANCE_NEUTRAL_VISION\nAllianceSettingAllied=0,alliancesetting,bj_ALLIANCE_ALLIED,WESTRING_ALLIANCE_ALLIED\nAllianceSettingAlliedVision=0,alliancesetting,bj_ALLIANCE_ALLIED_VISION,WESTRING_ALLIANCE_ALLIEDVISION\nAllianceSettingAlliedUnits=0,alliancesetting,bj_ALLIANCE_ALLIED_UNITS,WESTRING_ALLIANCE_ALLIEDUNITS\nAllianceSettingAlliedAdvUnits=0,alliancesetting,bj_ALLIANCE_ALLIED_ADVUNITS,WESTRING_ALLIANCE_ALLIEDADVUNITS\n\n// Alliance types\nAllianceTypePassive=0,alliancetype,ALLIANCE_PASSIVE,WESTRING_ALLIANCE_PASSIVE\nAllianceTypeSharedVision=0,alliancetype,ALLIANCE_SHARED_VISION,WESTRING_ALLIANCE_SHAREDVISION\nAllianceTypeSharedControl=0,alliancetype,ALLIANCE_SHARED_CONTROL,WESTRING_ALLIANCE_SHAREDCONTROL\nAllianceTypeSharedFullControl=0,alliancetype,ALLIANCE_SHARED_ADVANCED_CONTROL,WESTRING_ALLIANCE_SHAREDFULLCONTROL\nAllianceTypeXP=0,alliancetype,ALLIANCE_SHARED_XP,WESTRING_ALLIANCE_XP\nAllianceTypeSpells=0,alliancetype,ALLIANCE_SHARED_SPELLS,WESTRING_ALLIANCE_SPELLS\nAllianceTypeHelpRequest=0,alliancetype,ALLIANCE_HELP_REQUEST,WESTRING_ALLIANCE_HELPREQUEST\nAllianceTypeHelpResponse=0,alliancetype,ALLIANCE_HELP_RESPONSE,WESTRING_ALLIANCE_HELPRESPONSE\n\n// Attack types\nAttackTypeNormal=1,attacktype,ATTACK_TYPE_NORMAL,WESTRING_UE_ATTACKTYPE_SPELLS\nAttackTypeMelee=1,attacktype,ATTACK_TYPE_MELEE,WESTRING_UE_ATTACKTYPE_NORMAL\nAttackTypePierce=1,attacktype,ATTACK_TYPE_PIERCE,WESTRING_UE_ATTACKTYPE_PIERCE\nAttackTypeSiege=1,attacktype,ATTACK_TYPE_SIEGE,WESTRING_UE_ATTACKTYPE_SIEGE\nAttackTypeMagic=1,attacktype,ATTACK_TYPE_MAGIC,WESTRING_UE_ATTACKTYPE_MAGIC\nAttackTypeChaos=1,attacktype,ATTACK_TYPE_CHAOS,WESTRING_UE_ATTACKTYPE_CHAOS\nAttackTypeHero=1,attacktype,ATTACK_TYPE_HERO,WESTRING_UE_ATTACKTYPE_HERO\n\n// Damage types\nDamageTypeUnknown=1,damagetype,DAMAGE_TYPE_UNKNOWN,WESTRING_DAMAGE_TYPE_UNKNOWN\nDamageTypeNormal=1,damagetype,DAMAGE_TYPE_NORMAL,WESTRING_DAMAGE_TYPE_NORMAL\nDamageTypeEnhanced=1,damagetype,DAMAGE_TYPE_ENHANCED,WESTRING_DAMAGE_TYPE_ENHANCED\nDamageTypeFire=1,damagetype,DAMAGE_TYPE_FIRE,WESTRING_DAMAGE_TYPE_FIRE\nDamageTypeCold=1,damagetype,DAMAGE_TYPE_COLD,WESTRING_DAMAGE_TYPE_COLD\nDamageTypeLightning=1,damagetype,DAMAGE_TYPE_LIGHTNING,WESTRING_DAMAGE_TYPE_LIGHTNING\nDamageTypePoison=1,damagetype,DAMAGE_TYPE_POISON,WESTRING_DAMAGE_TYPE_POISON\nDamageTypeDisease=1,damagetype,DAMAGE_TYPE_DISEASE,WESTRING_DAMAGE_TYPE_DISEASE\nDamageTypeDivine=1,damagetype,DAMAGE_TYPE_DIVINE,WESTRING_DAMAGE_TYPE_DIVINE\nDamageTypeMagic=1,damagetype,DAMAGE_TYPE_MAGIC,WESTRING_DAMAGE_TYPE_MAGIC\nDamageTypeSonic=1,damagetype,DAMAGE_TYPE_SONIC,WESTRING_DAMAGE_TYPE_SONIC\nDamageTypeAcid=1,damagetype,DAMAGE_TYPE_ACID,WESTRING_DAMAGE_TYPE_ACID\nDamageTypeForce=1,damagetype,DAMAGE_TYPE_FORCE,WESTRING_DAMAGE_TYPE_FORCE\nDamageTypeDeath=1,damagetype,DAMAGE_TYPE_DEATH,WESTRING_DAMAGE_TYPE_DEATH\nDamageTypeMind=1,damagetype,DAMAGE_TYPE_MIND,WESTRING_DAMAGE_TYPE_MIND\nDamageTypePlant=1,damagetype,DAMAGE_TYPE_PLANT,WESTRING_DAMAGE_TYPE_PLANT\nDamageTypeDefensive=1,damagetype,DAMAGE_TYPE_DEFENSIVE,WESTRING_DAMAGE_TYPE_DEFENSIVE\nDamageTypeDemolition=1,damagetype,DAMAGE_TYPE_DEMOLITION,WESTRING_DAMAGE_TYPE_DEMOLITION\nDamageTypeSlowPoison=1,damagetype,DAMAGE_TYPE_SLOW_POISON,WESTRING_DAMAGE_TYPE_SLOW_POISON\nDamageTypeSpiritLink=1,damagetype,DAMAGE_TYPE_SPIRIT_LINK,WESTRING_DAMAGE_TYPE_SPIRIT_LINK\nDamageTypeShadowStrike=1,damagetype,DAMAGE_TYPE_SHADOW_STRIKE,WESTRING_DAMAGE_TYPE_SHADOW_STRIKE\nDamageTypeUniversal=1,damagetype,DAMAGE_TYPE_UNIVERSAL,WESTRING_DAMAGE_TYPE_UNIVERSAL\n\n// Weapon types\nWeaponTypeMetalLightChop=1,weapontype,WEAPON_TYPE_METAL_LIGHT_CHOP,WESTRING_UE_COMBATSOUND_METALLIGHTCHOP\nWeaponTypeMetalMediumChop=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_CHOP,WESTRING_UE_COMBATSOUND_METALMEDIUMCHOP\nWeaponTypeMetalHeavyChop=1,weapontype,WEAPON_TYPE_METAL_HEAVY_CHOP,WESTRING_UE_COMBATSOUND_METALHEAVYCHOP\nWeaponTypeMetalLightSlice=1,weapontype,WEAPON_TYPE_METAL_LIGHT_SLICE,WESTRING_UE_COMBATSOUND_METALLIGHTSLICE\nWeaponTypeMetalMediumSlice=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_SLICE,WESTRING_UE_COMBATSOUND_METALMEDIUMSLICE\nWeaponTypeMetalHeavySlice=1,weapontype,WEAPON_TYPE_METAL_HEAVY_SLICE,WESTRING_UE_COMBATSOUND_METALHEAVYSLICE\nWeaponTypeMetalMediumBash=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_BASH,WESTRING_UE_COMBATSOUND_METALMEDIUMBASH\nWeaponTypeMetalHeavyBash=1,weapontype,WEAPON_TYPE_METAL_HEAVY_BASH,WESTRING_UE_COMBATSOUND_METALHEAVYBASH\nWeaponTypeWoodLightBash=1,weapontype,WEAPON_TYPE_WOOD_LIGHT_BASH,WESTRING_UE_COMBATSOUND_WOODLIGHTBASH\nWeaponTypeWoodMediumBash=1,weapontype,WEAPON_TYPE_WOOD_MEDIUM_BASH,WESTRING_UE_COMBATSOUND_WOODMEDIUMBASH\nWeaponTypeWoodHeavyBash=1,weapontype,WEAPON_TYPE_WOOD_HEAVY_BASH,WESTRING_UE_COMBATSOUND_WOODHEAVYBASH\nWeaponTypeAxeMediumChop=1,weapontype,WEAPON_TYPE_AXE_MEDIUM_CHOP,WESTRING_UE_COMBATSOUND_AXEMEDIUMCHOP\nWeaponTypeRockHeavyBash=1,weapontype,WEAPON_TYPE_ROCK_HEAVY_BASH,WESTRING_UE_COMBATSOUND_ROCKHEAVYBASH\n\nPathingTypeAny=1,pathingtype,PATHING_TYPE_ANY,WESTRING_PATHINGTYPE_ANY\nPathingTypeWalkability=1,pathingtype,PATHING_TYPE_WALKABILITY,WESTRING_PATHINGTYPE_WALKABILITY\nPathingTypeFlyability=1,pathingtype,PATHING_TYPE_FLYABILITY,WESTRING_PATHINGTYPE_FLYABILITY\nPathingTypeBuildability=1,pathingtype,PATHING_TYPE_BUILDABILITY,WESTRING_PATHINGTYPE_BUILDABILITY\nPathingTypePeonHarvestPathing=1,pathingtype,PATHING_TYPE_PEONHARVESTPATHING,WESTRING_PATHINGTYPE_PEONHARVESTPATHING\nPathingTypeBlightPathing=1,pathingtype,PATHING_TYPE_BLIGHTPATHING,WESTRING_PATHINGTYPE_BLIGHTPATHING\nPathingTypeFloatability=1,pathingtype,PATHING_TYPE_FLOATABILITY,WESTRING_PATHINGTYPE_FLOATABILITY\nPathingTypeAmphibiousPathing=1,pathingtype,PATHING_TYPE_AMPHIBIOUSPATHING,WESTRING_PATHINGTYPE_AMPHIBIOUSPATHING\n\n// Camera fields\nCameraFieldTargetDistance=0,camerafield,CAMERA_FIELD_TARGET_DISTANCE,WESTRING_CAMERA_TARGETDISTANCE\nCameraFieldFarZ=0,camerafield,CAMERA_FIELD_FARZ,WESTRING_CAMERA_FARZ\nCameraFieldAOA=0,camerafield,CAMERA_FIELD_ANGLE_OF_ATTACK,WESTRING_CAMERA_AOA\nCameraFieldFOV=0,camerafield,CAMERA_FIELD_FIELD_OF_VIEW,WESTRING_CAMERA_FOV\nCameraFieldRoll=0,camerafield,CAMERA_FIELD_ROLL,WESTRING_CAMERA_ROLL\nCameraFieldRotation=0,camerafield,CAMERA_FIELD_ROTATION,WESTRING_CAMERA_ROTATION\nCameraFieldZOffset=1,camerafield,CAMERA_FIELD_ZOFFSET,WESTRING_CAMERA_ZOFFSET\n\n// Animation rarity controls\nRarityControlFrequent=0,raritycontrol,RARITY_FREQUENT,WESTRING_RARITY_FREQUENT\nRarityControlRare=0,raritycontrol,RARITY_RARE,WESTRING_RARITY_RARE\n\n// Blending Methods\nBlendModeNone=0,blendmode,BLEND_MODE_NONE,WESTRING_BLENDMODE_NONE\nBlendModeBlend=0,blendmode,BLEND_MODE_BLEND,WESTRING_BLENDMODE_BLEND\nBlendModeAdditive=0,blendmode,BLEND_MODE_ADDITIVE,WESTRING_BLENDMODE_ADDITIVE\nBlendModeModulate=0,blendmode,BLEND_MODE_MODULATE,WESTRING_BLENDMODE_MODULATE\nBlendModeModulate2x=0,blendmode,BLEND_MODE_MODULATE_2X,WESTRING_BLENDMODE_MODULATE_2X\nBlendModeKeyAlpha=0,blendmode,BLEND_MODE_KEYALPHA,WESTRING_BLENDMODE_KEYALPHA\n\n// Volume Groups\nVolumeGroupAmbient=0,volumegroup,SOUND_VOLUMEGROUP_AMBIENTSOUNDS,WESTRING_VOLUMEGROUP_AMBIENTSOUNDS\nVolumeGroupSpells=0,volumegroup,SOUND_VOLUMEGROUP_SPELLS,WESTRING_VOLUMEGROUP_SPELLS\nVolumeGroupCombat=0,volumegroup,SOUND_VOLUMEGROUP_COMBAT,WESTRING_VOLUMEGROUP_COMBAT\nVolumeGroupFire=0,volumegroup,SOUND_VOLUMEGROUP_FIRE,WESTRING_VOLUMEGROUP_FIRE\nVolumeGroupMusic=0,volumegroup,SOUND_VOLUMEGROUP_MUSIC,WESTRING_VOLUMEGROUP_MUSIC\nVolumeGroupUnitMovement=0,volumegroup,SOUND_VOLUMEGROUP_UNITMOVEMENT,WESTRING_VOLUMEGROUP_UNITMOVEMENT\nVolumeGroupUnitSounds=0,volumegroup,SOUND_VOLUMEGROUP_UNITSOUNDS,WESTRING_VOLUMEGROUP_UNITSOUNDS\nVolumeGroupUI=0,volumegroup,SOUND_VOLUMEGROUP_UI,WESTRING_VOLUMEGROUP_UI\n\nEffectTypeEffect=1,effecttype,EFFECT_TYPE_EFFECT,WESTRING_EFFECT_TYPE_EFFECT\nEffectTypeTarget=1,effecttype,EFFECT_TYPE_TARGET,WESTRING_EFFECT_TYPE_TARGET\nEffectTypeCaster=1,effecttype,EFFECT_TYPE_CASTER,WESTRING_EFFECT_TYPE_CASTER\nEffectTypeSpecial=1,effecttype,EFFECT_TYPE_SPECIAL,WESTRING_EFFECT_TYPE_SPECIAL\nEffectTypeAreaEffect=1,effecttype,EFFECT_TYPE_AREA_EFFECT,WESTRING_EFFECT_TYPE_AREA_EFFECT\nEffectTypeMissile=1,effecttype,EFFECT_TYPE_MISSILE,WESTRING_EFFECT_TYPE_MISSILE\nEffectTypeLightning=1,effecttype,EFFECT_TYPE_LIGHTNING,WESTRING_EFFECT_TYPE_LIGHTNING\n\nSoundTypeEffect=1,soundtype,SOUND_TYPE_EFFECT,WESTRING_SOUND_TYPE_EFFECT\nSoundTypeEffectLooped=1,soundtype,SOUND_TYPE_EFFECT_LOOPED,WESTRING_SOUND_TYPE_EFFECT_LOOPED\n\n// Fog states\nFogStateMasked=0,fogstate,FOG_OF_WAR_MASKED,WESTRING_FOGSTATE_MASKED\nFogStateFogged=0,fogstate,FOG_OF_WAR_FOGGED,WESTRING_FOGSTATE_FOGGED\nFogStateVisible=0,fogstate,FOG_OF_WAR_VISIBLE,WESTRING_FOGSTATE_VISIBLE\n\n// Fog styles\nFogStyleLinear=0,fogstyle,0,WESTRING_FOGSTYLE_LINEAR\nFogStyleExp1=0,fogstyle,1,WESTRING_FOGSTYLE_EXP1\nFogStyleExp2=0,fogstyle,2,WESTRING_FOGSTYLE_EXP2\n\n// Timed-life buff codes\nTimedLifeBuffCodeAnimateDead=1,timedlifebuffcode,'BUan',WESTRING_TIMEDLIFEBUFFCODE_ANIMATEDEAD\nTimedLifeBuffCodePlagueWard=1,timedlifebuffcode,'Bapl',WESTRING_TIMEDLIFEBUFFCODE_PLAGUEWARD\nTimedLifeBuffCodeForceOfNature=1,timedlifebuffcode,'BEfn',WESTRING_TIMEDLIFEBUFFCODE_FORCEOFNATURE\nTimedLifeBuffCodeGeneric=1,timedlifebuffcode,'BTLF',WESTRING_TIMEDLIFEBUFFCODE_GENERIC\nTimedLifeBuffCodeHealingWard=1,timedlifebuffcode,'Bhwd',WESTRING_TIMEDLIFEBUFFCODE_HEALINGWARD\nTimedLifeBuffCodeRaiseDead=1,timedlifebuffcode,'Brai',WESTRING_TIMEDLIFEBUFFCODE_RAISEDEAD\nTimedLifeBuffCodeWaterElemental=1,timedlifebuffcode,'BHwe',WESTRING_TIMEDLIFEBUFFCODE_WATERELEMENTAL\n\n// Item status codes\nItemStatusHidden=1,itemstatus,bj_ITEM_STATUS_HIDDEN,WESTRING_ITEMSTATUS_HIDDEN\nItemStatusOwned=1,itemstatus,bj_ITEM_STATUS_OWNED,WESTRING_ITEMSTATUS_OWNED\nItemStatusInvulnerable=1,itemstatus,bj_ITEM_STATUS_INVULNERABLE,WESTRING_ITEMSTATUS_INVULNERABLE\nItemStatusPowerup=1,itemstatus,bj_ITEM_STATUS_POWERUP,WESTRING_ITEMSTATUS_POWERUP\nItemStatusSellable=1,itemstatus,bj_ITEM_STATUS_SELLABLE,WESTRING_ITEMSTATUS_SELLABLE\nItemStatusPawnable=1,itemstatus,bj_ITEM_STATUS_PAWNABLE,WESTRING_ITEMSTATUS_PAWNABLE\n\n// Itemcode status codes\nItemcodeStatusPowerup=1,itemcodestatus,bj_ITEMCODE_STATUS_POWERUP,WESTRING_ITEMCODESTATUS_POWERUP\nItemcodeStatusSellable=1,itemcodestatus,bj_ITEMCODE_STATUS_SELLABLE,WESTRING_ITEMCODESTATUS_SELLABLE\nItemcodeStatusPawnable=1,itemcodestatus,bj_ITEMCODE_STATUS_PAWNABLE,WESTRING_ITEMCODESTATUS_PAWNABLE\n\n// Minimap ping styles\nMinimapPingStyleSimple=1,minimappingstyle,bj_MINIMAPPINGSTYLE_SIMPLE,WESTRING_MINIMAPPINGSTYLE_SIMPLE\nMinimapPingStyleFlashy=1,minimappingstyle,bj_MINIMAPPINGSTYLE_FLASHY,WESTRING_MINIMAPPINGSTYLE_FLASHY\nMinimapPingStyleAttack=1,minimappingstyle,bj_MINIMAPPINGSTYLE_ATTACK,WESTRING_MINIMAPPINGSTYLE_ATTACK\n\n// Corpse creation styles\nCorpseTypeFlesh=1,corpsetype,bj_CORPSETYPE_FLESH,WESTRING_CORPSETYPE_FLESH\nCorpseTypeBone=1,corpsetype,bj_CORPSETYPE_BONE,WESTRING_CORPSETYPE_BONE\n\n// String case option\nStringCaseLower=1,stringcaseoption,false,WESTRING_STRINGCASE_LOWER\nStringCaseUpper=1,stringcaseoption,true,WESTRING_STRINGCASE_UPPER\n\n// Change color option\nChangeColorTrue=0,colorchangeoption,true,WESTRING_CHANGECOLOR_CHANGE\nChangeColorFalse=0,colorchangeoption,false,WESTRING_CHANGECOLOR_RETAIN\n\n// Player Change Color option\nPlayerChangeColorChange=0,playerchangecoloroption,true,WESTRING_SETPLAYERCOLOR_CHANGE\nPlayerChangeColorRetain=0,playerchangecoloroption,false,WESTRING_SETPLAYERCOLOR_RETAIN\n\n// Chat match types\nChatMatchTypeExact=0,chatmatchtype,true,WESTRING_CHATMATCH_EXACT\nChatMatchTypeSubstring=0,chatmatchtype,false,WESTRING_CHATMATCH_SUBSTRING\n\n// UnitFacing bones\nUnitFacingBoneHead=0,unitfacingbone,`bone_head`,WESTRING_UNITFACINGBONE_HEAD\nUnitFacingBoneChest=0,unitfacingbone,`bone_chest`,WESTRING_UNITFACINGBONE_CHEST\n\n// Include option\nInclusionInclude=0,includeoption,true,WESTRING_INCLUSION_INCLUDE\nInclusionExclude=0,includeoption,false,WESTRING_INCLUSION_EXCLUDE\n\n// Camera Pan option\nCameraApply=0,cameraapplyoption,true,WESTRING_CAMERAAPPLYOPTION_APPLY\nCameraApplyNoPan=0,cameraapplyoption,false,WESTRING_CAMERAAPPLYOPTION_APPLYNOPAN\n\n// Camera Orientation option\nCameraOrientationNormal=0,cameraorientationoption,false,WESTRING_CAMERAORIENTATION_NORMAL\nCameraOrientationInherit=0,cameraorientationoption,true,WESTRING_CAMERAORIENTATION_INHERIT\n\n// Invulnerability option\nInvulnerabilityInvulnerable=0,invulnerableoption,true,WESTRING_INVULNERABILITY_INVULNERABLE\nInvulnerabilityVulnerable=0,invulnerableoption,false,WESTRING_INVULNERABILITY_VULNERABLE\n\n// Availability option\nAvailabilityOptionAvailable=0,availabilityoption,true,WESTRING_AVAILABILITY_AVAILABLE\nAvailabilityOptionUnavailable=0,availabilityoption,false,WESTRING_AVAILABILITY_UNAVAILABLE\n\n// ShowHide option\nShowHideHide=0,showhideoption,false,WESTRING_SHOWHIDE_HIDE\nShowHideShow=0,showhideoption,true,WESTRING_SHOWHIDE_SHOW\n\n// Minimize option\nMinimize=1,minimizeoption,true,WESTRING_MINIMIZEOPTION_MINIMIZE\nMaximize=1,minimizeoption,false,WESTRING_MINIMIZEOPTION_MAXIMIZE\n\n// Sky Model\nSkyModelNone=0,skymodelstring,null,WESTRING_SKYMODEL_NONE\nSkyModelSky08=0,skymodelstring,`Environment\\\\Sky\\\\BlizzardSky\\\\BlizzardSky.mdl`,WESTRING_SKYMODEL_SKY08\nSkyModelSky02=0,skymodelstring,`Environment\\\\Sky\\\\DalaranSky\\\\DalaranSky.mdl`,WESTRING_SKYMODEL_SKY02\nSkyModelSky06=0,skymodelstring,`Environment\\\\Sky\\\\FelwoodSky\\\\FelwoodSky.mdl`,WESTRING_SKYMODEL_SKY06\nSkyModelSky07=0,skymodelstring,`Environment\\\\Sky\\\\FoggedSky\\\\FoggedSky.mdl`,WESTRING_SKYMODEL_SKY07\nSkyModelSky01=0,skymodelstring,`Environment\\\\Sky\\\\Sky\\\\SkyLight.mdl`,WESTRING_SKYMODEL_SKY01\nSkyModelSky03=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronFallSky\\\\LordaeronFallSky.mdl`,WESTRING_SKYMODEL_SKY03\nSkyModelSky04=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronSummerSky\\\\LordaeronSummerSky.mdl`,WESTRING_SKYMODEL_SKY04\nSkyModelSky05=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSky\\\\LordaeronWinterSky.mdl`,WESTRING_SKYMODEL_SKY05\nSkyModelSky09=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyBrightGreen\\\\LordaeronWinterSkyBrightGreen.mdl`,WESTRING_SKYMODEL_SKY09\nSkyModelSky10=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyPink\\\\LordaeronWinterSkyPink.mdl`,WESTRING_SKYMODEL_SKY10\nSkyModelSky11=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyPurple\\\\LordaeronWinterSkyPurple.mdl`,WESTRING_SKYMODEL_SKY11\nSkyModelSky12=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyRed\\\\LordaeronWinterSkyRed.mdl`,WESTRING_SKYMODEL_SKY12\nSkyModelSky13=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyYellow\\\\LordaeronWinterSkyYellow.mdl`,WESTRING_SKYMODEL_SKY13\nSkyModelSky14=1,skymodelstring,`Environment\\\\Sky\\\\Outland_Sky\\\\Outland_Sky.mdl`,WESTRING_SKYMODEL_SKY14\n\n// Cinematic filter textures\nCineFilterTextureWhite=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\White_mask.blp`,WESTRING_CINEFILTERTEX_WHITE\nCineFilterTextureBlack=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Black_mask.blp`,WESTRING_CINEFILTERTEX_BLACK\nCineFilterTextureHaze=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\HazeFilter_mask.blp`,WESTRING_CINEFILTERTEX_HAZE\nCineFilterTextureGroundFog=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\GroundFog_mask.blp`,WESTRING_CINEFILTERTEX_GROUNDFOG\nCineFilterTextureHazeAndFog=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\HazeAndFogFilter_Mask.blp`,WESTRING_CINEFILTERTEX_HAZEANDFOG\nCineFilterTextureDiagonal=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\DiagonalSlash_mask.blp`,WESTRING_CINEFILTERTEX_DIAGONAL\nCineFilterTextureDream=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\DreamFilter_Mask.blp`,WESTRING_CINEFILTERTEX_DREAM\nCineFilterTextureScope=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Scope_Mask.blp`,WESTRING_CINEFILTERTEX_SCOPE\nCineFilterTexturePow=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\SpecialPowMask.blp`,WESTRING_CINEFILTERTEX_POW\nCineFilterTextureSplat=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\SpecialSplatMask.blp`,WESTRING_CINEFILTERTEX_SPLAT\nCineFilterTexturePanda=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Panda-n-Cub.blp`,WESTRING_CINEFILTERTEX_PANDA\n\n// Music themes\nMusicThemeArthas=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\ArthasTheme.mp3`,WESTRING_MUSICTHEME_ARTHAS\nMusicThemeBloodElf=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\BloodElfTheme.mp3`,WESTRING_MUSICTHEME_BLOODELF\nMusicThemeComradeship=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Comradeship.mp3`,WESTRING_MUSICTHEME_COMRADESHIP\nMusicThemeCredits=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Credits.mp3`,WESTRING_MUSICTHEME_CREDITS\nMusicThemeDarkAgents=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\DarkAgents.mp3`,WESTRING_MUSICTHEME_DARKAGENTS\nMusicThemeDarkVictory=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\DarkVictory.mp3`,WESTRING_MUSICTHEME_DARKVICTORY\nMusicThemeDoom=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Doom.mp3`,WESTRING_MUSICTHEME_DOOM\nMusicThemeHeroicVictory=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HeroicVictory.mp3`,WESTRING_MUSICTHEME_HEROIC_VICTORY\nMusicThemeHuman1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human1.mp3`,WESTRING_MUSICTHEME_HUMAN1\nMusicThemeHuman2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human2.mp3`,WESTRING_MUSICTHEME_HUMAN2\nMusicThemeHuman3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human3.mp3`,WESTRING_MUSICTHEME_HUMAN3\nMusicThemeHumanX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanX1.mp3`,WESTRING_MUSICTHEME_HUMANX1\nMusicThemeDefeatHuman=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_HUMAN\nMusicThemeVictoryHuman=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_HUMAN\nMusicThemeIllidan=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\IllidansTheme.mp3`,WESTRING_MUSICTHEME_ILLIDAN\nMusicThemeLichKing=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\LichKingTheme.mp3`,WESTRING_MUSICTHEME_LICHKING\nMusicThemeMainScreen=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\MainScreen.mp3`,WESTRING_MUSICTHEME_MAINSCREEN\nMusicThemeMainScreenX=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\War3XMainScreen.mp3`,WESTRING_MUSICTHEME_MAINSCREENX\nMusicThemeNaga=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NagaTheme.mp3`,WESTRING_MUSICTHEME_NAGA\nMusicThemeNightElf1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf1.mp3`,WESTRING_MUSICTHEME_NIGHTELF1\nMusicThemeNightElf2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf2.mp3`,WESTRING_MUSICTHEME_NIGHTELF2\nMusicThemeNightElf3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf3.mp3`,WESTRING_MUSICTHEME_NIGHTELF3\nMusicThemeNightElfX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfX1.mp3`,WESTRING_MUSICTHEME_NIGHTELFX1\nMusicThemeDefeatNightElf=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_NIGHTELF\nMusicThemeVictoryNightElf=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_NIGHTELF\nMusicThemeOrc1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc1.mp3`,WESTRING_MUSICTHEME_ORC1\nMusicThemeOrc2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc2.mp3`,WESTRING_MUSICTHEME_ORC2\nMusicThemeOrc3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc3.mp3`,WESTRING_MUSICTHEME_ORC3\nMusicThemeOrcX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcX1.mp3`,WESTRING_MUSICTHEME_ORCX1\nMusicThemeDefeatOrc=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_ORC\nMusicThemeOrcTheme=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcTheme.mp3`,WESTRING_MUSICTHEME_ORC_THEME\nMusicThemeVictoryOrc=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_ORC\nMusicThemePersuit=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\PursuitTheme.mp3`,WESTRING_MUSICTHEME_PURSUIT\nMusicThemeSadMystery=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\SadMystery.mp3`,WESTRING_MUSICTHEME_SADMYSTERY\nMusicThemeTension=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Tension.mp3`,WESTRING_MUSICTHEME_TENSION\nMusicThemeTragicConfrontation=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\TragicConfrontation.mp3`,WESTRING_MUSICTHEME_TRAGICCONFRONTATION\nMusicThemeUndead1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead1.mp3`,WESTRING_MUSICTHEME_UNDEAD1\nMusicThemeUndead2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead2.mp3`,WESTRING_MUSICTHEME_UNDEAD2\nMusicThemeUndead3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead3.mp3`,WESTRING_MUSICTHEME_UNDEAD3\nMusicThemeUndeadX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadX1.mp3`,WESTRING_MUSICTHEME_UNDEADX1\nMusicThemeDefeatUndead=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_UNDEAD\nMusicThemeVictoryUndead=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_UNDEAD\n\n// Daytime Ambient Themes\nAmbientThemeDayA=0,ambientthemeday,`AshenvaleDay`,WESTRING_AMBIENTTHEMEDAY_A\nAmbientThemeDayB=0,ambientthemeday,`BarrensDay`,WESTRING_AMBIENTTHEMEDAY_B\nAmbientThemeDayK=1,ambientthemeday,`BlackCitadelDay`,WESTRING_AMBIENTTHEMEDAY_K\nAmbientThemeDayY=0,ambientthemeday,`CityScapeDay`,WESTRING_AMBIENTTHEMEDAY_Y\nAmbientThemeDayX=0,ambientthemeday,`DalaranDay`,WESTRING_AMBIENTTHEMEDAY_X\nAmbientThemeDayJ=1,ambientthemeday,`DalaranRuinsDay`,WESTRING_AMBIENTTHEMEDAY_J\nAmbientThemeDayD=0,ambientthemeday,`DungeonDay`,WESTRING_AMBIENTTHEMEDAY_D\nAmbientThemeDayC=0,ambientthemeday,`FelwoodDay`,WESTRING_AMBIENTTHEMEDAY_C\nAmbientThemeDayI=1,ambientthemeday,`IceCrownDay`,WESTRING_AMBIENTTHEMEDAY_I\nAmbientThemeDayF=0,ambientthemeday,`LordaeronFallDay`,WESTRING_AMBIENTTHEMEDAY_F\nAmbientThemeDayL=0,ambientthemeday,`LordaeronSummerDay`,WESTRING_AMBIENTTHEMEDAY_L\nAmbientThemeDayW=0,ambientthemeday,`LordaeronWinterDay`,WESTRING_AMBIENTTHEMEDAY_W\nAmbientThemeDayN=0,ambientthemeday,`NorthrendDay`,WESTRING_AMBIENTTHEMEDAY_N\nAmbientThemeDayO=1,ambientthemeday,`BlackCitadelDay`,WESTRING_AMBIENTTHEMEDAY_O\nAmbientThemeDayZ=1,ambientthemeday,`SunkenRuinsDay`,WESTRING_AMBIENTTHEMEDAY_Z\nAmbientThemeDayV=0,ambientthemeday,`VillageDay`,WESTRING_AMBIENTTHEMEDAY_V\nAmbientThemeDayQ=0,ambientthemeday,`VillageFallDay`,WESTRING_AMBIENTTHEMEDAY_Q\n\n// Nighttime Ambient Themes\nAmbientThemeNightA=0,ambientthemenight,`AshenvaleNight`,WESTRING_AMBIENTTHEMENIGHT_A\nAmbientThemeNightB=0,ambientthemenight,`BarrensNight`,WESTRING_AMBIENTTHEMENIGHT_B\nAmbientThemeNightK=1,ambientthemenight,`BlackCitadelNight`,WESTRING_AMBIENTTHEMENIGHT_K\nAmbientThemeNightY=0,ambientthemenight,`CityScapeNight`,WESTRING_AMBIENTTHEMENIGHT_Y\nAmbientThemeNightX=0,ambientthemenight,`DalaranNight`,WESTRING_AMBIENTTHEMENIGHT_X\nAmbientThemeNightJ=1,ambientthemenight,`DalaranRuinsNight`,WESTRING_AMBIENTTHEMENIGHT_J\nAmbientThemeNightD=0,ambientthemenight,`DungeonNight`,WESTRING_AMBIENTTHEMENIGHT_D\nAmbientThemeNightC=0,ambientthemenight,`FelwoodNight`,WESTRING_AMBIENTTHEMENIGHT_C\nAmbientThemeNightI=1,ambientthemenight,`IceCrownNight`,WESTRING_AMBIENTTHEMENIGHT_I\nAmbientThemeNightF=0,ambientthemenight,`LordaeronFallNight`,WESTRING_AMBIENTTHEMENIGHT_F\nAmbientThemeNightL=0,ambientthemenight,`LordaeronSummerNight`,WESTRING_AMBIENTTHEMENIGHT_L\nAmbientThemeNightW=0,ambientthemenight,`LordaeronWinterNight`,WESTRING_AMBIENTTHEMENIGHT_W\nAmbientThemeNightN=0,ambientthemenight,`NorthrendNight`,WESTRING_AMBIENTTHEMENIGHT_N\nAmbientThemeNightO=1,ambientthemenight,`BlackCitadelNight`,WESTRING_AMBIENTTHEMENIGHT_O\nAmbientThemeNightZ=1,ambientthemenight,`SunkenRuinsNight`,WESTRING_AMBIENTTHEMENIGHT_Z\nAmbientThemeNightV=0,ambientthemenight,`VillageNight`,WESTRING_AMBIENTTHEMENIGHT_V\nAmbientThemeNightQ=0,ambientthemenight,`VillageFallNight`,WESTRING_AMBIENTTHEMENIGHT_Q\n\n// Unit State Method\nUnitStateMethodAbsolute=0,unitstatemethod,bj_UNIT_STATE_METHOD_ABSOLUTE,WESTRING_UNITSTATEMETHOD_ABSOLUTE\nUnitStateMethodRelative=0,unitstatemethod,bj_UNIT_STATE_METHOD_RELATIVE,WESTRING_UNITSTATEMETHOD_RELATIVE\nUnitStateMethodDefaults=0,unitstatemethod,bj_UNIT_STATE_METHOD_DEFAULTS,WESTRING_UNITSTATEMETHOD_DEFAULTS\nUnitStateMethodMaximum=0,unitstatemethod,bj_UNIT_STATE_METHOD_MAXIMUM,WESTRING_UNITSTATEMETHOD_MAXIMUM\n\n// CheckingIgnoring option\nCheckingIgnoringChecking=0,checkingignoringoption,true,WESTRING_CHECKINGIGNORINGOPTION_CHECKING\nCheckingIgnoringIgnoring=0,checkingignoringoption,false,WESTRING_CHECKINGIGNORINGOPTION_IGNORING\n\n// Pathing option\nPathingOn=0,pathingoption,true,WESTRING_PATHING_ON\nPathingOff=0,pathingoption,false,WESTRING_PATHING_OFF\n\n// Pawnable option\nPawnableOptionPawnable=1,pawnableoption,true,WESTRING_PAWNABLEOPTION_PAWNABLE\nPawnableOptionUnpawnable=1,pawnableoption,false,WESTRING_PAWNABLEOPTION_UNPAWNABLE\n\n// DropOnDeath option\nDropNoDropOptionDrop=0,dropnodropoption,true,WESTRING_DROPNODROPOPTION_DROP\nDropNoDropOptionNoDrop=0,dropnodropoption,false,WESTRING_DROPNODROPOPTION_NODROP\n\n// Droppable option\nDroppableOptionDrop=0,droppableoption,true,WESTRING_DROPPABLE_DROP\nDroppableOptionNoDrop=0,droppableoption,false,WESTRING_DROPPABLE_NODROP\n\n// BeforeAfter option\nBeforeAfterBefore=0,beforeafteroption,false,WESTRING_BEFOREAFTER_BEFORE\nBeforeAfterAfter=0,beforeafteroption,true,WESTRING_BEFOREAFTER_AFTER\n\n// OnOff option\nOnOffOn=0,onoffoption,true,WESTRING_ONOFF_ON\nOnOffOff=0,onoffoption,false,WESTRING_ONOFF_OFF\n\n// EnableDisable option\nEnableDisableEnable=0,enabledisableoption,true,WESTRING_ENABLEDISABLE_ENABLE\nEnableDisableDisable=0,enabledisableoption,false,WESTRING_ENABLEDISABLE_DISABLE\n\n// EnabledDisabled option\nEnabledDisabledEnabled=0,enableddisabledoption,true,WESTRING_ENABLEDDISABLED_ENABLED\nEnabledDisabledDisabled=0,enableddisabledoption,false,WESTRING_ENABLEDDISABLED_DISABLED\n\n// Rescuable option\nRescuableOptionRescuable=0,rescuableoption,true,WESTRING_RESCUABLEOPTION_RESCUABLE\nRescuableOptionUnrescuable=0,rescuableoption,false,WESTRING_RESCUABLEOPTION_UNRESCUABLE\n\n// AllowDont option\nAllowDontAllow=0,allowdontoption,true,WESTRING_ALLOWDONTOPTION_ALLOW\nAllowDontDont=0,allowdontoption,false,WESTRING_ALLOWDONTOPTION_DONT\n\n// FadeDont option\nFadeDontFade=0,fadedontoption,true,WESTRING_FADEDONTOPTION_FADE\nFadeDontDont=0,fadedontoption,false,WESTRING_FADEDONTOPTION_DONT\n\n// AddSetTo option\nAddSetToAdd=0,addsettooption,bj_TIMETYPE_ADD,WESTRING_ADDSETTOOPTION_ADD\nAddSetToSub=0,addsettooption,bj_TIMETYPE_SUB,WESTRING_ADDSETTOOPTION_SUB\nAddSetToSet=0,addsettooption,bj_TIMETYPE_SET,WESTRING_ADDSETTOOPTION_SET\n\n// Modify methods\nModifyMethodAdd=1,modifymethod,bj_MODIFYMETHOD_ADD,WESTRING_MODIFYMETHOD_ADD\nModifyMethodSub=1,modifymethod,bj_MODIFYMETHOD_SUB,WESTRING_MODIFYMETHOD_SUB\nModifyMethodSet=1,modifymethod,bj_MODIFYMETHOD_SET,WESTRING_MODIFYMETHOD_SET\n\n// WaitDont option\nWaitDontWait=0,waitdontoption,true,WESTRING_WAITDONTOPTION_WAIT\nWaitDontDont=0,waitdontoption,false,WESTRING_WAITDONTOPTION_DONT\n\n// CraterTypes\nCraterTypeTemporary=1,cratertype,false,WESTRING_CRATERTYPE_TEMPORARY\nCraterTypePermanent=1,cratertype,true,WESTRING_CRATERTYPE_PERMANENT\n\n// RippleTypes\nRippleTypeNormal=1,rippletype,false,WESTRING_RIPPLETYPE_NORMAL\nRippleTypeDepression=1,rippletype,true,WESTRING_RIPPLETYPE_DEPRESSION\n\n// CreateRemove option\nCreateRemoveCreate=0,createremoveoption,true,WESTRING_CREATEREMOVEOPTION_CREATE\nCreateRemoveRemove=0,createremoveoption,false,WESTRING_CREATEREMOVEOPTION_REMOVE\n\n// AddRemove option\nAddRemoveAdd=0,addremoveoption,true,WESTRING_ADDREMOVEOPTION_ADD\nAddRemoveRemove=0,addremoveoption,false,WESTRING_ADDREMOVEOPTION_REMOVE\n\n// QuestType option\nQuestTypeReqDiscovered=0,questtypeoption,bj_QUESTTYPE_REQ_DISCOVERED,WESTRING_QUESTTYPE_REQ_DISCOVERED\nQuestTypeOptDiscovered=0,questtypeoption,bj_QUESTTYPE_OPT_DISCOVERED,WESTRING_QUESTTYPE_OPT_DISCOVERED\nQuestTypeReqUndiscovered=0,questtypeoption,bj_QUESTTYPE_REQ_UNDISCOVERED,WESTRING_QUESTTYPE_REQ_UNDISCOVERED\nQuestTypeOptUndiscovered=0,questtypeoption,bj_QUESTTYPE_OPT_UNDISCOVERED,WESTRING_QUESTTYPE_OPT_UNDISCOVERED\n\n// QuestMessageType option\nQuestMessageTypeDiscovered=0,questmessagetype,bj_QUESTMESSAGE_DISCOVERED,WESTRING_QUESTMESSAGE_DISCOVERED\nQuestMessageTypeUpdated=0,questmessagetype,bj_QUESTMESSAGE_UPDATED,WESTRING_QUESTMESSAGE_UPDATED\nQuestMessageTypeCompleted=0,questmessagetype,bj_QUESTMESSAGE_COMPLETED,WESTRING_QUESTMESSAGE_COMPLETED\nQuestMessageTypeFailed=0,questmessagetype,bj_QUESTMESSAGE_FAILED,WESTRING_QUESTMESSAGE_FAILED\nQuestMessageTypeRequirement=0,questmessagetype,bj_QUESTMESSAGE_REQUIREMENT,WESTRING_QUESTMESSAGE_REQUIREMENT\nQuestMessageTypeMissionFailed=0,questmessagetype,bj_QUESTMESSAGE_MISSIONFAILED,WESTRING_QUESTMESSAGE_MISSIONFAILED\nQuestMessageTypeAlwaysHint=0,questmessagetype,bj_QUESTMESSAGE_ALWAYSHINT,WESTRING_QUESTMESSAGE_ALWAYSHINT\nQuestMessageTypeHint=0,questmessagetype,bj_QUESTMESSAGE_HINT,WESTRING_QUESTMESSAGE_HINT\nQuestMessageTypeSecret=0,questmessagetype,bj_QUESTMESSAGE_SECRET,WESTRING_QUESTMESSAGE_SECRET\nQuestMessageTypeWarning=1,questmessagetype,bj_QUESTMESSAGE_WARNING,WESTRING_QUESTMESSAGE_WARNING\nQuestMessageTypeUnitAcquired=0,questmessagetype,bj_QUESTMESSAGE_UNITACQUIRED,WESTRING_QUESTMESSAGE_UNITACQUIRED\nQuestMessageTypeUnitAvailable=0,questmessagetype,bj_QUESTMESSAGE_UNITAVAILABLE,WESTRING_QUESTMESSAGE_UNITAVAILABLE\nQuestMessageTypeItemAcquired=0,questmessagetype,bj_QUESTMESSAGE_ITEMACQUIRED,WESTRING_QUESTMESSAGE_ITEMACQUIRED\n\n// Hero Stats\nHeroStatStr=1,herostat,bj_HEROSTAT_STR,WESTRING_HEROSTAT_STR\nHeroStatAgi=1,herostat,bj_HEROSTAT_AGI,WESTRING_HEROSTAT_AGI\nHeroStatInt=1,herostat,bj_HEROSTAT_INT,WESTRING_HEROSTAT_INT\n\n// Completion option\nCompletionOptionCompleted=0,completionoption,true,WESTRING_COMPLETIONOPTION_COMPLETED\nCompletionOptionIncomplete=0,completionoption,false,WESTRING_COMPLETIONOPTION_INCOMPLETE\n\n// Failure option\nFailureOptionFailed=0,failureoption,true,WESTRING_FAILUREOPTION_FAILED\nFailureOptionNotFailed=0,failureoption,false,WESTRING_FAILUREOPTION_NOTFAILED\n\n// Discovered option\nDiscoveredOptionDiscovered=0,discoveredoption,true,WESTRING_DISCOVEREDOPTION_DISCOVERED\nDiscoveredOptionUndiscovered=0,discoveredoption,false,WESTRING_DISCOVEREDOPTION_UNDISCOVERED\n\n// PauseResume option\nPauseResumePause=0,pauseresumeoption,true,WESTRING_PAUSERESUMEOPTION_PAUSE\nPauseResumeResume=0,pauseresumeoption,false,WESTRING_PAUSERESUMEOPTION_RESUME\n\n// Periodic option\nPeriodicOptionOneTime=0,periodicoption,false,WESTRING_PERIODICOPTION_ONETIME\nPeriodicOptionPeriodic=0,periodicoption,true,WESTRING_PERIODICOPTION_PERIODIC\n\n// LeaderboardSort option\nLeaderboardSortByValue=0,leaderboardsortoption,bj_SORTTYPE_SORTBYVALUE,WESTRING_LEADERBOARDSORT_BYVALUE\nLeaderboardSortByPlayer=0,leaderboardsortoption,bj_SORTTYPE_SORTBYPLAYER,WESTRING_LEADERBOARDSORT_BYPLAYER\nLeaderboardSortByLabel=0,leaderboardsortoption,bj_SORTTYPE_SORTBYLABEL,WESTRING_LEADERBOARDSORT_BYLABEL\n\n// Ascending option\nAscendingOptionAscending=0,ascendingoption,true,WESTRING_ASCENDINGOPTION_ASCENDING\nAscendingOptionDescending=0,ascendingoption,false,WESTRING_ASCENDINGOPTION_DESCENDING\n\n// SleepWake option\nSleepWakeOptionSleep=0,sleepwakeoption,true,WESTRING_SLEEPWAKEOPTION_SLEEP\nSleepWakeOptionWake=0,sleepwakeoption,false,WESTRING_SLEEPWAKEOPTION_WAKE\n\n// PauseUnpause option\nPauseUnpauseOptionPause=0,pauseunpauseoption,true,WESTRING_PAUSEUNPAUSEOPTION_PAUSE\nPauseUnpauseOptionUnpause=0,pauseunpauseoption,false,WESTRING_PAUSEUNPAUSEOPTION_UNPAUSE\n\n// ShareDont option\nShareDontOptionShare=0,sharedontoption,true,WESTRING_SHAREDONTOPTION_SHARE\nShareDontOptionDont=0,sharedontoption,false,WESTRING_SHAREDONTOPTION_DONT\n\n// InOut option\nFadeTypeOptionFadeOutIn=0,fadetypeoption,bj_CINEFADETYPE_FADEOUTIN,WESTRING_FADETYPEOPTION_FADEOUTIN\nFadeTypeOptionFadeOut=0,fadetypeoption,bj_CINEFADETYPE_FADEOUT,WESTRING_FADETYPEOPTION_FADEOUT\nFadeTypeOptionFadeIn=0,fadetypeoption,bj_CINEFADETYPE_FADEIN,WESTRING_FADETYPEOPTION_FADEIN\n\n// Buff Types\nBuffTypeAll=0,bufftype,bj_REMOVEBUFFS_ALL,WESTRING_BUFFTYPE_ALL\nBuffTypeNonTLife=1,bufftype,bj_REMOVEBUFFS_NONTLIFE,WESTRING_BUFFTYPE_NONTLIFE\nBuffTypePositive=0,bufftype,bj_REMOVEBUFFS_POSITIVE,WESTRING_BUFFTYPE_POSITIVE\nBuffTypeNegative=0,bufftype,bj_REMOVEBUFFS_NEGATIVE,WESTRING_BUFFTYPE_NEGATIVE\n\n// Buff Polarity options\nBuffPolarityPositive=1,buffpolarity,bj_BUFF_POLARITY_POSITIVE,WESTRING_BUFF_POLARITY_POSITIVE\nBuffPolarityNegative=1,buffpolarity,bj_BUFF_POLARITY_NEGATIVE,WESTRING_BUFF_POLARITY_NEGATIVE\nBuffPolarityEither=1,buffpolarity,bj_BUFF_POLARITY_EITHER,WESTRING_BUFF_POLARITY_EITHER\n\n// Buff Resistance types\nBuffResistMagic=1,buffresist,bj_BUFF_RESIST_MAGIC,WESTRING_BUFF_RESIST_MAGIC\nBuffResistPhysical=1,buffresist,bj_BUFF_RESIST_PHYSICAL,WESTRING_BUFF_RESIST_PHYSICAL\nBuffResistEither=1,buffresist,bj_BUFF_RESIST_EITHER,WESTRING_BUFF_RESIST_EITHER\nBuffResistBoth=1,buffresist,bj_BUFF_RESIST_BOTH,WESTRING_BUFF_RESIST_BOTH\n\n// Camera Bounds Adjustment Type\nCameraBoundsAdjustAdd=0,cameraboundsadjusttype,bj_CAMERABOUNDS_ADJUST_ADD,WESTRING_CAMERABOUNDSADJUST_ADD\nCameraBoundsAdjustSub=0,cameraboundsadjusttype,bj_CAMERABOUNDS_ADJUST_SUB,WESTRING_CAMERABOUNDSADJUST_SUB\n\n// Availability Option\nAvailableOptionAvailable=0,availableoption,true,WESTRING_AVAILABLEOPTION_AVAILABLE\nAvailableOptionUnavailable=0,availableoption,false,WESTRING_AVAILABLEOPTION_UNAVAILABLE\n\n// Explode Option\nExplodeDontExplode=0,explodedontoption,true,WESTRING_EXPLODEDONTOPTION_EXPLODE\nExplodeDontDont=0,explodedontoption,false,WESTRING_EXPLODEDONTOPTION_DONT\n\n// SuspendResume Option\nSuspendResumeSuspend=0,suspendresumeoption,true,WESTRING_SUSPENDRESUMEOPTION_SUSPEND\nSuspendResumeResume=0,suspendresumeoption,true,WESTRING_SUSPENDRESUMEOPTION_RESUME\n\n// Tournament Game Event Types\nGameEventTourneySoon=1,gameevent,EVENT_GAME_TOURNAMENT_FINISH_SOON,WESTRING_GAMEEVENT_TOURNAMENTFINISHSOON\nGameEventTourneyNow=1,gameevent,EVENT_GAME_TOURNAMENT_FINISH_NOW,WESTRING_GAMEEVENT_TOURNAMENTFINISHNOW\n\n\n// Mission Index\n// Tutorial\nMissionIndexT00=0,missionindex,bj_MISSION_INDEX_T00,WESTRING_MISSION_INDEX_T00\nMissionIndexT01=0,missionindex,bj_MISSION_INDEX_T01,WESTRING_MISSION_INDEX_T01\n// Human\nMissionIndexH00=0,missionindex,bj_MISSION_INDEX_H00,WESTRING_MISSION_INDEX_H00\nMissionIndexH01=0,missionindex,bj_MISSION_INDEX_H01,WESTRING_MISSION_INDEX_H01\nMissionIndexH02=0,missionindex,bj_MISSION_INDEX_H02,WESTRING_MISSION_INDEX_H02\nMissionIndexH03=0,missionindex,bj_MISSION_INDEX_H03,WESTRING_MISSION_INDEX_H03\nMissionIndexH04=0,missionindex,bj_MISSION_INDEX_H04,WESTRING_MISSION_INDEX_H04\nMissionIndexH05=0,missionindex,bj_MISSION_INDEX_H05,WESTRING_MISSION_INDEX_H05\nMissionIndexH06=0,missionindex,bj_MISSION_INDEX_H06,WESTRING_MISSION_INDEX_H06\nMissionIndexH07=0,missionindex,bj_MISSION_INDEX_H07,WESTRING_MISSION_INDEX_H07\nMissionIndexH08=0,missionindex,bj_MISSION_INDEX_H08,WESTRING_MISSION_INDEX_H08\nMissionIndexH09=0,missionindex,bj_MISSION_INDEX_H09,WESTRING_MISSION_INDEX_H09\nMissionIndexH10=0,missionindex,bj_MISSION_INDEX_H10,WESTRING_MISSION_INDEX_H10\nMissionIndexH11=0,missionindex,bj_MISSION_INDEX_H11,WESTRING_MISSION_INDEX_H11\n// Undead\nMissionIndexU00=0,missionindex,bj_MISSION_INDEX_U00,WESTRING_MISSION_INDEX_U00\nMissionIndexU01=0,missionindex,bj_MISSION_INDEX_U01,WESTRING_MISSION_INDEX_U01\nMissionIndexU02=0,missionindex,bj_MISSION_INDEX_U02,WESTRING_MISSION_INDEX_U02\nMissionIndexU03=0,missionindex,bj_MISSION_INDEX_U03,WESTRING_MISSION_INDEX_U03\nMissionIndexU05=0,missionindex,bj_MISSION_INDEX_U05,WESTRING_MISSION_INDEX_U05\nMissionIndexU07=0,missionindex,bj_MISSION_INDEX_U07,WESTRING_MISSION_INDEX_U07\nMissionIndexU08=0,missionindex,bj_MISSION_INDEX_U08,WESTRING_MISSION_INDEX_U08\nMissionIndexU09=0,missionindex,bj_MISSION_INDEX_U09,WESTRING_MISSION_INDEX_U09\nMissionIndexU10=0,missionindex,bj_MISSION_INDEX_U10,WESTRING_MISSION_INDEX_U10\nMissionIndexU11=0,missionindex,bj_MISSION_INDEX_U11,WESTRING_MISSION_INDEX_U11\n// Orc\nMissionIndexO00=0,missionindex,bj_MISSION_INDEX_O00,WESTRING_MISSION_INDEX_O00\nMissionIndexO01=0,missionindex,bj_MISSION_INDEX_O01,WESTRING_MISSION_INDEX_O01\nMissionIndexO02=0,missionindex,bj_MISSION_INDEX_O02,WESTRING_MISSION_INDEX_O02\nMissionIndexO03=0,missionindex,bj_MISSION_INDEX_O03,WESTRING_MISSION_INDEX_O03\nMissionIndexO04=0,missionindex,bj_MISSION_INDEX_O04,WESTRING_MISSION_INDEX_O04\nMissionIndexO05=0,missionindex,bj_MISSION_INDEX_O05,WESTRING_MISSION_INDEX_O05\nMissionIndexO06=0,missionindex,bj_MISSION_INDEX_O06,WESTRING_MISSION_INDEX_O06\nMissionIndexO07=0,missionindex,bj_MISSION_INDEX_O07,WESTRING_MISSION_INDEX_O07\nMissionIndexO08=0,missionindex,bj_MISSION_INDEX_O08,WESTRING_MISSION_INDEX_O08\nMissionIndexO09=0,missionindex,bj_MISSION_INDEX_O09,WESTRING_MISSION_INDEX_O09\nMissionIndexO10=0,missionindex,bj_MISSION_INDEX_O10,WESTRING_MISSION_INDEX_O10\n// Night Elf\nMissionIndexN00=0,missionindex,bj_MISSION_INDEX_N00,WESTRING_MISSION_INDEX_N00\nMissionIndexN01=0,missionindex,bj_MISSION_INDEX_N01,WESTRING_MISSION_INDEX_N01\nMissionIndexN02=0,missionindex,bj_MISSION_INDEX_N02,WESTRING_MISSION_INDEX_N02\nMissionIndexN03=0,missionindex,bj_MISSION_INDEX_N03,WESTRING_MISSION_INDEX_N03\nMissionIndexN04=0,missionindex,bj_MISSION_INDEX_N04,WESTRING_MISSION_INDEX_N04\nMissionIndexN05=0,missionindex,bj_MISSION_INDEX_N05,WESTRING_MISSION_INDEX_N05\nMissionIndexN06=0,missionindex,bj_MISSION_INDEX_N06,WESTRING_MISSION_INDEX_N06\nMissionIndexN07=0,missionindex,bj_MISSION_INDEX_N07,WESTRING_MISSION_INDEX_N07\n// Expansion Night Elf\nMissionIndexXN00=1,missionindex,bj_MISSION_INDEX_XN00,WESTRING_MISSION_INDEX_XN00\nMissionIndexXN01=1,missionindex,bj_MISSION_INDEX_XN01,WESTRING_MISSION_INDEX_XN01\nMissionIndexXN02=1,missionindex,bj_MISSION_INDEX_XN02,WESTRING_MISSION_INDEX_XN02\nMissionIndexXN03=1,missionindex,bj_MISSION_INDEX_XN03,WESTRING_MISSION_INDEX_XN03\nMissionIndexXN04=1,missionindex,bj_MISSION_INDEX_XN04,WESTRING_MISSION_INDEX_XN04\nMissionIndexXN05=1,missionindex,bj_MISSION_INDEX_XN05,WESTRING_MISSION_INDEX_XN05\nMissionIndexXN06=1,missionindex,bj_MISSION_INDEX_XN06,WESTRING_MISSION_INDEX_XN06\nMissionIndexXN07=1,missionindex,bj_MISSION_INDEX_XN07,WESTRING_MISSION_INDEX_XN07\nMissionIndexXN08=1,missionindex,bj_MISSION_INDEX_XN08,WESTRING_MISSION_INDEX_XN08\nMissionIndexXN09=1,missionindex,bj_MISSION_INDEX_XN09,WESTRING_MISSION_INDEX_XN09\nMissionIndexXN10=1,missionindex,bj_MISSION_INDEX_XN10,WESTRING_MISSION_INDEX_XN10\n// Expansion Human\nMissionIndexXH00=1,missionindex,bj_MISSION_INDEX_XH00,WESTRING_MISSION_INDEX_XH00\nMissionIndexXH01=1,missionindex,bj_MISSION_INDEX_XH01,WESTRING_MISSION_INDEX_XH01\nMissionIndexXH02=1,missionindex,bj_MISSION_INDEX_XH02,WESTRING_MISSION_INDEX_XH02\nMissionIndexXH03=1,missionindex,bj_MISSION_INDEX_XH03,WESTRING_MISSION_INDEX_XH03\nMissionIndexXH04=1,missionindex,bj_MISSION_INDEX_XH04,WESTRING_MISSION_INDEX_XH04\nMissionIndexXH05=1,missionindex,bj_MISSION_INDEX_XH05,WESTRING_MISSION_INDEX_XH05\nMissionIndexXH06=1,missionindex,bj_MISSION_INDEX_XH06,WESTRING_MISSION_INDEX_XH06\nMissionIndexXH07=1,missionindex,bj_MISSION_INDEX_XH07,WESTRING_MISSION_INDEX_XH07\nMissionIndexXH08=1,missionindex,bj_MISSION_INDEX_XH08,WESTRING_MISSION_INDEX_XH08\nMissionIndexXH09=1,missionindex,bj_MISSION_INDEX_XH09,WESTRING_MISSION_INDEX_XH09\n// Expansion Undead\nMissionIndexXU00=1,missionindex,bj_MISSION_INDEX_XU00,WESTRING_MISSION_INDEX_XU00\nMissionIndexXU01=1,missionindex,bj_MISSION_INDEX_XU01,WESTRING_MISSION_INDEX_XU01\nMissionIndexXU02=1,missionindex,bj_MISSION_INDEX_XU02,WESTRING_MISSION_INDEX_XU02\nMissionIndexXU03=1,missionindex,bj_MISSION_INDEX_XU03,WESTRING_MISSION_INDEX_XU03\nMissionIndexXU04=1,missionindex,bj_MISSION_INDEX_XU04,WESTRING_MISSION_INDEX_XU04\nMissionIndexXU05=1,missionindex,bj_MISSION_INDEX_XU05,WESTRING_MISSION_INDEX_XU05\nMissionIndexXU06=1,missionindex,bj_MISSION_INDEX_XU06,WESTRING_MISSION_INDEX_XU06\nMissionIndexXU07=1,missionindex,bj_MISSION_INDEX_XU07,WESTRING_MISSION_INDEX_XU07\nMissionIndexXU08=1,missionindex,bj_MISSION_INDEX_XU08,WESTRING_MISSION_INDEX_XU08\nMissionIndexXU09=1,missionindex,bj_MISSION_INDEX_XU09,WESTRING_MISSION_INDEX_XU09\nMissionIndexXU10=1,missionindex,bj_MISSION_INDEX_XU10,WESTRING_MISSION_INDEX_XU10\nMissionIndexXU11=1,missionindex,bj_MISSION_INDEX_XU11,WESTRING_MISSION_INDEX_XU11\nMissionIndexXU12=1,missionindex,bj_MISSION_INDEX_XU12,WESTRING_MISSION_INDEX_XU12\nMissionIndexXU13=1,missionindex,bj_MISSION_INDEX_XU13,WESTRING_MISSION_INDEX_XU13\n// Expansion Orc\nMissionIndexXO00=1,missionindex,bj_MISSION_INDEX_XO00,WESTRING_MISSION_INDEX_XO00\n\n// Campaign Index\nCampaignIndexT=0,campaignindex,bj_CAMPAIGN_INDEX_T,WESTRING_CAMPAIGN_INDEX_T\nCampaignIndexH=0,campaignindex,bj_CAMPAIGN_INDEX_H,WESTRING_CAMPAIGN_INDEX_H\nCampaignIndexU=0,campaignindex,bj_CAMPAIGN_INDEX_U,WESTRING_CAMPAIGN_INDEX_U\nCampaignIndexO=0,campaignindex,bj_CAMPAIGN_INDEX_O,WESTRING_CAMPAIGN_INDEX_O\nCampaignIndexN=0,campaignindex,bj_CAMPAIGN_INDEX_N,WESTRING_CAMPAIGN_INDEX_N\nCampaignIndexXN=1,campaignindex,bj_CAMPAIGN_INDEX_XN,WESTRING_CAMPAIGN_INDEX_XN\nCampaignIndexXH=1,campaignindex,bj_CAMPAIGN_INDEX_XH,WESTRING_CAMPAIGN_INDEX_XH\nCampaignIndexXU=1,campaignindex,bj_CAMPAIGN_INDEX_XU,WESTRING_CAMPAIGN_INDEX_XU\nCampaignIndexXO=1,campaignindex,bj_CAMPAIGN_INDEX_XO,WESTRING_CAMPAIGN_INDEX_XO\n\n// Cinematic Index\nCinematicIndexTOP=0,cinematicindex,bj_CINEMATICINDEX_TOP,WESTRING_CINEMATICTYPE_TOP\nCinematicIndexHOP=0,cinematicindex,bj_CINEMATICINDEX_HOP,WESTRING_CINEMATICTYPE_HOP\nCinematicIndexHED=0,cinematicindex,bj_CINEMATICINDEX_HED,WESTRING_CINEMATICTYPE_HED\nCinematicIndexUED=0,cinematicindex,bj_CINEMATICINDEX_UED,WESTRING_CINEMATICTYPE_UED\nCinematicIndexOED=0,cinematicindex,bj_CINEMATICINDEX_OED,WESTRING_CINEMATICTYPE_OED\nCinematicIndexNED=0,cinematicindex,bj_CINEMATICINDEX_NED,WESTRING_CINEMATICTYPE_NED\nCinematicIndexXOP=1,cinematicindex,bj_CINEMATICINDEX_XOP,WESTRING_CINEMATICTYPE_XOP\nCinematicIndexXED=1,cinematicindex,bj_CINEMATICINDEX_XED,WESTRING_CINEMATICTYPE_XED\n\n// Trigger Unit-Targeted Unit Orders\n// Common\nUnitOrderAttackUnit=0,unitorderutarg,`attack`,WESTRING_UNITORDERUTARG_ATTACK\nUnitOrderAttackUnitOnce=0,unitorderutarg,`attackonce`,WESTRING_UNITORDERUTARG_ATTACKONCE\nUnitOrderMoveUnit=0,unitorderutarg,`move`,WESTRING_UNITORDERUTARG_MOVE\nUnitOrderSmartUnit=1,unitorderutarg,`smart`,WESTRING_UNITORDERUTARG_SMART\nUnitOrderHarvest=0,unitorderutarg,`harvest`,WESTRING_UNITORDERUTARG_HARVEST\nUnitOrderRevive=0,unitorderutarg,`revive`,WESTRING_UNITORDERUTARG_REVIVE\nUnitOrderLoad=0,unitorderutarg,`load`,WESTRING_UNITORDERUTARG_LOAD\nUnitOrderUnload=0,unitorderutarg,`unload`,WESTRING_UNITORDERUTARG_UNLOAD\nUnitOrderBoard=0,unitorderutarg,`board`,WESTRING_UNITORDERUTARG_BOARD\nUnitOrderForceBoard=0,unitorderutarg,`forceboard`,WESTRING_UNITORDERUTARG_FORCEBOARD\n// Human\nUnitOrderRepair=0,unitorderutarg,`repair`,WESTRING_UNITORDERUTARG_REPAIR\nUnitOrderInnerFire=0,unitorderutarg,`innerfire`,WESTRING_UNITORDERUTARG_INNERFIRE\nUnitOrderDispel=0,unitorderutarg,`dispel`,WESTRING_UNITORDERUTARG_DISPEL\nUnitOrderHeal=0,unitorderutarg,`heal`,WESTRING_UNITORDERUTARG_HEAL\nUnitOrderSlow=0,unitorderutarg,`slow`,WESTRING_UNITORDERUTARG_SLOW\nUnitOrderInvisibility=0,unitorderutarg,`invisibility`,WESTRING_UNITORDERUTARG_INVISIBILITY\nUnitOrderPolymorph=0,unitorderutarg,`polymorph`,WESTRING_UNITORDERUTARG_POLYMORPH\nUnitOrderControlMagic=1,unitorderutarg,`controlmagic`,WESTRING_UNITORDERUTARG_CONTROLMAGIC\nUnitOrderSpellSteal=1,unitorderutarg,`spellsteal`,WESTRING_UNITORDERUTARG_SPELLSTEAL\nUnitOrderAerialShackles=1,unitorderutarg,`magicleash`,WESTRING_UNITORDERUTARG_AERIALSHACKLES\nUnitOrderMassTeleport=0,unitorderutarg,`massteleport`,WESTRING_UNITORDERUTARG_MASSTELEPORT\nUnitOrderBanish=1,unitorderutarg,`banish`,WESTRING_UNITORDERUTARG_BANISH\nUnitOrderSiphonMana=1,unitorderutarg,`drain`,WESTRING_UNITORDERUTARG_SIPHONMANA\nUnitOrderThunderBolt=0,unitorderutarg,`thunderbolt`,WESTRING_UNITORDERUTARG_THUNDERBOLT\nUnitOrderHolyBolt=0,unitorderutarg,`holybolt`,WESTRING_UNITORDERUTARG_HOLYBOLT\n// Orc\nUnitOrderRepairO=0,unitorderutarg,`repair`,WESTRING_UNITORDERUTARG_REPAIRO\nUnitOrderEnsnare=0,unitorderutarg,`ensnare`,WESTRING_UNITORDERUTARG_ENSNARE\nUnitOrderUnstableConcoction=1,unitorderutarg,`unstableconcoction`,WESTRING_UNITORDERUTARG_UNSTABLECONCOCTION\nUnitOrderPurge=0,unitorderutarg,`purge`,WESTRING_UNITORDERUTARG_PURGE\nUnitOrderLightningShield=0,unitorderutarg,`lightningshield`,WESTRING_UNITORDERUTARG_LIGHTNINGSHIELD\nUnitOrderBloodlust=0,unitorderutarg,`bloodlust`,WESTRING_UNITORDERUTARG_BLOODLUST\nUnitOrderSpiritLink=1,unitorderutarg,`spiritlink`,WESTRING_UNITORDERUTARG_SPIRITLINK\nUnitOrderDevour=0,unitorderutarg,`devour`,WESTRING_UNITORDERUTARG_DEVOUR\nUnitOrderChainLightning=0,unitorderutarg,`chainlightning`,WESTRING_UNITORDERUTARG_CHAINLIGHTNING\nUnitOrderHealingWave=1,unitorderutarg,`healingwave`,WESTRING_UNITORDERUTARG_HEALINGWAVE\nUnitOrderHex=1,unitorderutarg,`hex`,WESTRING_UNITORDERUTARG_HEX\nUnitOrderAncestralSpiritTarg=1,unitorderutarg,`ancestralspirittarg`,WESTRING_UNITORDERUTARG_ANCESTRALSPIRIT\n// Night Elf\nUnitOrderRenew=0,unitorderutarg,`renew`,WESTRING_UNITORDERUTARG_RENEW\nUnitOrderEntangle=0,unitorderutarg,`entangle`,WESTRING_UNITORDERUTARG_ENTANGLE\nUnitOrderEntangleInstant=0,unitorderutarg,`entangleinstant`,WESTRING_UNITORDERUTARG_ENTANGLEINSTANT\nUnitOrderReplenish=0,unitorderutarg,`recharge`,WESTRING_UNITORDERUTARG_REPLENISH\nUnitOrderMountHippogryph=0,unitorderutarg,`mounthippogryph`,WESTRING_UNITORDERUTARG_MOUNTHIPPOGRYPH\nUnitOrderLoadArcher=0,unitorderutarg,`loadarcher`,WESTRING_UNITORDERUTARG_LOADARCHER\nUnitOrderAutoDispel=0,unitorderutarg,`autodispel`,WESTRING_UNITORDERUTARG_AUTODISPEL\nUnitOrderFaerieFire=0,unitorderutarg,`faeriefire`,WESTRING_UNITORDERUTARG_FAERIEFIRE\nUnitOrderCyclone=0,unitorderutarg,`cyclone`,WESTRING_UNITORDERUTARG_CYCLONE\nUnitOrderRejuvination=0,unitorderutarg,`rejuvination`,WESTRING_UNITORDERUTARG_REJUVINATION\nUnitOrderVengeance=1,unitorderutarg,`vengeance`,WESTRING_UNITORDERUTARG_VENGEANCE\nUnitOrderManaBurn=0,unitorderutarg,`manaburn`,WESTRING_UNITORDERUTARG_MANABURN\nUnitOrderEntanglingRoots=0,unitorderutarg,`entanglingroots`,WESTRING_UNITORDERUTARG_ENTANGLINGROOTS\nUnitOrderShadowStrike=1,unitorderutarg,`shadowstrike`,WESTRING_UNITORDERUTARG_SHADOWSTRIKE\n// Undead\nUnitOrderRestoration=0,unitorderutarg,`restoration`,WESTRING_UNITORDERUTARG_RESTORE\nUnitOrderSacrificeAcolyte=0,unitorderutarg,`sacrifice`,WESTRING_UNITORDERUTARG_SACRIFICEACOLYTE\nUnitOrderSacrifice=0,unitorderutarg,`requestsacrifice`,WESTRING_UNITORDERUTARG_SACRIFICE\nUnitOrderUnsummon=0,unitorderutarg,`unsummon`,WESTRING_UNITORDERUTARG_UNSUMMON\nUnitOrderWeb=0,unitorderutarg,`web`,WESTRING_UNITORDERUTARG_WEB\nUnitOrderRaiseDead=0,unitorderutarg,`raisedead`,WESTRING_UNITORDERUTARG_RAISEDEAD\nUnitOrderUnholyFrenzy=0,unitorderutarg,`unholyfrenzy`,WESTRING_UNITORDERUTARG_UNHOLYFRENZY\nUnitOrderCripple=0,unitorderutarg,`cripple`,WESTRING_UNITORDERUTARG_CRIPPLE\nUnitOrderCurse=0,unitorderutarg,`curse`,WESTRING_UNITORDERUTARG_CURSE\nUnitOrderAntiMagicShell=0,unitorderutarg,`antimagicshell`,WESTRING_UNITORDERUTARG_ANTIMAGICSHELL\nUnitOrderPossession=0,unitorderutarg,`possession`,WESTRING_UNITORDERUTARG_POSSESSION\nUnitOrderAbsorbMana=1,unitorderutarg,`absorb`,WESTRING_UNITORDERUTARG_ABSORBMANA\nUnitOrderFlamingAttack=1,unitorderutarg,`flamingattacktarg`,WESTRING_UNITORDERUTARG_FLAMINGATTACK\nUnitOrderImpale=1,unitorderutarg,`impale`,WESTRING_UNITORDERUTARG_IMPALE\nUnitOrderCarrionScarabs=1,unitorderutarg,`carrionscarabs`,WESTRING_UNITORDERUTARG_CARRIONSCARABS\nUnitOrderDeathCoil=0,unitorderutarg,`deathcoil`,WESTRING_UNITORDERUTARG_DEATHCOIL\nUnitOrderDeathPact=0,unitorderutarg,`deathpact`,WESTRING_UNITORDERUTARG_DEATHPACT\nUnitOrderSleep=0,unitorderutarg,`sleep`,WESTRING_UNITORDERUTARG_SLEEP\nUnitOrderFrostNova=0,unitorderutarg,`frostnova`,WESTRING_UNITORDERUTARG_FROSTNOVA\nUnitOrderFrostArmor=0,unitorderutarg,`frostarmor`,WESTRING_UNITORDERUTARG_FROSTARMOR\nUnitOrderDarkRitual=0,unitorderutarg,`darkritual`,WESTRING_UNITORDERUTARG_DARKRITUAL\n// Neutral\nUnitOrderCreepDevour=1,unitorderutarg,`creepdevour`,WESTRING_UNITORDERUTARG_CREEPDEVOUR\nUnitOrderFirebolt=0,unitorderutarg,`firebolt`,WESTRING_UNITORDERUTARG_FIREBOLT\nUnitOrderCreepHeal=0,unitorderutarg,`creepheal`,WESTRING_UNITORDERUTARG_CREEPHEAL\nUnitOrderCreepThunderBolt=0,unitorderutarg,`creepthunderbolt`,WESTRING_UNITORDERUTARG_CREEPTHUNDERBOLT\nUnitOrderParasite=1,unitorderutarg,`parasite`,WESTRING_UNITORDERUTARG_PARASITE\nUnitOrderSelfDestructUnit=1,unitorderutarg,`selfdestruct`,WESTRING_UNITORDERUTARG_SELFDESTRUCT\nUnitOrderBlackArrow=1,unitorderutarg,`blackarrow`,WESTRING_UNITORDERUTARG_BLACKARROW\nUnitOrderCharm=1,unitorderutarg,`charm`,WESTRING_UNITORDERUTARG_CHARM\nUnitOrderLifeDrain=1,unitorderutarg,`drain`,WESTRING_UNITORDERUTARG_LIFEDRAIN\nUnitOrderColdArrow=1,unitorderutarg,`coldarrowstarg`,WESTRING_UNITORDERUTARG_COLDARROW\nUnitOrderForkedLightning=1,unitorderutarg,`forkedlightning`,WESTRING_UNITORDERUTARG_FORKEDLIGHTNING\nUnitOrderStrongDrink=1,unitorderutarg,`drunkenhaze`,WESTRING_UNITORDERUTARG_STRONGDRINK\nUnitOrderDoom=1,unitorderutarg,`doom`,WESTRING_UNITORDERUTARG_DOOM\nUnitOrderAcidBomb=1,unitorderutarg,`acidbomb`,WESTRING_UNITORDERUTARG_ACIDBOMB\nUnitOrderTransmute=1,unitorderutarg,`transmute`,WESTRING_UNITORDERUTARG_TRANSMUTE\nUnitOrderSoulBurn=1,unitorderutarg,`soulburn`,WESTRING_UNITORDERUTARG_SOULBURN\nUnitOrderPoisonArrow=0,unitorderutarg,`poisonarrowstarg`,WESTRING_UNITORDERUTARG_POISONARROW\nUnitOrderIncinerateArrow=1,unitorderutarg,`incineratearrow`,WESTRING_UNITORDERUTARG_INCINERATEARROW\n// Special\nUnitOrderFingerOfDeath=0,unitorderutarg,`fingerofdeath`,WESTRING_UNITORDERUTARG_FINGEROFDEATH\nUnitOrderDarkConversion=0,unitorderutarg,`darkconversion`,WESTRING_UNITORDERUTARG_DARKCONVERSION\nUnitOrderSoulPreservation=0,unitorderutarg,`soulpreservation`,WESTRING_UNITORDERUTARG_SOULPRESERVATION\nUnitOrderDarkConversionFast=0,unitorderutarg,`darkconversion`,WESTRING_UNITORDERUTARG_DARKCONVERSIONFAST\n\n// Trigger Point-Targeted Unit Orders\n// Common\nUnitOrderAttack=0,unitorderptarg,`attack`,WESTRING_UNITORDERPTARG_ATTACK\nUnitOrderAttackGround=0,unitorderptarg,`attackground`,WESTRING_UNITORDERPTARG_ATTACKGROUND\nUnitOrderMove=0,unitorderptarg,`move`,WESTRING_UNITORDERPTARG_MOVE\nUnitOrderPatrol=0,unitorderptarg,`patrol`,WESTRING_UNITORDERPTARG_PATROL\nUnitOrderSmartPoint=1,unitorderptarg,`smart`,WESTRING_UNITORDERPTARG_SMART\nUnitOrderSetRally=0,unitorderptarg,`setrally`,WESTRING_UNITORDERPTARG_SETRALLY\nUnitOrderUnloadAll=0,unitorderptarg,`unloadall`,WESTRING_UNITORDERPTARG_UNLOADALL\n// Human\nUnitOrderFlare=0,unitorderptarg,`flare`,WESTRING_UNITORDERPTARG_FLARE\nUnitOrderCloudOfFog=1,unitorderptarg,`cloudoffog`,WESTRING_UNITORDERPTARG_CLOUDOFFOG\nUnitOrderBlizzard=0,unitorderptarg,`blizzard`,WESTRING_UNITORDERPTARG_BLIZZARD\nUnitOrderFlameStrike=1,unitorderptarg,`flamestrike`,WESTRING_UNITORDERPTARG_FLAMESTRIKE\n// Orc\nUnitOrderSentryWard=0,unitorderptarg,`evileye`,WESTRING_UNITORDERPTARG_SENTRYWARD\nUnitOrderStasisTrap=0,unitorderptarg,`stasistrap`,WESTRING_UNITORDERPTARG_STASISTRAP\nUnitOrderHealingWard=0,unitorderptarg,`healingward`,WESTRING_UNITORDERPTARG_HEALINGWARD\nUnitOrderDisenchant=1,unitorderptarg,`disenchant`,WESTRING_UNITORDERPTARG_DISENCHANT\nUnitOrderFarSight=0,unitorderptarg,`farsight`,WESTRING_UNITORDERPTARG_FARSIGHT\nUnitOrderEarthquake=0,unitorderptarg,`earthquake`,WESTRING_UNITORDERPTARG_EARTHQUAKE\nUnitOrderSerpentWard=1,unitorderptarg,`ward`,WESTRING_UNITORDERPTARG_SERPENTWARD\nUnitOrderShockwave=0,unitorderptarg,`shockwave`,WESTRING_UNITORDERPTARG_SHOCKWAVE\n// Night Elf\nUnitOrderRoot=0,unitorderptarg,`root`,WESTRING_UNITORDERPTARG_ROOT\nUnitOrderDetonate=0,unitorderptarg,`detonate`,WESTRING_UNITORDERPTARG_DETONATE\nUnitOrderForceOfNature=0,unitorderptarg,`forceofnature`,WESTRING_UNITORDERPTARG_FORCEOFNATURE\nUnitOrderStarfall=0,unitorderptarg,`obsolete`,WESTRING_UNITORDERPTARG_STARFALL\nUnitOrderBlink=1,unitorderptarg,`blink`,WESTRING_UNITORDERPTARG_BLINK\n// Undead\nUnitOrderDevourMagic=1,unitorderptarg,`devourmagic`,WESTRING_UNITORDERPTARG_DEVOURMAGIC\nUnitOrderImpalePoint=1,unitorderptarg,`impale`,WESTRING_UNITORDERPTARG_IMPALE\nUnitOrderCarrionSwarm=0,unitorderptarg,`carrionswarm`,WESTRING_UNITORDERPTARG_CARRIONSWARM\nUnitOrderDarkSummoning=0,unitorderptarg,`dreadlordinferno`,WESTRING_UNITORDERPTARG_DARKSUMMONING\nUnitOrderDeathAndDecay=0,unitorderptarg,`deathanddecay`,WESTRING_UNITORDERPTARG_DEATHANDDECAY\n// Neutral\nUnitOrderBreathOfFrost=1,unitorderptarg,`breathoffrost`,WESTRING_UNITORDERPTARG_BREATHOFFROST\nUnitOrderMonsoon=1,unitorderptarg,`monsoon`,WESTRING_UNITORDERPTARG_MONSOON\nUnitOrderSelfDestruct=0,unitorderptarg,`selfdestruct`,WESTRING_UNITORDERPTARG_SELFDESTRUCT\nUnitOrderStampede=1,unitorderptarg,`stampede`,WESTRING_UNITORDERPTARG_STAMPEDE\nUnitOrderSilence=1,unitorderptarg,`silence`,WESTRING_UNITORDERPTARG_SILENCE\nUnitOrderTornado=1,unitorderptarg,`tornado`,WESTRING_UNITORDERPTARG_TORNADO\nUnitOrderBreathOfFire=1,unitorderptarg,`breathoffire`,WESTRING_UNITORDERPTARG_BREATHOFFIRE\nUnitOrderHeroRainOfFire=1,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_HERORAINOFFIRE\nUnitOrderHealingSpray=1,unitorderptarg,`healingspray`,WESTRING_UNITORDERPTARG_HEALINGSPRAY\nUnitOrderClusterRockets=1,unitorderptarg,`clusterrockets`,WESTRING_UNITORDERPTARG_CLUSTERROCKETS\nUnitOrderSummonFactory=1,unitorderptarg,`summonfactory`,WESTRING_UNITORDERPTARG_SUMMONFACTORY\nUnitOrderVolcano=1,unitorderptarg,`volcano`,WESTRING_UNITORDERPTARG_VOLCANO\n// Special\nUnitOrderDarkPortal=0,unitorderptarg,`darkportal`,WESTRING_UNITORDERPTARG_DARKPORTAL\nUnitOrderRainOfChaos=0,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_RAINOFCHAOS\nUnitOrderRainOfFire=0,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_RAINOFFIRE\nUnitOrderInferno=0,unitorderptarg,`inferno`,WESTRING_UNITORDERPTARG_INFERNO\nUnitOrderDarkSummoningOld=0,unitorderptarg,`darksummoning`,WESTRING_UNITORDERPTARG_DARKSUMMONINGOLD\n\n// Trigger Destructible-Targeted Unit Orders\n// Common\nUnitOrderAttackDestructible=0,unitorderdtarg,`attack`,WESTRING_UNITORDERDTARG_ATTACK\nUnitOrderSmartDestructible=1,unitorderdtarg,`smart`,WESTRING_UNITORDERDTARG_SMART\nUnitOrderHarvestDestructible=0,unitorderdtarg,`harvest`,WESTRING_UNITORDERDTARG_HARVEST\n// Human\n// Orc\n// Night Elf\nUnitOrderConsumeTree=0,unitorderdtarg,`eattree`,WESTRING_UNITORDERDTARG_CONSUMETREE\nUnitOrderSentinel=0,unitorderdtarg,`sentinel`,WESTRING_UNITORDERDTARG_SENTINEL\nUnitOrderGrabTree=1,unitorderdtarg,`grabtree`,WESTRING_UNITORDERDTARG_GRABTREE\n// Undead\n// Neutral\n// Special\n\n// Trigger Item-Targeted Unit Orders\n// Common\nUnitOrderAttackItem=1,unitorderitarg,`attack`,WESTRING_UNITORDERITARG_ATTACK\nUnitOrderAttackItemOnce=1,unitorderitarg,`attackonce`,WESTRING_UNITORDERITARG_ATTACKONCE\nUnitOrderMoveItem=1,unitorderitarg,`move`,WESTRING_UNITORDERITARG_MOVE\nUnitOrderSmartItem=1,unitorderitarg,`smart`,WESTRING_UNITORDERITARG_SMART\n\n// Trigger Immediate / Untargeted Unit Orders\n// Common\nUnitOrderStop=0,unitordernotarg,`stop`,WESTRING_UNITORDERNOTARG_STOP\nUnitOrderHoldPosition=0,unitordernotarg,`holdposition`,WESTRING_UNITORDERNOTARG_HOLDPOSITION\nUnitOrderAutoHarvestGold=0,unitordernotarg,`autoharvestgold`,WESTRING_UNITORDERNOTARG_AUTOHARVESTGOLD\nUnitOrderAutoHarvestLumber=0,unitordernotarg,`autoharvestlumber`,WESTRING_UNITORDERNOTARG_AUTOHARVESTLUMBER\nUnitOrderReturnResources=0,unitordernotarg,`returnresources`,WESTRING_UNITORDERNOTARG_RETURNRESOURCES\nUnitOrderBuild=1,unitordernotarg,`build`,WESTRING_UNITORDERNOTARG_BUILD\nUnitOrderLevelup=1,unitordernotarg,`levelup`,WESTRING_UNITORDERNOTARG_LEVELUP\n// Human\nUnitOrderHumanBuild=1,unitordernotarg,`humanbuild`,WESTRING_UNITORDERNOTARG_HUMANBUILD\nUnitOrderTownBellOn=0,unitordernotarg,`townbellon`,WESTRING_UNITORDERNOTARG_TOWNBELLON\nUnitOrderTownBellOff=0,unitordernotarg,`townbelloff`,WESTRING_UNITORDERNOTARG_TOWNBELLOFF\nUnitOrderMilitia=0,unitordernotarg,`militia`,WESTRING_UNITORDERNOTARG_MILITIA\nUnitOrderMilitiaOff=0,unitordernotarg,`militiaoff`,WESTRING_UNITORDERNOTARG_MILITIAOFF\nUnitOrderRepairOn=0,unitordernotarg,`repairon`,WESTRING_UNITORDERNOTARG_REPAIRON\nUnitOrderRepairOff=0,unitordernotarg,`repairoff`,WESTRING_UNITORDERNOTARG_REPAIROFF\nUnitOrderDefend=0,unitordernotarg,`defend`,WESTRING_UNITORDERNOTARG_DEFEND\nUnitOrderUnDefend=0,unitordernotarg,`undefend`,WESTRING_UNITORDERNOTARG_UNDEFEND\nUnitOrderHealOn=0,unitordernotarg,`healon`,WESTRING_UNITORDERNOTARG_HEALON\nUnitOrderHealOff=0,unitordernotarg,`healoff`,WESTRING_UNITORDERNOTARG_HEALOFF\nUnitOrderInnerFireOn=0,unitordernotarg,`innerfireon`,WESTRING_UNITORDERNOTARG_INNERFIREON\nUnitOrderInnerFireOff=0,unitordernotarg,`innerfireoff`,WESTRING_UNITORDERNOTARG_INNERFIREOFF\nUnitOrderSlowOn=0,unitordernotarg,`slowon`,WESTRING_UNITORDERNOTARG_SLOWON\nUnitOrderSlowOff=0,unitordernotarg,`slowoff`,WESTRING_UNITORDERNOTARG_SLOWOFF\nUnitOrderSpellStealOn=1,unitordernotarg,`spellstealon`,WESTRING_UNITORDERNOTARG_SPELLSTEALON\nUnitOrderSpellStealOff=1,unitordernotarg,`spellstealoff`,WESTRING_UNITORDERNOTARG_SPELLSTEALOFF\nUnitOrderWaterElemental=0,unitordernotarg,`waterelemental`,WESTRING_UNITORDERNOTARG_WATERELEMENTAL\nUnitOrderPhoenix=1,unitordernotarg,`phoenix`,WESTRING_UNITORDERNOTARG_PHOENIX\nUnitOrderThunderClap=0,unitordernotarg,`thunderclap`,WESTRING_UNITORDERNOTARG_THUNDERCLAP\nUnitOrderAvatar=0,unitordernotarg,`avatar`,WESTRING_UNITORDERNOTARG_AVATAR\nUnitOrderDivineShield=0,unitordernotarg,`divineshield`,WESTRING_UNITORDERNOTARG_DIVINESHIELD\nUnitOrderUnDivineShield=0,unitordernotarg,`undivineshield`,WESTRING_UNITORDERNOTARG_UNDIVINESHIELD\nUnitOrderResurrection=0,unitordernotarg,`resurrection`,WESTRING_UNITORDERNOTARG_RESURRECTION\n// Orc\nUnitOrderOrcBuild=1,unitordernotarg,`orcbuild`,WESTRING_UNITORDERNOTARG_ORCBUILD\nUnitOrderBattleStations=0,unitordernotarg,`battlestations`,WESTRING_UNITORDERNOTARG_BATTLESTATIONS\nUnitOrderStandDown=0,unitordernotarg,`standdown`,WESTRING_UNITORDERNOTARG_STANDDOWN\nUnitOrderRepairOOn=0,unitordernotarg,`repairon`,WESTRING_UNITORDERNOTARG_REPAIROON\nUnitOrderRepairOOff=0,unitordernotarg,`repairoff`,WESTRING_UNITORDERNOTARG_REPAIROOFF\nUnitOrderBerserk=1,unitordernotarg,`berserk`,WESTRING_UNITORDERNOTARG_BERSERK\nUnitOrderBloodlustOn=0,unitordernotarg,`bloodluston`,WESTRING_UNITORDERNOTARG_BLOODLUSTON\nUnitOrderBloodlustOff=0,unitordernotarg,`bloodlustoff`,WESTRING_UNITORDERNOTARG_BLOODLUSTOFF\nUnitOrderAncestralSpirit=1,unitordernotarg,`ancestralspirit`,WESTRING_UNITORDERNOTARG_ANCESTRALSPIRIT\nUnitOrderEtherealForm=1,unitordernotarg,`uncorporealform`,WESTRING_UNITORDERNOTARG_ETHEREALFORM\nUnitOrderCorporealForm=1,unitordernotarg,`corporealform`,WESTRING_UNITORDERNOTARG_CORPOREALFORM\nUnitOrderWindWalk=0,unitordernotarg,`windwalk`,WESTRING_UNITORDERNOTARG_WINDWALK\nUnitOrderMirrorImage=0,unitordernotarg,`mirrorimage`,WESTRING_UNITORDERNOTARG_MIRRORIMAGE\nUnitOrderWhirlWind=0,unitordernotarg,`whirlwind`,WESTRING_UNITORDERNOTARG_BLADESTORM\nUnitOrderSpiritWolf=0,unitordernotarg,`spiritwolf`,WESTRING_UNITORDERNOTARG_FERALSPIRIT\nUnitOrderVoodoo=1,unitordernotarg,`voodoo`,WESTRING_UNITORDERNOTARG_VOODOO\nUnitOrderStomp=0,unitordernotarg,`stomp`,WESTRING_UNITORDERNOTARG_WARSTOMP\n// Night Elf\nUnitOrderNightElfBuild=1,unitordernotarg,`nightelfbuild`,WESTRING_UNITORDERNOTARG_NIGHTELFBUILD\nUnitOrderUnRoot=0,unitordernotarg,`unroot`,WESTRING_UNITORDERNOTARG_UNROOT\nUnitOrderAutoEntangle=1,unitordernotarg,`autoentangle`,WESTRING_UNITORDERNOTARG_AUTOENTANGLE\nUnitOrderAutoEntangleInstant=1,unitordernotarg,`autoentangleinstant`,WESTRING_UNITORDERNOTARG_AUTOENTANGLEINSTANT\nUnitOrderReplenishOn=1,unitordernotarg,`rechargeon`,WESTRING_UNITORDERNOTARG_REPLENISHON\nUnitOrderReplenishOff=1,unitordernotarg,`rechargeoff`,WESTRING_UNITORDERNOTARG_REPLENISHOFF\nUnitOrderAmbush=0,unitordernotarg,`ambush`,WESTRING_UNITORDERNOTARG_HIDE\nUnitOrderRenewOn=0,unitordernotarg,`renewon`,WESTRING_UNITORDERNOTARG_RENEWON\nUnitOrderRenewOff=0,unitordernotarg,`renewoff`,WESTRING_UNITORDERNOTARG_RENEWOFF\nUnitOrderCoupleInstant1=1,unitordernotarg,`coupleinstant`,WESTRING_UNITORDERNOTARG_COUPLEINSTANT1\nUnitOrderCoupleInstant2=1,unitordernotarg,`coupleinstant`,WESTRING_UNITORDERNOTARG_COUPLEINSTANT2\nUnitOrderDecouple=1,unitordernotarg,`decouple`,WESTRING_UNITORDERNOTARG_DECOUPLE\nUnitOrderAutoDispelOn=0,unitordernotarg,`autodispelon`,WESTRING_UNITORDERNOTARG_AUTODISPELON\nUnitOrderAutoDispelOff=0,unitordernotarg,`autodispeloff`,WESTRING_UNITORDERNOTARG_AUTODISPELOFF\nUnitOrderFaerieFireOn=0,unitordernotarg,`faeriefireon`,WESTRING_UNITORDERNOTARG_FAERIEFIREON\nUnitOrderFaerieFireOff=0,unitordernotarg,`faeriefireoff`,WESTRING_UNITORDERNOTARG_FAERIEFIREOFF\nUnitOrderRavenForm=0,unitordernotarg,`ravenform`,WESTRING_UNITORDERNOTARG_RAVENFORM\nUnitOrderUnRavenForm=0,unitordernotarg,`unravenform`,WESTRING_UNITORDERNOTARG_UNRAVENFORM\nUnitOrderRoar=0,unitordernotarg,`roar`,WESTRING_UNITORDERNOTARG_ROAR\nUnitOrderBearForm=0,unitordernotarg,`bearform`,WESTRING_UNITORDERNOTARG_BEARFORM\nUnitOrderUnBearForm=0,unitordernotarg,`unbearform`,WESTRING_UNITORDERNOTARG_UNBEARFORM\nUnitOrderTaunt=1,unitordernotarg,`taunt`,WESTRING_UNITORDERNOTARG_TAUNT\nUnitOrderManaFlareOn=1,unitordernotarg,`manaflareon`,WESTRING_UNITORDERNOTARG_MANAFLAREON\nUnitOrderManaFlareOff=1,unitordernotarg,`manaflareoff`,WESTRING_UNITORDERNOTARG_MANAFLAREOFF\nUnitOrderPhaseShift=1,unitordernotarg,`phaseshift`,WESTRING_UNITORDERNOTARG_PHASESHIFT\nUnitOrderPhaseShiftOn=1,unitordernotarg,`phaseshifton`,WESTRING_UNITORDERNOTARG_PHASESHIFTON\nUnitOrderPhaseShiftOff=1,unitordernotarg,`phaseshiftoff`,WESTRING_UNITORDERNOTARG_PHASESHIFTOFF\nUnitOrderVengeanceInstant=1,unitordernotarg,`vengeanceinstant`,WESTRING_UNITORDERNOTARG_VENGEANCEINSTANT\nUnitOrderVengeanceOn=1,unitordernotarg,`vengeanceon`,WESTRING_UNITORDERNOTARG_VENGEANCEON\nUnitOrderVengeanceOff=1,unitordernotarg,`vengeanceoff`,WESTRING_UNITORDERNOTARG_VENGEANCEOFF\nUnitOrderImmolation=0,unitordernotarg,`immolation`,WESTRING_UNITORDERNOTARG_IMMOLATION\nUnitOrderUnImmolation=0,unitordernotarg,`unimmolation`,WESTRING_UNITORDERNOTARG_UNIMMOLATION\nUnitOrderMetamorphosis=0,unitordernotarg,`metamorphosis`,WESTRING_UNITORDERNOTARG_METAMORPHOSIS\nUnitOrderTranquility=0,unitordernotarg,`tranquility`,WESTRING_UNITORDERNOTARG_TRANQUILITY\nUnitOrderSearingArrows=0,unitordernotarg,`flamingarrows`,WESTRING_UNITORDERNOTARG_SEARINGARROWS\nUnitOrderUnSearingArrows=0,unitordernotarg,`unflamingarrows`,WESTRING_UNITORDERNOTARG_UNSEARINGARROWS\nUnitOrderScout=0,unitordernotarg,`scout`,WESTRING_UNITORDERNOTARG_SCOUT\nUnitOrderStarfall2=0,unitordernotarg,`starfall`,WESTRING_UNITORDERNOTARG_STARFALL\nUnitOrderFanOfKnives=1,unitordernotarg,`fanofknives`,WESTRING_UNITORDERNOTARG_FANOFKNIVES\nUnitOrderSpiritOfVengeance=1,unitordernotarg,`spiritofvengeance`,WESTRING_UNITORDERNOTARG_SPIRITOFVENGEANCE\n// Undead\nUnitOrderUndeadBuild=1,unitordernotarg,`undeadbuild`,WESTRING_UNITORDERNOTARG_UNDEADBUILD\nUnitOrderRestorationOn=0,unitordernotarg,`restorationon`,WESTRING_UNITORDERNOTARG_RESTOREON\nUnitOrderRestorationOff=0,unitordernotarg,`restorationoff`,WESTRING_UNITORDERNOTARG_RESTOREOFF\nUnitOrderCannibalize=0,unitordernotarg,`cannibalize`,WESTRING_UNITORDERNOTARG_CANNIBALIZE\nUnitOrderWebOn=0,unitordernotarg,`webon`,WESTRING_UNITORDERNOTARG_WEBON\nUnitOrderWebOff=0,unitordernotarg,`weboff`,WESTRING_UNITORDERNOTARG_WEBOFF\nUnitOrderBurrow=1,unitordernotarg,`burrow`,WESTRING_UNITORDERNOTARG_BURROW\nUnitOrderUnBurrow=1,unitordernotarg,`unburrow`,WESTRING_UNITORDERNOTARG_UNBURROW\nUnitOrderLoadCorpse=0,unitordernotarg,`loadcorpse`,WESTRING_UNITORDERNOTARG_LOADCORPSE\nUnitOrderUnloadAllCorpses=0,unitordernotarg,`unloadallcorpses`,WESTRING_UNITORDERNOTARG_UNLOADALLCORPSES\nUnitOrderStoneForm=0,unitordernotarg,`stoneform`,WESTRING_UNITORDERNOTARG_STONEFORM\nUnitOrderUnStoneForm=0,unitordernotarg,`unstoneform`,WESTRING_UNITORDERNOTARG_UNSTONEFORM\nUnitOrderRaiseDeadInstant=1,unitordernotarg,`instant`,WESTRING_UNITORDERNOTARG_RAISEDEAD\nUnitOrderRaiseDeadOn=0,unitordernotarg,`raisedeadon`,WESTRING_UNITORDERNOTARG_RAISEDEADON\nUnitOrderRaiseDeadOff=0,unitordernotarg,`raisedeadoff`,WESTRING_UNITORDERNOTARG_RAISEDEADOFF\nUnitOrderCurseOn=0,unitordernotarg,`curseon`,WESTRING_UNITORDERNOTARG_CURSEON\nUnitOrderCurseOff=0,unitordernotarg,`curseoff`,WESTRING_UNITORDERNOTARG_CURSEOFF\nUnitOrderFlamingAttackOn=1,unitordernotarg,`flamingattack`,WESTRING_UNITORDERNOTARG_FLAMINGATTACKON\nUnitOrderFlamingAttackOff=1,unitordernotarg,`unflamingattack`,WESTRING_UNITORDERNOTARG_FLAMINGATTACKOFF\nUnitOrderSphinxForm=1,unitordernotarg,`avengerform`,WESTRING_UNITORDERNOTARG_SPHINXFORM\nUnitOrderReplenishLife=1,unitordernotarg,`replenishlife`,WESTRING_UNITORDERNOTARG_REPLENISHLIFE\nUnitOrderReplenishLifeOn=1,unitordernotarg,`replenishlifeon`,WESTRING_UNITORDERNOTARG_REPLENISHLIFEON\nUnitOrderReplenishLifeOff=1,unitordernotarg,`replenishlifeoff`,WESTRING_UNITORDERNOTARG_REPLENISHLIFEOFF\nUnitOrderReplenishMana=1,unitordernotarg,`replenishmana`,WESTRING_UNITORDERNOTARG_REPLENISHMANA\nUnitOrderReplenishManaOn=1,unitordernotarg,`replenishmanaon`,WESTRING_UNITORDERNOTARG_REPLENISHMANAON\nUnitOrderReplenishManaOff=1,unitordernotarg,`replenishmanaoff`,WESTRING_UNITORDERNOTARG_REPLENISHMANAOFF\nUnitOrderCarrionScarabsOn=1,unitordernotarg,`carrionscarabson`,WESTRING_UNITORDERNOTARG_CARRIONSCARABSON\nUnitOrderCarrionScarabsOff=1,unitordernotarg,`carrionscarabsoff`,WESTRING_UNITORDERNOTARG_CARRIONSCARABSOFF\nUnitOrderCarrionScarabsInstant=1,unitordernotarg,`carrionscarabsinstant`,WESTRING_UNITORDERNOTARG_CARRIONSCARABS\nUnitOrderLocustSwarm=1,unitordernotarg,`locustswarm`,WESTRING_UNITORDERNOTARG_LOCUSTSWARM\nUnitOrderAnimateDead=0,unitordernotarg,`animatedead`,WESTRING_UNITORDERNOTARG_ANIMATEDEAD\nUnitOrderFrostArmorOn=0,unitordernotarg,`frostarmoron`,WESTRING_UNITORDERNOTARG_FROSTARMORON\nUnitOrderFrostArmorOff=0,unitordernotarg,`frostarmoroff`,WESTRING_UNITORDERNOTARG_FROSTARMOROFF\n// Neutral\nUnitOrderNagaBuild=1,unitordernotarg,`nagabuild`,WESTRING_UNITORDERNOTARG_NAGABUILD\nUnitOrderCreepAnimateDead=0,unitordernotarg,`creepanimatedead`,WESTRING_UNITORDERNOTARG_CREEPANIMATEDEAD\nUnitOrderCreepHealOn=0,unitordernotarg,`creephealon`,WESTRING_UNITORDERNOTARG_CREEPHEALON\nUnitOrderCreepHealOff=0,unitordernotarg,`creephealoff`,WESTRING_UNITORDERNOTARG_CREEPHEALOFF\nUnitOrderRevenge=0,unitordernotarg,`revenge`,WESTRING_UNITORDERNOTARG_REVENGE\nUnitOrderCreepThunderClap=0,unitordernotarg,`creepthunderclap`,WESTRING_UNITORDERNOTARG_CREEPTHUNDERCLAP\nUnitOrderWateryMinion=1,unitordernotarg,`wateryminion`,WESTRING_UNITORDERNOTARG_WATERYMINION\nUnitOrderSelfDestructOn=1,unitordernotarg,`selfdestructon`,WESTRING_UNITORDERNOTARG_SELFDESTRUCTON\nUnitOrderSelfDestructOff=1,unitordernotarg,`selfdestructoff`,WESTRING_UNITORDERNOTARG_SELFDESTRUCTOFF\nUnitOrderSummonGrizzly=1,unitordernotarg,`summongrizzly`,WESTRING_UNITORDERNOTARG_SUMMONGRIZZLY\nUnitOrderSummonQuillbeast=1,unitordernotarg,`summonquillbeast`,WESTRING_UNITORDERNOTARG_SUMMONQUILLBEAST\nUnitOrderSummonWarEagle=1,unitordernotarg,`summonwareagle`,WESTRING_UNITORDERNOTARG_SUMMONWAREAGLE\nUnitOrderBlackArrowOn=1,unitordernotarg,`blackarrowon`,WESTRING_UNITORDERNOTARG_BLACKARROWON\nUnitOrderBlackArrowOff=1,unitordernotarg,`blackarrowoff`,WESTRING_UNITORDERNOTARG_BLACKARROWOFF\nUnitOrderColdArrowOn=1,unitordernotarg,`coldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWON\nUnitOrderColdArrowOff=1,unitordernotarg,`uncoldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWOFF\nUnitOrderManaShieldOn=1,unitordernotarg,`manashieldon`,WESTRING_UNITORDERNOTARG_MANASHIELDON\nUnitOrderManaShieldOff=1,unitordernotarg,`manashieldoff`,WESTRING_UNITORDERNOTARG_MANASHIELDOFF\nUnitOrderElementalFury=1,unitordernotarg,`elementalfury`,WESTRING_UNITORDERNOTARG_ELEMENTALFURY\nUnitOrderHowlOfTerror=1,unitordernotarg,`howlofterror`,WESTRING_UNITORDERNOTARG_HOWLOFTERROR\nUnitOrderPoisonArrows=0,unitordernotarg,`poisonarrows`,WESTRING_UNITORDERNOTARG_POISONARROWON\nUnitOrderUnPoisonArrows=0,unitordernotarg,`unpoisonarrows`,WESTRING_UNITORDERNOTARG_POISONARROWOFF\nUnitOrderChemicalRage=1,unitordernotarg,`chemicalrage`,WESTRING_UNITORDERNOTARG_CHEMICALRAGE\nUnitOrderRoboGoblin=1,unitordernotarg,`robogoblin`,WESTRING_UNITORDERNOTARG_ROBOGOBLIN\nUnitOrderUnRoboGoblin=1,unitordernotarg,`unrobogoblin`,WESTRING_UNITORDERNOTARG_UNROBOGOBLIN\nUnitOrderLavaMonster=1,unitordernotarg,`lavamonster`,WESTRING_UNITORDERNOTARG_LAVAMONSTER\nUnitOrderIncinerateArrowOn=1,unitordernotarg,`incineratearrowon`,WESTRING_UNITORDERNOTARG_INCINERATEARROWON\nUnitOrderIncinerateArrowOff=1,unitordernotarg,`incineratearrowoff`,WESTRING_UNITORDERNOTARG_INCINERATEARROWOFF\n// Special\nUnitOrderChannel=1,unitordernotarg,`channel`,WESTRING_UNITORDERNOTARG_CHANNEL\nUnitOrderMedivhRavenForm=0,unitordernotarg,`ravenform`,WESTRING_UNITORDERNOTARG_MEDIVHRAVENFORM\nUnitOrderMedivhUnRavenForm=0,unitordernotarg,`unravenform`,WESTRING_UNITORDERNOTARG_MEDIVHUNRAVENFORM\nUnitOrderRexxarBattleRoar=1,unitordernotarg,`battleroar`,WESTRING_UNITORDERNOTARG_REXXARBATTLEROAR\nUnitOrderColdArrows=0,unitordernotarg,`coldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWS\nUnitOrderUnColdArrows=0,unitordernotarg,`uncoldarrows`,WESTRING_UNITORDERNOTARG_UNCOLDARROWS\n\n// Hero Skills\n// Human Archmage\nHeroSkillBlizzard=0,heroskillcode,'AHbz',WESTRING_HEROSKILL_BLIZZARD\nHeroSkillWaterElemental=0,heroskillcode,'AHwe',WESTRING_HEROSKILL_WATERELEMENTAL\nHeroSkillBrillianceAura=0,heroskillcode,'AHab',WESTRING_HEROSKILL_BRILLIANCEAURA\nHeroSkillMassTeleport=0,heroskillcode,'AHmt',WESTRING_HEROSKILL_MASSTELEPORT\n// Human Blood Mage\nHeroSkillFlameStrike=1,heroskillcode,'AHfs',WESTRING_HEROSKILL_FLAMESTRIKE\nHeroSkillBanish=1,heroskillcode,'AHbn',WESTRING_HEROSKILL_BANISH\nHeroSkillSiphonMana=1,heroskillcode,'AHdr',WESTRING_HEROSKILL_SIPHONMANA\nHeroSkillPhoenix=1,heroskillcode,'AHpx',WESTRING_HEROSKILL_PHOENIX\n// Human Mountain King\nHeroSkillStormBolt=0,heroskillcode,'AHtb',WESTRING_HEROSKILL_STORMBOLT\nHeroSkillThunderClap=0,heroskillcode,'AHtc',WESTRING_HEROSKILL_THUNDERCLAP\nHeroSkillBash=0,heroskillcode,'AHbh',WESTRING_HEROSKILL_BASH\nHeroSkillAvatar=0,heroskillcode,'AHav',WESTRING_HEROSKILL_AVATAR\n// Human Paladin\nHeroSkillDivineShield=0,heroskillcode,'AHds',WESTRING_HEROSKILL_DIVINESHIELD\nHeroSkillHolyBolt=0,heroskillcode,'AHhb',WESTRING_HEROSKILL_HOLYBOLT\nHeroSkillDevotionAura=0,heroskillcode,'AHad',WESTRING_HEROSKILL_DEVOTIONAURA\nHeroSkillResurrection=0,heroskillcode,'AHre',WESTRING_HEROSKILL_RESURRECTION\n// Orc Blademaster\nHeroSkillWindWalk=0,heroskillcode,'AOwk',WESTRING_HEROSKILL_WINDWALK\nHeroSkillMirrorImage=0,heroskillcode,'AOmi',WESTRING_HEROSKILL_MIRRORIMAGE\nHeroSkillCriticalStrike=0,heroskillcode,'AOcr',WESTRING_HEROSKILL_CRITICALSTRIKE\nHeroSkillWhirlwind=0,heroskillcode,'AOww',WESTRING_HEROSKILL_WHIRLWIND\n// Orc Far Seer\nHeroSkillChainLightning=0,heroskillcode,'AOcl',WESTRING_HEROSKILL_CHAINLIGHTNING\nHeroSkillFarSight=0,heroskillcode,'AOfs',WESTRING_HEROSKILL_FARSIGHT\nHeroSkillSpiritWolf=0,heroskillcode,'AOsf',WESTRING_HEROSKILL_SPIRITWOLF\nHeroSkillEarthquake=0,heroskillcode,'AOeq',WESTRING_HEROSKILL_EARTHQUAKE\n// Orc Shadow Hunter\nHeroSkillHealingWave=1,heroskillcode,'AOhw',WESTRING_HEROSKILL_HEALINGWAVE\nHeroSkillHex=1,heroskillcode,'AOhx',WESTRING_HEROSKILL_HEX\nHeroSkillSerpentWard=1,heroskillcode,'AOsw',WESTRING_HEROSKILL_SERPENTWARD\nHeroSkillVoodoo=1,heroskillcode,'AOvd',WESTRING_HEROSKILL_VOODOO\n// Orc Tauren Chieftain\nHeroSkillShockwave=0,heroskillcode,'AOsh',WESTRING_HEROSKILL_SHOCKWAVE\nHeroSkillWarStomp=0,heroskillcode,'AOws',WESTRING_HEROSKILL_WARSTOMP\nHeroSkillEnduranceAura=0,heroskillcode,'AOae',WESTRING_HEROSKILL_ENDURANCEAURA\nHeroSkillReincarnation=0,heroskillcode,'AOre',WESTRING_HEROSKILL_REINCARNATION\n// Undead Crypt Lord\nHeroSkillImpale=1,heroskillcode,'AUim',WESTRING_HEROSKILL_IMPALE\nHeroSkillThornyShield=1,heroskillcode,'AUts',WESTRING_HEROSKILL_THORNYSHIELD\nHeroSkillCarrionScarabs=1,heroskillcode,'AUcb',WESTRING_HEROSKILL_CARRIONSCARABS\nHeroSkillLocustSwarm=1,heroskillcode,'AUls',WESTRING_HEROSKILL_LOCUSTSWARM\n// Undead Death Knight\nHeroSkillDeathCoil=0,heroskillcode,'AUdc',WESTRING_HEROSKILL_DEATHCOIL\nHeroSkillDeathPact=0,heroskillcode,'AUdp',WESTRING_HEROSKILL_DEATHPACT\nHeroSkillUnholyAura=0,heroskillcode,'AUau',WESTRING_HEROSKILL_UNHOLYAURA\nHeroSkillAnimateDead=0,heroskillcode,'AUan',WESTRING_HEROSKILL_ANIMATEDEAD\n// Undead Dread Lord\nHeroSkillCarrionSwarm=0,heroskillcode,'AUcs',WESTRING_HEROSKILL_CARRIONSWARM\nHeroSkillSleep=0,heroskillcode,'AUsl',WESTRING_HEROSKILL_SLEEP\nHeroSkillVampiricAura=0,heroskillcode,'AUav',WESTRING_HEROSKILL_VAMPIRICAURA\nHeroSkillDarkSummoning=0,heroskillcode,'AUin',WESTRING_HEROSKILL_DARKSUMMONING\n// Undead Lich\nHeroSkillFrostNova=0,heroskillcode,'AUfn',WESTRING_HEROSKILL_FROSTNOVA\nHeroSkillFrostArmor=0,heroskillcode,'AUfa',WESTRING_HEROSKILL_FROSTARMOR\nHeroSkillDarkRitual=0,heroskillcode,'AUdr',WESTRING_HEROSKILL_DARKRITUAL\nHeroSkillDeathAndDecay=0,heroskillcode,'AUdd',WESTRING_HEROSKILL_DEATHANDDECAY\n// Night Elf Demon Hunter\nHeroSkillManaBurn=0,heroskillcode,'AEmb',WESTRING_HEROSKILL_MANABURN\nHeroSkillImmolation=0,heroskillcode,'AEim',WESTRING_HEROSKILL_IMMOLATION\nHeroSkillEvasion=0,heroskillcode,'AEev',WESTRING_HEROSKILL_EVASION\nHeroSkillMetamorphosis=0,heroskillcode,'AEme',WESTRING_HEROSKILL_METAMORPHOSIS\n// Night Elf Keeper of the Grove\nHeroSkillEntanglingRoots=0,heroskillcode,'AEer',WESTRING_HEROSKILL_ENTANGLINGROOTS\nHeroSkillForceOfNature=0,heroskillcode,'AEfn',WESTRING_HEROSKILL_FORCEOFNATURE\nHeroSkillThornsAura=0,heroskillcode,'AEah',WESTRING_HEROSKILL_THORNSAURA\nHeroSkillTranquility=0,heroskillcode,'AEtq',WESTRING_HEROSKILL_TRANQUILITY\n// Night Elf Priestess of the Moon\nHeroSkillScout=0,heroskillcode,'AEst',WESTRING_HEROSKILL_SCOUT\nHeroSkillSearingArrows=0,heroskillcode,'AHfa',WESTRING_HEROSKILL_SEARINGARROWS\nHeroSkillTrueshotAura=0,heroskillcode,'AEar',WESTRING_HEROSKILL_TRUESHOTAURA\nHeroSkillStarfall=0,heroskillcode,'AEsf',WESTRING_HEROSKILL_STARFALL\n// Night Elf Warden\nHeroSkillFanOfKnives=1,heroskillcode,'AEfk',WESTRING_HEROSKILL_FANOFKNIVES\nHeroSkillBlink=1,heroskillcode,'AEbl',WESTRING_HEROSKILL_BLINK\nHeroSkillShadowTouch=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_SHADOWTOUCH\nHeroSkillSpiritOfVengeance=1,heroskillcode,'AEsv',WESTRING_HEROSKILL_SPIRITOFVENGEANCE\n// Neutral Beast Master\nHeroSkillGrizzly=1,heroskillcode,'ANsg',WESTRING_HEROSKILL_GRIZZLY\nHeroSkillQuillbeast=1,heroskillcode,'ANsq',WESTRING_HEROSKILL_QUILLBEAST\nHeroSkillWarEagle=1,heroskillcode,'ANsw',WESTRING_HEROSKILL_WAREAGLE\nHeroSkillStampede=1,heroskillcode,'ANst',WESTRING_HEROSKILL_STAMPEDE\n// Neutral Dark Ranger\nHeroSkillSilence=1,heroskillcode,'ANsi',WESTRING_HEROSKILL_SILENCE\nHeroSkillBlackArrow=1,heroskillcode,'ANba',WESTRING_HEROSKILL_BLACKARROW\nHeroSkillLifeDrain=1,heroskillcode,'ANdr',WESTRING_HEROSKILL_LIFEDRAIN\nHeroSkillCharm=1,heroskillcode,'ANch',WESTRING_HEROSKILL_CHARM\n// Neutral Naga Sea Witch\nHeroSkillForkedLightning=1,heroskillcode,'ANfl',WESTRING_HEROSKILL_FORKEDLIGHTNING\nHeroSkillColdArrow=1,heroskillcode,'ANfa',WESTRING_HEROSKILL_COLDARROW\nHeroSkillManaShield=1,heroskillcode,'ANms',WESTRING_HEROSKILL_MANASHIELD\nHeroSkillTornado=1,heroskillcode,'ANto',WESTRING_HEROSKILL_TORNADO\n// Neutral Pandaren Brewmaster\nHeroSkillBreathOfFire=1,heroskillcode,'ANbf',WESTRING_HEROSKILL_BREATHOFFIRE\nHeroSkillStrongDrink=1,heroskillcode,'ANdh',WESTRING_HEROSKILL_STRONGDRINK\nHeroSkillDrunkenBrawler=1,heroskillcode,'ANdb',WESTRING_HEROSKILL_DRUNKENBRAWLER\nHeroSkillElementalFury=1,heroskillcode,'ANef',WESTRING_HEROSKILL_ELEMENTALFURY\n// Neutral Pit Lord\nHeroSkillRainOfFire=1,heroskillcode,'ANrf',WESTRING_HEROSKILL_RAINOFFIRE\nHeroSkillHowlOfTerror=1,heroskillcode,'ANht',WESTRING_HEROSKILL_HOWLOFTERROR\nHeroSkillCleavingAttack=1,heroskillcode,'ANca',WESTRING_HEROSKILL_CLEAVINGATTACK\nHeroSkillDoom=1,heroskillcode,'ANdo',WESTRING_HEROSKILL_DOOM\n// Neutral Alchemist\nHeroSkillAcidBomb=1,heroskillcode,'ANab',WESTRING_HEROSKILL_ACIDBOMB\nHeroSkillChemicalRage=1,heroskillcode,'ANcr',WESTRING_HEROSKILL_CHEMICALRAGE\nHeroSkillHealingSpray=1,heroskillcode,'ANhs',WESTRING_HEROSKILL_HEALINGSPRAY\nHeroSkillTransmute=1,heroskillcode,'ANtm',WESTRING_HEROSKILL_TRANSMUTE\n// Neutral Tinker\nHeroSkillEngineeringUpgrade=1,heroskillcode,'ANeg',WESTRING_HEROSKILL_ENGINEERINGUPGRADE\nHeroSkillClusterRockets=1,heroskillcode,'ANcs',WESTRING_HEROSKILL_CLUSTERROCKETS\nHeroSkillSummonFactory=1,heroskillcode,'ANsy',WESTRING_HEROSKILL_SUMMONFACTORY\nHeroSkillRoboGoblin=1,heroskillcode,'ANrg',WESTRING_HEROSKILL_ROBOGOBLIN\n// Neutral Fire Lord\nHeroSkillIncinerate=1,heroskillcode,'ANic',WESTRING_HEROSKILL_INCINERATE\nHeroSkillIncinerateArrow=1,heroskillcode,'ANia',WESTRING_HEROSKILL_INCINERATEARROW\nHeroSkillSoulBurn=1,heroskillcode,'ANso',WESTRING_HEROSKILL_SOULBURN\nHeroSkillLavaMonster=1,heroskillcode,'ANlm',WESTRING_HEROSKILL_LAVAMONSTER\nHeroSkillVolcano=1,heroskillcode,'ANvc',WESTRING_HEROSKILL_VOLCANO\n// Special Akama\nHeroSkillChainLightning2=1,heroskillcode,'AOcl',WESTRING_HEROSKILL_AKAMA_CHAINLIGHTNING\nHeroSkillSpiritBeast=1,heroskillcode,'ACs7',WESTRING_HEROSKILL_AKAMA_FERALSPIRIT\nHeroSkillShadowTouch2=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_AKAMA_SHADOWTOUCH\nHeroSkillReincarnation2=1,heroskillcode,'ANr2',WESTRING_HEROSKILL_AKAMA_REINCARNATION\n// Special Archimonde\nHeroSkillDarkPortal=0,heroskillcode,'ANdp',WESTRING_HEROSKILL_DARKPORTAL\nHeroSkillRainOfChaos=0,heroskillcode,'ANrc',WESTRING_HEROSKILL_RAINOFCHAOS\nHeroSkillArchiBash=0,heroskillcode,'AHah',WESTRING_HEROSKILL_ARCHIBASH\nHeroSkillFingerOfDeath=0,heroskillcode,'ANfd',WESTRING_HEROSKILL_FINGEROFDEATH\n// Special Balnazar\nHeroSkillBalnaSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_BALNA_SLEEP\nHeroSkillBalnaVampiricAura=1,heroskillcode,'AUav',WESTRING_HEROSKILL_BALNA_VAMPIRICAURA\nHeroSkillBalnaRainOfChaos=1,heroskillcode,'ANr3',WESTRING_HEROSKILL_BALNA_RAINOFCHAOS\nHeroSkillBalnaFingerOfPain=1,heroskillcode,'ACf3',WESTRING_HEROSKILL_BALNA_FINGEROFPAIN\nHeroSkillBalnaEarthquake=1,heroskillcode,'AOeq',WESTRING_HEROSKILL_BALNA_EARTHQUAKE\n// Special Chen\nHeroSkillChenBreathOfFire=1,heroskillcode,'ANcf',WESTRING_HEROSKILL_CHEN_BREATHOFFIRE\nHeroSkillChenStrongDrink=1,heroskillcode,'Acdh',WESTRING_HEROSKILL_CHEN_STRONGDRINK\nHeroSkillChenDrunkenBrawler=1,heroskillcode,'Acdb',WESTRING_HEROSKILL_CHEN_DRUNKENBRAWLER\nHeroSkillChenElementalFury=1,heroskillcode,'Acef',WESTRING_HEROSKILL_CHEN_ELEMENTALFURY\nHeroSkillChenAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_CHEN_ATTRIBUTEBONUS\n// Special Detheroc\nHeroSkillDetheSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_DETHE_SLEEP\nHeroSkillDetheShadowTouch=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_DETHE_SHADOWTOUCH\nHeroSkillDetheCarrionSwarm=1,heroskillcode,'AUcs',WESTRING_HEROSKILL_DETHE_CARRIONSWARM\nHeroSkillDetheDeathAndDecay=1,heroskillcode,'AUdd',WESTRING_HEROSKILL_DETHE_DEATHANDDECAY\n// Special Garithos\nHeroSkillGaritShockwave=1,heroskillcode,'ANsh',WESTRING_HEROSKILL_GARIT_SHOCKWAVE\nHeroSkillGaritHolyLight=1,heroskillcode,'AHhb',WESTRING_HEROSKILL_GARIT_HOLYLIGHT\nHeroSkillGaritDevotionAura=1,heroskillcode,'AHad',WESTRING_HEROSKILL_GARIT_DEVOTIONAURA\nHeroSkillGaritAvatar=1,heroskillcode,'ANav',WESTRING_HEROSKILL_GARIT_AVATAR\n// Special Illidan\nHeroSkillIllimorphosis=0,heroskillcode,'AEIl',WESTRING_HEROSKILL_ILLIMORPHOSIS\nHeroSkillEvilIllimorphosis=0,heroskillcode,'AEvi',WESTRING_HEROSKILL_EVILILLIMORPHOSIS\n// Special Malganis\nHeroSkillMalganisSleep=0,heroskillcode,'ANdc',WESTRING_HEROSKILL_DARKCONVERSION\nHeroSkillSoulPreservation=0,heroskillcode,'ANsl',WESTRING_HEROSKILL_SOULPRESERVATION\n// Special Manaroth\nHeroSkillManarothReincarnation=0,heroskillcode,'ANrn',WESTRING_HEROSKILL_MANAROTHREINCARNATION\n// Special Rexxar\nHeroSkillRexxarGrizzly=1,heroskillcode,'Arsg',WESTRING_HEROSKILL_REXXAR_GRIZZLY\nHeroSkillRexxarQuillbeast=1,heroskillcode,'Arsq',WESTRING_HEROSKILL_REXXAR_QUILLBEAST\nHeroSkillRexxarStormBolt=1,heroskillcode,'ANsb',WESTRING_HEROSKILL_REXXAR_STORMBOLT\nHeroSkillRexxarStampede=1,heroskillcode,'Arsp',WESTRING_HEROSKILL_REXXAR_STAMPEDE\nHeroSkillRexxarAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_REXXAR_ATTRIBUTEBONUS\n// Special Rokhan\nHeroSkillRokhanHealingWave=1,heroskillcode,'ANhw',WESTRING_HEROSKILL_ROKHAN_HEALINGWAVE\nHeroSkillRokhanHex=1,heroskillcode,'ANhx',WESTRING_HEROSKILL_ROKHAN_HEX\nHeroSkillRokhanSerpentWard=1,heroskillcode,'Arsw',WESTRING_HEROSKILL_ROKHAN_SERPENTWARD\nHeroSkillRokhanVoodooSpirits=1,heroskillcode,'AOls',WESTRING_HEROSKILL_ROKHAN_VOODOOSPIRITS\nHeroSkillRokhanAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_ROKHAN_ATTRIBUTEBONUS\n// Special Sylvanas Windrunner\nHeroSkillColdArrows=0,heroskillcode,'AHca',WESTRING_HEROSKILL_COLDARROWS\n// Special Tichondrius\nHeroSkillTichondriusInferno=0,heroskillcode,'SNin',WESTRING_HEROSKILL_TICHONDRIUSINFERNO\n// Special Varimathras\nHeroSkillVarimSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_VARIM_SLEEP\nHeroSkillVarimVampiricAura=1,heroskillcode,'AUav',WESTRING_HEROSKILL_VARIM_VAMPIRICAURA\nHeroSkillVarimRainOfFire=1,heroskillcode,'ANrf',WESTRING_HEROSKILL_VARIM_RAINOFFIRE\nHeroSkillVarimDoom=1,heroskillcode,'ANdo',WESTRING_HEROSKILL_VARIM_DOOM\n// Special Warlock\nHeroSkillInfernal=0,heroskillcode,'ANin',WESTRING_HEROSKILL_INFERNAL\n// Special Miscellaneous\nHeroSkillMalganisSleepFast=0,heroskillcode,'SNdc',WESTRING_HEROSKILL_DARKCONVERSIONFAST\nHeroSkillDarkSummoningOld=0,heroskillcode,'AUds',WESTRING_HEROSKILL_DARKSUMMONINGOLD\n\n// Weather Effects\nWeatherAshenvaleHeavyRain=0,weathereffectcode,'RAhr',WESTRING_WEATHER_ASHENVALEHEAVYRAIN\nWeatherAshenvaleLightRain=0,weathereffectcode,'RAlr',WESTRING_WEATHER_ASHENVALELIGHTRAIN\nWeatherDalaranShield=0,weathereffectcode,'MEds',WESTRING_WEATHER_DALARANSHIELD\nWeatherDungeonHeavyBlueFog=0,weathereffectcode,'FDbh',WESTRING_WEATHER_DUNGEONHEAVYBLUEFOG\nWeatherDungeonLightBlueFog=0,weathereffectcode,'FDbl',WESTRING_WEATHER_DUNGEONBLUEFOG\nWeatherDungeonHeavyGreenFog=0,weathereffectcode,'FDgh',WESTRING_WEATHER_DUNGEONHEAVYGREENFOG\nWeatherDungeonLightGreenFog=0,weathereffectcode,'FDgl',WESTRING_WEATHER_DUNGEONGREENFOG\nWeatherDungeonHeavyRedFog=0,weathereffectcode,'FDrh',WESTRING_WEATHER_DUNGEONHEAVYREDFOG\nWeatherDungeonLightRedFog=0,weathereffectcode,'FDrl',WESTRING_WEATHER_DUNGEONREDFOG\nWeatherDungeonHeavyWhiteFog=0,weathereffectcode,'FDwh',WESTRING_WEATHER_DUNGEONHEAVYWHITEFOG\nWeatherDungeonLightWhiteFog=0,weathereffectcode,'FDwl',WESTRING_WEATHER_DUNGEONWHITEFOG\nWeatherLordaeronHeavyRain=0,weathereffectcode,'RLhr',WESTRING_WEATHER_LORDAERONHEAVYRAIN\nWeatherLordaeronLightRain=0,weathereffectcode,'RLlr',WESTRING_WEATHER_LORDAERONLIGHTRAIN\nWeatherNorthrendBlizzard=0,weathereffectcode,'SNbs',WESTRING_WEATHER_NORTHRENDBLIZZARD\nWeatherNorthrendHeavySnow=0,weathereffectcode,'SNhs',WESTRING_WEATHER_NORTHRENDHEAVYSNOW\nWeatherNorthrendLightSnow=0,weathereffectcode,'SNls',WESTRING_WEATHER_NORTHRENDLIGHTSNOW\nWeatherOutlandWind=1,weathereffectcode,'WOcw',WESTRING_WEATHER_OUTLANDWIND\nWeatherOutlandWindLight=1,weathereffectcode,'WOlw',WESTRING_WEATHER_OUTLANDWINDLIGHT\nWeatherRaysOfLight=0,weathereffectcode,'LRaa',WESTRING_WEATHER_RAYSOFLIGHT\nWeatherRaysOfMoonlight=0,weathereffectcode,'LRma',WESTRING_WEATHER_RAYSOFMOONLIGHT\nWeatherHeavyWind=0,weathereffectcode,'WNcw',WESTRING_WEATHER_WIND\n\n// Tile IDs\nTerrainTypeLdrt=1,terraintype,'Ldrt',WESTRING_TERRAINTYPE_Ldrt\nTerrainTypeLdro=1,terraintype,'Ldro',WESTRING_TERRAINTYPE_Ldro\nTerrainTypeLdrg=1,terraintype,'Ldrg',WESTRING_TERRAINTYPE_Ldrg\nTerrainTypeLrok=1,terraintype,'Lrok',WESTRING_TERRAINTYPE_Lrok\nTerrainTypeLgrs=1,terraintype,'Lgrs',WESTRING_TERRAINTYPE_Lgrs\nTerrainTypeLgrd=1,terraintype,'Lgrd',WESTRING_TERRAINTYPE_Lgrd\nTerrainTypeFdrt=1,terraintype,'Fdrt',WESTRING_TERRAINTYPE_Fdrt\nTerrainTypeFdro=1,terraintype,'Fdro',WESTRING_TERRAINTYPE_Fdro\nTerrainTypeFdrg=1,terraintype,'Fdrg',WESTRING_TERRAINTYPE_Fdrg\nTerrainTypeFrok=1,terraintype,'Frok',WESTRING_TERRAINTYPE_Frok\nTerrainTypeFgrs=1,terraintype,'Fgrs',WESTRING_TERRAINTYPE_Fgrs\nTerrainTypeFgrd=1,terraintype,'Fgrd',WESTRING_TERRAINTYPE_Fgrd\nTerrainTypeWdrt=1,terraintype,'Wdrt',WESTRING_TERRAINTYPE_Wdrt\nTerrainTypeWdro=1,terraintype,'Wdro',WESTRING_TERRAINTYPE_Wdro\nTerrainTypeWsng=1,terraintype,'Wsng',WESTRING_TERRAINTYPE_Wsng\nTerrainTypeWrok=1,terraintype,'Wrok',WESTRING_TERRAINTYPE_Wrok\nTerrainTypeWgrs=1,terraintype,'Wgrs',WESTRING_TERRAINTYPE_Wgrs\nTerrainTypeWsnw=1,terraintype,'Wsnw',WESTRING_TERRAINTYPE_Wsnw\nTerrainTypeBdrt=1,terraintype,'Bdrt',WESTRING_TERRAINTYPE_Bdrt\nTerrainTypeBdrh=1,terraintype,'Bdrh',WESTRING_TERRAINTYPE_Bdrh\nTerrainTypeBdrr=1,terraintype,'Bdrr',WESTRING_TERRAINTYPE_Bdrr\nTerrainTypeBdrg=1,terraintype,'Bdrg',WESTRING_TERRAINTYPE_Bdrg\nTerrainTypeBdsr=1,terraintype,'Bdsr',WESTRING_TERRAINTYPE_Bdsr\nTerrainTypeBdsd=1,terraintype,'Bdsd',WESTRING_TERRAINTYPE_Bdsd\nTerrainTypeBflr=1,terraintype,'Bflr',WESTRING_TERRAINTYPE_Bflr\nTerrainTypeBgrr=1,terraintype,'Bgrr',WESTRING_TERRAINTYPE_Bgrr\nTerrainTypeAdrt=1,terraintype,'Adrt',WESTRING_TERRAINTYPE_Adrt\nTerrainTypeAdrd=1,terraintype,'Adrd',WESTRING_TERRAINTYPE_Adrd\nTerrainTypeAgrs=1,terraintype,'Agrs',WESTRING_TERRAINTYPE_Agrs\nTerrainTypeArck=1,terraintype,'Arck',WESTRING_TERRAINTYPE_Arck\nTerrainTypeAgrd=1,terraintype,'Agrd',WESTRING_TERRAINTYPE_Agrd\nTerrainTypeAvin=1,terraintype,'Avin',WESTRING_TERRAINTYPE_Avin\nTerrainTypeAdrg=1,terraintype,'Adrg',WESTRING_TERRAINTYPE_Adrg\nTerrainTypeAlvd=1,terraintype,'Alvd',WESTRING_TERRAINTYPE_Alvd\nTerrainTypeCdrt=1,terraintype,'Cdrt',WESTRING_TERRAINTYPE_Cdrt\nTerrainTypeCdrd=1,terraintype,'Cdrd',WESTRING_TERRAINTYPE_Cdrd\nTerrainTypeCpos=1,terraintype,'Cpos',WESTRING_TERRAINTYPE_Cpos\nTerrainTypeCrck=1,terraintype,'Crck',WESTRING_TERRAINTYPE_Crck\nTerrainTypeCvin=1,terraintype,'Cvin',WESTRING_TERRAINTYPE_Cvin\nTerrainTypeCgrs=1,terraintype,'Cgrs',WESTRING_TERRAINTYPE_Cgrs\nTerrainTypeClvg=1,terraintype,'Clvg',WESTRING_TERRAINTYPE_Clvg\nTerrainTypeNdrt=1,terraintype,'Ndrt',WESTRING_TERRAINTYPE_Ndrt\nTerrainTypeNdrd=1,terraintype,'Ndrd',WESTRING_TERRAINTYPE_Ndrd\nTerrainTypeNrck=1,terraintype,'Nrck',WESTRING_TERRAINTYPE_Nrck\nTerrainTypeNgrs=1,terraintype,'Ngrs',WESTRING_TERRAINTYPE_Ngrs\nTerrainTypeNice=1,terraintype,'Nice',WESTRING_TERRAINTYPE_Nice\nTerrainTypeNsnw=1,terraintype,'Nsnw',WESTRING_TERRAINTYPE_Nsnw\nTerrainTypeNsnr=1,terraintype,'Nsnr',WESTRING_TERRAINTYPE_Nsnr\nTerrainTypeYdrt=1,terraintype,'Ydrt',WESTRING_TERRAINTYPE_Ydrt\nTerrainTypeYdtr=1,terraintype,'Ydtr',WESTRING_TERRAINTYPE_Ydtr\nTerrainTypeYblm=1,terraintype,'Yblm',WESTRING_TERRAINTYPE_Yblm\nTerrainTypeYbtl=1,terraintype,'Ybtl',WESTRING_TERRAINTYPE_Ybtl\nTerrainTypeYsqd=1,terraintype,'Ysqd',WESTRING_TERRAINTYPE_Ysqd\nTerrainTypeYrtl=1,terraintype,'Yrtl',WESTRING_TERRAINTYPE_Yrtl\nTerrainTypeYgsb=1,terraintype,'Ygsb',WESTRING_TERRAINTYPE_Ygsb\nTerrainTypeYhdg=1,terraintype,'Yhdg',WESTRING_TERRAINTYPE_Yhdg\nTerrainTypeYwmb=1,terraintype,'Ywmb',WESTRING_TERRAINTYPE_Ywmb\nTerrainTypeVdrt=1,terraintype,'Vdrt',WESTRING_TERRAINTYPE_Vdrt\nTerrainTypeVdrr=1,terraintype,'Vdrr',WESTRING_TERRAINTYPE_Vdrr\nTerrainTypeVcrp=1,terraintype,'Vcrp',WESTRING_TERRAINTYPE_Vcrp\nTerrainTypeVcbp=1,terraintype,'Vcbp',WESTRING_TERRAINTYPE_Vcbp\nTerrainTypeVstp=1,terraintype,'Vstp',WESTRING_TERRAINTYPE_Vstp\nTerrainTypeVgrs=1,terraintype,'Vgrs',WESTRING_TERRAINTYPE_Vgrs\nTerrainTypeVrck=1,terraintype,'Vrck',WESTRING_TERRAINTYPE_Vrck\nTerrainTypeVgrt=1,terraintype,'Vgrt',WESTRING_TERRAINTYPE_Vgrt\nTerrainTypeQdrt=1,terraintype,'Qdrt',WESTRING_TERRAINTYPE_Qdrt\nTerrainTypeQdrr=1,terraintype,'Qdrr',WESTRING_TERRAINTYPE_Qdrr\nTerrainTypeQcrp=1,terraintype,'Qcrp',WESTRING_TERRAINTYPE_Qcrp\nTerrainTypeQcbp=1,terraintype,'Qcbp',WESTRING_TERRAINTYPE_Qcbp\nTerrainTypeQstp=1,terraintype,'Qstp',WESTRING_TERRAINTYPE_Qstp\nTerrainTypeQgrs=1,terraintype,'Qgrs',WESTRING_TERRAINTYPE_Qgrs\nTerrainTypeQrck=1,terraintype,'Qrck',WESTRING_TERRAINTYPE_Qrck\nTerrainTypeQgrt=1,terraintype,'Qgrt',WESTRING_TERRAINTYPE_Qgrt\nTerrainTypeXdrt=1,terraintype,'Xdrt',WESTRING_TERRAINTYPE_Xdrt\nTerrainTypeXdtr=1,terraintype,'Xdtr',WESTRING_TERRAINTYPE_Xdtr\nTerrainTypeXblm=1,terraintype,'Xblm',WESTRING_TERRAINTYPE_Xblm\nTerrainTypeXbtl=1,terraintype,'Xbtl',WESTRING_TERRAINTYPE_Xbtl\nTerrainTypeXsqd=1,terraintype,'Xsqd',WESTRING_TERRAINTYPE_Xsqd\nTerrainTypeXrtl=1,terraintype,'Xrtl',WESTRING_TERRAINTYPE_Xrtl\nTerrainTypeXgsb=1,terraintype,'Xgsb',WESTRING_TERRAINTYPE_Xgsb\nTerrainTypeXhdg=1,terraintype,'Xhdg',WESTRING_TERRAINTYPE_Xhdg\nTerrainTypeXwmb=1,terraintype,'Xwmb',WESTRING_TERRAINTYPE_Xwmb\nTerrainTypeDdrt=1,terraintype,'Ddrt',WESTRING_TERRAINTYPE_Ddrt\nTerrainTypeDbrk=1,terraintype,'Dbrk',WESTRING_TERRAINTYPE_Dbrk\nTerrainTypeDrds=1,terraintype,'Drds',WESTRING_TERRAINTYPE_Drds\nTerrainTypeDlvc=1,terraintype,'Dlvc',WESTRING_TERRAINTYPE_Dlvc\nTerrainTypeDlav=1,terraintype,'Dlav',WESTRING_TERRAINTYPE_Dlav\nTerrainTypeDdkr=1,terraintype,'Ddkr',WESTRING_TERRAINTYPE_Ddkr\nTerrainTypeDgrs=1,terraintype,'Dgrs',WESTRING_TERRAINTYPE_Dgrs\nTerrainTypeDsqd=1,terraintype,'Dsqd',WESTRING_TERRAINTYPE_Dsqd\nTerrainTypeGdrt=1,terraintype,'Gdrt',WESTRING_TERRAINTYPE_Gdrt\nTerrainTypeGbrk=1,terraintype,'Gbrk',WESTRING_TERRAINTYPE_Gbrk\nTerrainTypeGrds=1,terraintype,'Grds',WESTRING_TERRAINTYPE_Grds\nTerrainTypeGlvc=1,terraintype,'Glvc',WESTRING_TERRAINTYPE_Glvc\nTerrainTypeGlav=1,terraintype,'Glav',WESTRING_TERRAINTYPE_Glav\nTerrainTypeGdkr=1,terraintype,'Gdkr',WESTRING_TERRAINTYPE_Gdkr\nTerrainTypeGgrs=1,terraintype,'Ggrs',WESTRING_TERRAINTYPE_Ggrs\nTerrainTypeGsqd=1,terraintype,'Gsqd',WESTRING_TERRAINTYPE_Gsqd\nTerrainTypeZdrt=1,terraintype,'Zdrt',WESTRING_TERRAINTYPE_Zdrt\nTerrainTypeZdtr=1,terraintype,'Zdtr',WESTRING_TERRAINTYPE_Zdtr\nTerrainTypeZdrg=1,terraintype,'Zdrg',WESTRING_TERRAINTYPE_Zdrg\nTerrainTypeZbks=1,terraintype,'Zbks',WESTRING_TERRAINTYPE_Zbks\nTerrainTypeZsan=1,terraintype,'Zsan',WESTRING_TERRAINTYPE_Zsan\nTerrainTypeZbkl=1,terraintype,'Zbkl',WESTRING_TERRAINTYPE_Zbkl\nTerrainTypeZtil=1,terraintype,'Ztil',WESTRING_TERRAINTYPE_Ztil\nTerrainTypeZgrs=1,terraintype,'Zgrs',WESTRING_TERRAINTYPE_Zgrs\nTerrainTypeZvin=1,terraintype,'Zvin',WESTRING_TERRAINTYPE_Zvin\nTerrainTypeIdrt=1,terraintype,'Idrt',WESTRING_TERRAINTYPE_Idrt\nTerrainTypeIdtr=1,terraintype,'Idtr',WESTRING_TERRAINTYPE_Idtr\nTerrainTypeIdki=1,terraintype,'Idki',WESTRING_TERRAINTYPE_Idki\nTerrainTypeIbkb=1,terraintype,'Ibkb',WESTRING_TERRAINTYPE_Ibkb\nTerrainTypeIrbk=1,terraintype,'Irbk',WESTRING_TERRAINTYPE_Irbk\nTerrainTypeItbk=1,terraintype,'Itbk',WESTRING_TERRAINTYPE_Itbk\nTerrainTypeIice=1,terraintype,'Iice',WESTRING_TERRAINTYPE_Iice\nTerrainTypeIbsq=1,terraintype,'Ibsq',WESTRING_TERRAINTYPE_Ibsq\nTerrainTypeIsnw=1,terraintype,'Isnw',WESTRING_TERRAINTYPE_Isnw\nTerrainTypeOdrt=1,terraintype,'Odrt',WESTRING_TERRAINTYPE_Odrt\nTerrainTypeOdtr=1,terraintype,'Odtr',WESTRING_TERRAINTYPE_Odtr\nTerrainTypeOsmb=1,terraintype,'Osmb',WESTRING_TERRAINTYPE_Osmb\nTerrainTypeOfst=1,terraintype,'Ofst',WESTRING_TERRAINTYPE_Ofst\nTerrainTypeOlgb=1,terraintype,'Olgb',WESTRING_TERRAINTYPE_Olgb\nTerrainTypeOrok=1,terraintype,'Orok',WESTRING_TERRAINTYPE_Orok\nTerrainTypeOfsl=1,terraintype,'Ofsl',WESTRING_TERRAINTYPE_Ofsl\nTerrainTypeOaby=1,terraintype,'Oaby',WESTRING_TERRAINTYPE_Oaby\nTerrainTypeKdrt=1,terraintype,'Kdrt',WESTRING_TERRAINTYPE_Kdrt\nTerrainTypeKfsl=1,terraintype,'Kfsl',WESTRING_TERRAINTYPE_Kfsl\nTerrainTypeKdtr=1,terraintype,'Kdtr',WESTRING_TERRAINTYPE_Kdtr\nTerrainTypeKfst=1,terraintype,'Kfst',WESTRING_TERRAINTYPE_Kfst\nTerrainTypeKsmb=1,terraintype,'Ksmb',WESTRING_TERRAINTYPE_Ksmb\nTerrainTypeKlgb=1,terraintype,'Klgb',WESTRING_TERRAINTYPE_Klgb\nTerrainTypeKsqt=1,terraintype,'Ksqt',WESTRING_TERRAINTYPE_Ksqt\nTerrainTypeKdkt=1,terraintype,'Kdkt',WESTRING_TERRAINTYPE_Kdkt\nTerrainTypeJdrt=1,terraintype,'Jdrt',WESTRING_TERRAINTYPE_Jdrt\nTerrainTypeJdtr=1,terraintype,'Jdtr',WESTRING_TERRAINTYPE_Jdtr\nTerrainTypeJblm=1,terraintype,'Jblm',WESTRING_TERRAINTYPE_Jblm\nTerrainTypeJbtl=1,terraintype,'Jbtl',WESTRING_TERRAINTYPE_Jbtl\nTerrainTypeJsqd=1,terraintype,'Jsqd',WESTRING_TERRAINTYPE_Jsqd\nTerrainTypeJrtl=1,terraintype,'Jrtl',WESTRING_TERRAINTYPE_Jrtl\nTerrainTypeJgsb=1,terraintype,'Jgsb',WESTRING_TERRAINTYPE_Jgsb\nTerrainTypeJhdg=1,terraintype,'Jhdg',WESTRING_TERRAINTYPE_Jhdg\nTerrainTypeJwmb=1,terraintype,'Jwmb',WESTRING_TERRAINTYPE_Jwmb\nTerrainTypecAc2=1,terraintype,'cAc2',WESTRING_TERRAINTYPE_cAc2\nTerrainTypecAc1=1,terraintype,'cAc1',WESTRING_TERRAINTYPE_cAc1\nTerrainTypecBc2=1,terraintype,'cBc2',WESTRING_TERRAINTYPE_cBc2\nTerrainTypecBc1=1,terraintype,'cBc1',WESTRING_TERRAINTYPE_cBc1\nTerrainTypecKc1=1,terraintype,'cKc1',WESTRING_TERRAINTYPE_cKc1\nTerrainTypecKc2=1,terraintype,'cKc2',WESTRING_TERRAINTYPE_cKc2\nTerrainTypecYc2=1,terraintype,'cYc2',WESTRING_TERRAINTYPE_cYc2\nTerrainTypecYc1=1,terraintype,'cYc1',WESTRING_TERRAINTYPE_cYc1\nTerrainTypecXc2=1,terraintype,'cXc2',WESTRING_TERRAINTYPE_cXc2\nTerrainTypecXc1=1,terraintype,'cXc1',WESTRING_TERRAINTYPE_cXc1\nTerrainTypecJc2=1,terraintype,'cJc2',WESTRING_TERRAINTYPE_cJc2\nTerrainTypecJc1=1,terraintype,'cJc1',WESTRING_TERRAINTYPE_cJc1\nTerrainTypecDc2=1,terraintype,'cDc2',WESTRING_TERRAINTYPE_cDc2\nTerrainTypecDc1=1,terraintype,'cDc1',WESTRING_TERRAINTYPE_cDc1\nTerrainTypecCc2=1,terraintype,'cCc2',WESTRING_TERRAINTYPE_cCc2\nTerrainTypecCc1=1,terraintype,'cCc1',WESTRING_TERRAINTYPE_cCc1\nTerrainTypecIc2=1,terraintype,'cIc2',WESTRING_TERRAINTYPE_cIc2\nTerrainTypecIc1=1,terraintype,'cIc1',WESTRING_TERRAINTYPE_cIc1\nTerrainTypecFc2=1,terraintype,'cFc2',WESTRING_TERRAINTYPE_cFc2\nTerrainTypecFc1=1,terraintype,'cFc1',WESTRING_TERRAINTYPE_cFc1\nTerrainTypecLc2=1,terraintype,'cLc2',WESTRING_TERRAINTYPE_cLc2\nTerrainTypecLc1=1,terraintype,'cLc1',WESTRING_TERRAINTYPE_cLc1\nTerrainTypecWc2=1,terraintype,'cWc2',WESTRING_TERRAINTYPE_cWc2\nTerrainTypecWc1=1,terraintype,'cWc1',WESTRING_TERRAINTYPE_cWc1\nTerrainTypecNc2=1,terraintype,'cNc2',WESTRING_TERRAINTYPE_cNc2\nTerrainTypecNc1=1,terraintype,'cNc1',WESTRING_TERRAINTYPE_cNc1\nTerrainTypecOc1=1,terraintype,'cOc1',WESTRING_TERRAINTYPE_cOc1\nTerrainTypecOc2=1,terraintype,'cOc2',WESTRING_TERRAINTYPE_cOc2\nTerrainTypecZc2=1,terraintype,'cZc2',WESTRING_TERRAINTYPE_cZc2\nTerrainTypecZc1=1,terraintype,'cZc1',WESTRING_TERRAINTYPE_cZc1\nTerrainTypecGc2=1,terraintype,'cGc2',WESTRING_TERRAINTYPE_cGc2\nTerrainTypecGc1=1,terraintype,'cGc1',WESTRING_TERRAINTYPE_cGc1\nTerrainTypecVc2=1,terraintype,'cVc2',WESTRING_TERRAINTYPE_cVc2\nTerrainTypecVc1=1,terraintype,'cVc1',WESTRING_TERRAINTYPE_cVc1\nTerrainTypecQc2=1,terraintype,'cQc2',WESTRING_TERRAINTYPE_cQc2\nTerrainTypecQc1=1,terraintype,'cQc1',WESTRING_TERRAINTYPE_cQc1\n\n//  Terrain Shapes\nTerrainShapeCircle=1,terrainshape,0,WESTRING_TERRAINSHAPE_CIRCLE\nTerrainShapeSquare=1,terrainshape,1,WESTRING_TERRAINSHAPE_SQUARE\n\n//  Lightning Types\nLightningTypeCLPB=1,lightningtype,`CLPB`,WESTRING_LIGHTNINGTYPE_CLPB\nLightningTypeCLSB=1,lightningtype,`CLSB`,WESTRING_LIGHTNINGTYPE_CLSB\nLightningTypeDRAB=1,lightningtype,`DRAB`,WESTRING_LIGHTNINGTYPE_DRAB\nLightningTypeDRAL=1,lightningtype,`DRAL`,WESTRING_LIGHTNINGTYPE_DRAL\nLightningTypeDRAM=1,lightningtype,`DRAM`,WESTRING_LIGHTNINGTYPE_DRAM\nLightningTypeAFOD=1,lightningtype,`AFOD`,WESTRING_LIGHTNINGTYPE_AFOD\nLightningTypeFORK=1,lightningtype,`FORK`,WESTRING_LIGHTNINGTYPE_FORK\nLightningTypeHWPB=1,lightningtype,`HWPB`,WESTRING_LIGHTNINGTYPE_HWPB\nLightningTypeHWSB=1,lightningtype,`HWSB`,WESTRING_LIGHTNINGTYPE_HWSB\nLightningTypeCHIM=1,lightningtype,`CHIM`,WESTRING_LIGHTNINGTYPE_CHIM\nLightningTypeLEAS=1,lightningtype,`LEAS`,WESTRING_LIGHTNINGTYPE_LEAS\nLightningTypeMBUR=1,lightningtype,`MBUR`,WESTRING_LIGHTNINGTYPE_MBUR\nLightningTypeMFPB=1,lightningtype,`MFPB`,WESTRING_LIGHTNINGTYPE_MFPB\nLightningTypeSPLK=1,lightningtype,`SPLK`,WESTRING_LIGHTNINGTYPE_SPLK\n\n//  Image types\nImageTypeShadow=1,imagetype,0,WESTRING_IMAGETYPE_SHADOW\nImageTypeSelection=1,imagetype,1,WESTRING_IMAGETYPE_SELECTION\nImageTypeIndicator=1,imagetype,2,WESTRING_IMAGETYPE_INDICATOR\nImageTypeOcclusionMark=1,imagetype,3,WESTRING_IMAGETYPE_OCCLUSIONMARK\nImageTypeUbersplat=1,imagetype,4,WESTRING_IMAGETYPE_UBERSPLAT\nImageTypeLast=1,imagetype,5,WESTRING_IMAGETYPE_LAST\n\n//  Ubersplat codes\nUbersplatTypeTEST=1,ubersplattype,`TEST`,WESTRING_UBERSPLAT_TEST\nUbersplatTypeLSDS=1,ubersplattype,`LSDS`,WESTRING_UBERSPLAT_LSDS\nUbersplatTypeLSDM=1,ubersplattype,`LSDM`,WESTRING_UBERSPLAT_LSDM\nUbersplatTypeLSDL=1,ubersplattype,`LSDL`,WESTRING_UBERSPLAT_LSDL\nUbersplatTypeHCRT=1,ubersplattype,`HCRT`,WESTRING_UBERSPLAT_HCRT\nUbersplatTypeUDSU=1,ubersplattype,`UDSU`,WESTRING_UBERSPLAT_UDSU\nUbersplatTypeDNCS=1,ubersplattype,`DNCS`,WESTRING_UBERSPLAT_DNCS\nUbersplatTypeHMTP=1,ubersplattype,`HMTP`,WESTRING_UBERSPLAT_HMTP\nUbersplatTypeSCTP=1,ubersplattype,`SCTP`,WESTRING_UBERSPLAT_SCTP\nUbersplatTypeAMRC=1,ubersplattype,`AMRC`,WESTRING_UBERSPLAT_AMRC\nUbersplatTypeDRKC=1,ubersplattype,`DRKC`,WESTRING_UBERSPLAT_DRKC\nUbersplatTypeDOSB=1,ubersplattype,`DOSB`,WESTRING_UBERSPLAT_DOSB\nUbersplatTypeDOMB=1,ubersplattype,`DOMB`,WESTRING_UBERSPLAT_DOMB\nUbersplatTypeDOLB=1,ubersplattype,`DOLB`,WESTRING_UBERSPLAT_DOLB\nUbersplatTypeDHSB=1,ubersplattype,`DHSB`,WESTRING_UBERSPLAT_DHSB\nUbersplatTypeDHMB=1,ubersplattype,`DHMB`,WESTRING_UBERSPLAT_DHMB\nUbersplatTypeDHLB=1,ubersplattype,`DHLB`,WESTRING_UBERSPLAT_DHLB\nUbersplatTypeDUSB=1,ubersplattype,`DUSB`,WESTRING_UBERSPLAT_DUSB\nUbersplatTypeDUMB=1,ubersplattype,`DUMB`,WESTRING_UBERSPLAT_DUMB\nUbersplatTypeDULB=1,ubersplattype,`DULB`,WESTRING_UBERSPLAT_DULB\nUbersplatTypeDNSB=1,ubersplattype,`DNSB`,WESTRING_UBERSPLAT_DNSB\nUbersplatTypeDNMB=1,ubersplattype,`DNMB`,WESTRING_UBERSPLAT_DNMB\nUbersplatTypeDNSA=1,ubersplattype,`DNSA`,WESTRING_UBERSPLAT_DNSA\nUbersplatTypeDNMA=1,ubersplattype,`DNMA`,WESTRING_UBERSPLAT_DNMA\nUbersplatTypeHSMA=1,ubersplattype,`HSMA`,WESTRING_UBERSPLAT_HSMA\nUbersplatTypeHMED=1,ubersplattype,`HMED`,WESTRING_UBERSPLAT_HMED\nUbersplatTypeHLAR=1,ubersplattype,`HLAR`,WESTRING_UBERSPLAT_HLAR\nUbersplatTypeOSMA=1,ubersplattype,`OSMA`,WESTRING_UBERSPLAT_OSMA\nUbersplatTypeOMED=1,ubersplattype,`OMED`,WESTRING_UBERSPLAT_OMED\nUbersplatTypeOLAR=1,ubersplattype,`OLAR`,WESTRING_UBERSPLAT_OLAR\nUbersplatTypeUSMA=1,ubersplattype,`USMA`,WESTRING_UBERSPLAT_USMA\nUbersplatTypeUMED=1,ubersplattype,`UMED`,WESTRING_UBERSPLAT_UMED\nUbersplatTypeULAR=1,ubersplattype,`ULAR`,WESTRING_UBERSPLAT_ULAR\nUbersplatTypeESMA=1,ubersplattype,`ESMA`,WESTRING_UBERSPLAT_ESMA\nUbersplatTypeEMDA=1,ubersplattype,`EMDA`,WESTRING_UBERSPLAT_EMDA\nUbersplatTypeESMB=1,ubersplattype,`ESMB`,WESTRING_UBERSPLAT_ESMB\nUbersplatTypeEMDB=1,ubersplattype,`EMDB`,WESTRING_UBERSPLAT_EMDB\nUbersplatTypeHTOW=1,ubersplattype,`HTOW`,WESTRING_UBERSPLAT_HTOW\nUbersplatTypeHCAS=1,ubersplattype,`HCAS`,WESTRING_UBERSPLAT_HCAS\nUbersplatTypeNGOL=1,ubersplattype,`NGOL`,WESTRING_UBERSPLAT_NGOL\nUbersplatTypeTHND=1,ubersplattype,`THND`,WESTRING_UBERSPLAT_THND\nUbersplatTypeNDGS=1,ubersplattype,`NDGS`,WESTRING_UBERSPLAT_NDGS\nUbersplatTypeCLTS=1,ubersplattype,`CLTS`,WESTRING_UBERSPLAT_CLTS\nUbersplatTypeHFS1=1,ubersplattype,`HFS1`,WESTRING_UBERSPLAT_HFS1\nUbersplatTypeHFS2=1,ubersplattype,`HFS2`,WESTRING_UBERSPLAT_HFS2\nUbersplatTypeUSBR=1,ubersplattype,`USBR`,WESTRING_UBERSPLAT_USBR\nUbersplatTypeNLAR=1,ubersplattype,`NLAR`,WESTRING_UBERSPLAT_NLAR\nUbersplatTypeNMED=1,ubersplattype,`NMED`,WESTRING_UBERSPLAT_NMED\nUbersplatTypeDPSW=1,ubersplattype,`DPSW`,WESTRING_UBERSPLAT_DPSW\nUbersplatTypeDPSE=1,ubersplattype,`DPSE`,WESTRING_UBERSPLAT_DPSE\nUbersplatTypeNVOL=1,ubersplattype,`NVOL`,WESTRING_UBERSPLAT_NVOL\nUbersplatTypeNVCR=1,ubersplattype,`NVCR`,WESTRING_UBERSPLAT_NVCR\n\n\n//***************************************************************************\n[TriggerEvents]\n// Defines events available in the editor\n// Key: script event function\n// Value 0: first game version in which this function is valid\n// Value 1+: argument types\n// Note that the first argument is always a `trigger`, and is excluded here\n\n// Special events not defined in scripts, handled internally by the editor\nMapInitializationEvent=0,nothing\n_MapInitializationEvent_Defaults=\n_MapInitializationEvent_Category=TC_NOTHING\n\n\n// Destructible events\nTriggerRegisterDeathEvent=0,destructable\n_TriggerRegisterDeathEvent_Defaults=_\n_TriggerRegisterDeathEvent_Category=TC_DESTRUCT\n\nTriggerRegisterDestDeathInRegionEvent=1,rect\n_TriggerRegisterDestDeathInRegionEvent_Defaults=_\n_TriggerRegisterDestDeathInRegionEvent_Category=TC_DESTRUCT\n\n\n// Dialog events\nTriggerRegisterDialogEventBJ=0,dialog\n_TriggerRegisterDialogEventBJ_Defaults=_\n_TriggerRegisterDialogEventBJ_Category=TC_DIALOG\n\n\n// Game events\nTriggerRegisterGameStateEventTimeOfDay=0,limitop,real\n_TriggerRegisterGameStateEventTimeOfDay_Defaults=LimitOpEqual,12\n_TriggerRegisterGameStateEventTimeOfDay_Limits=_,_,0,24\n_TriggerRegisterGameStateEventTimeOfDay_Category=TC_GAME\n\nTriggerRegisterVariableEvent=0,VarAsString_Real,limitop,real\n_TriggerRegisterVariableEvent_Defaults=_,LimitOpEqual,0\n_TriggerRegisterVariableEvent_Category=TC_GAME\n\nTriggerRegisterGameLoadedEventBJ=1,nothing\n_TriggerRegisterGameLoadedEventBJ_Defaults=\n_TriggerRegisterGameLoadedEventBJ_Category=TC_GAME\n\nTriggerRegisterGameSavedEventBJ=1,nothing\n_TriggerRegisterGameSavedEventBJ_Defaults=\n_TriggerRegisterGameSavedEventBJ_Category=TC_GAME\n\nTriggerRegisterShowSkillEventBJ=0,nothing\n_TriggerRegisterShowSkillEventBJ_Defaults=\n_TriggerRegisterShowSkillEventBJ_Category=TC_GAME\n\nTriggerRegisterBuildSubmenuEventBJ=0,nothing\n_TriggerRegisterBuildSubmenuEventBJ_Defaults=\n_TriggerRegisterBuildSubmenuEventBJ_Category=TC_GAME\n\nTriggerRegisterGameEvent=1,gameevent\n_TriggerRegisterGameEvent_Defaults=GameEventTourneyNow\n_TriggerRegisterGameEvent_Category=TC_GAME\n\n\n// Player events\nTriggerRegisterPlayerChatEvent=0,player,string,chatmatchtype\n_TriggerRegisterPlayerChatEvent_Defaults=Player00,_,ChatMatchTypeExact\n_TriggerRegisterPlayerChatEvent_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventEndCinematic=0,player\n_TriggerRegisterPlayerEventEndCinematic_Defaults=Player00\n_TriggerRegisterPlayerEventEndCinematic_Category=TC_PLAYER\n\nTriggerRegisterPlayerSelectionEventBJ=0,player,seldeseloption\n_TriggerRegisterPlayerSelectionEventBJ_Defaults=Player00,SelDeselOptionSel\n_TriggerRegisterPlayerSelectionEventBJ_Category=TC_PLAYER\n\nTriggerRegisterPlayerKeyEventBJ=1,player,keyeventtype,keyeventkey\n_TriggerRegisterPlayerKeyEventBJ_Defaults=Player00,KeyEventTypeDepress,KeyEventKeyLeft\n_TriggerRegisterPlayerKeyEventBJ_Category=TC_PLAYER\n\nTriggerRegisterPlayerMouseEventBJ=1,player,mouseeventtype\n_TriggerRegisterPlayerMouseEventBJ_Defaults=Player00,MouseEventTypeDown\n_TriggerRegisterPlayerMouseEventBJ_Category=TC_PLAYER\n\nTriggerRegisterPlayerStateEvent=0,player,playerstate,limitop,real\n_TriggerRegisterPlayerStateEvent_Defaults=Player00,PlayerStateGold,LimitOpGreaterThanOrEqual,1000\n_TriggerRegisterPlayerStateEvent_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventAllianceChanged=0,player\n_TriggerRegisterPlayerEventAllianceChanged_Defaults=Player00\n_TriggerRegisterPlayerEventAllianceChanged_Category=TC_PLAYER\n\nTriggerRegisterPlayerAllianceChange=0,player,alliancetype\n_TriggerRegisterPlayerAllianceChange_Defaults=Player00,AllianceTypePassive\n_TriggerRegisterPlayerAllianceChange_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventVictory=0,player\n_TriggerRegisterPlayerEventVictory_Defaults=Player00\n_TriggerRegisterPlayerEventVictory_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventDefeat=0,player\n_TriggerRegisterPlayerEventDefeat_Defaults=Player00\n_TriggerRegisterPlayerEventDefeat_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventLeave=1,player\n_TriggerRegisterPlayerEventLeave_Defaults=Player00\n_TriggerRegisterPlayerEventLeave_Category=TC_PLAYER\n\n\n// Timer events\nTriggerRegisterTimerEventSingle=0,real\n_TriggerRegisterTimerEventSingle_Defaults=5\n_TriggerRegisterTimerEventSingle_Limits=0,_\n_TriggerRegisterTimerEventSingle_Category=TC_TIME\n\nTriggerRegisterTimerEventPeriodic=0,real\n_TriggerRegisterTimerEventPeriodic_Defaults=2\n_TriggerRegisterTimerEventPeriodic_Limits=0,_\n_TriggerRegisterTimerEventPeriodic_Category=TC_TIME\n\nTriggerRegisterTimerExpireEventBJ=0,timer\n_TriggerRegisterTimerExpireEventBJ_Defaults=_\n_TriggerRegisterTimerExpireEventBJ_Category=TC_TIME\n\n\n// Unit events\nTriggerRegisterUnitEvent=0,unit,unitevent\n_TriggerRegisterUnitEvent_Defaults=_,UnitEventDeath\n_TriggerRegisterUnitEvent_Category=TC_UNIT\n\nTriggerRegisterPlayerUnitEventSimple=0,player,playerunitevent\n_TriggerRegisterPlayerUnitEventSimple_Defaults=Player00,PlayerUnitEventDeath\n_TriggerRegisterPlayerUnitEventSimple_Category=TC_UNIT\n\nTriggerRegisterAnyUnitEventBJ=1,playerunitevent\n_TriggerRegisterAnyUnitEventBJ_Defaults=PlayerUnitEventDeath\n_TriggerRegisterAnyUnitEventBJ_Category=TC_UNIT\n\nTriggerRegisterEnterRectSimple=0,rect\n_TriggerRegisterEnterRectSimple_Defaults=_\n_TriggerRegisterEnterRectSimple_Category=TC_UNIT\n\nTriggerRegisterLeaveRectSimple=0,rect\n_TriggerRegisterLeaveRectSimple_Defaults=_\n_TriggerRegisterLeaveRectSimple_Category=TC_UNIT\n\nTriggerRegisterUnitInRangeSimple=0,real,unit\n_TriggerRegisterUnitInRangeSimple_Defaults=256,_\n_TriggerRegisterUnitInRangeSimple_Defaults=0,_,_,_\n_TriggerRegisterUnitInRangeSimple_Category=TC_UNIT\n\nTriggerRegisterUnitLifeEvent=0,unit,limitop,real\n_TriggerRegisterUnitLifeEvent_Defaults=_,LimitOpLessThan,50\n_TriggerRegisterUnitLifeEvent_Category=TC_UNIT\n\nTriggerRegisterUnitManaEvent=0,unit,limitop,real\n_TriggerRegisterUnitManaEvent_Defaults=_,LimitOpLessThan,50\n_TriggerRegisterUnitManaEvent_Category=TC_UNIT\n\n\n\n//***************************************************************************\n[TriggerConditions]\n// Defines boolean condition functions\n// Key: condition function name\n// Value 0: first game version in which this function is valid\n// Value 1+: argument types\n\nOperatorCompareBoolean=0,boolean,EqualNotEqualOperator,boolean\n_OperatorCompareBoolean_Defaults=IsUnitType,OperatorEqualENE,true\n_OperatorCompareBoolean_Category=TC_CONDITION\n_OperatorCompareBoolean_UseWithAI=1\n_OperatorCompareBoolean_AIDefaults=true,OperatorEqualENE,true\n\nOperatorCompareAbilityId=1,abilcode,EqualNotEqualOperator,abilcode\n_OperatorCompareAbilityId_Defaults=GetSpellAbilityId,OperatorEqualENE,AUan\n_OperatorCompareAbilityId_Category=TC_CONDITION\n\nOperatorCompareBuffId=1,buffcode,EqualNotEqualOperator,buffcode\n_OperatorCompareBuffId_Defaults=_,OperatorEqualENE,_\n_OperatorCompareBuffId_Category=TC_CONDITION\n\nOperatorCompareDestructible=0,destructable,EqualNotEqualOperator,destructable\n_OperatorCompareDestructible_Defaults=_,OperatorEqualENE,_\n_OperatorCompareDestructible_Category=TC_CONDITION\n\nOperatorCompareDestructableCode=0,destructablecode,EqualNotEqualOperator,destructablecode\n_OperatorCompareDestructableCode_Defaults=GetDestructableTypeId,OperatorEqualENE,LTlt\n_OperatorCompareDestructableCode_Category=TC_CONDITION\n\nOperatorCompareButton=0,button,EqualNotEqualOperator,button\n_OperatorCompareButton_Defaults=GetClickedButtonBJ,OperatorEqualENE,_\n_OperatorCompareButton_Category=TC_CONDITION\n\nOperatorCompareGameDifficulty=0,gamedifficulty,EqualNotEqualOperator,gamedifficulty\n_OperatorCompareGameDifficulty_Defaults=GetGameDifficulty,OperatorEqualENE,GameDifficultyNormal\n_OperatorCompareGameDifficulty_Category=TC_CONDITION\n\nOperatorCompareGameSpeed=0,gamespeed,EqualNotEqualOperator,gamespeed\n_OperatorCompareGameSpeed_Defaults=GetGameSpeed,OperatorEqualENE,GameSpeedNormal\n_OperatorCompareGameSpeed_Category=TC_CONDITION\n\nOperatorCompareHeroSkill=0,heroskillcode,EqualNotEqualOperator,heroskillcode\n_OperatorCompareHeroSkill_Defaults=GetLearnedSkillBJ,OperatorEqualENE,HeroSkillBlizzard\n_OperatorCompareHeroSkill_Category=TC_CONDITION\n\nOperatorCompareInteger=0,integer,ComparisonOperator,integer\n_OperatorCompareInteger_Defaults=CountUnitsInGroup,OperatorEqual,0\n_OperatorCompareInteger_Category=TC_CONDITION\n_OperatorCompareInteger_UseWithAI=1\n_OperatorCompareInteger_AIDefaults=0,OperatorEqual,0\n\nOperatorCompareItem=0,item,EqualNotEqualOperator,item\n_OperatorCompareItem_Defaults=_,OperatorEqualENE,_\n_OperatorCompareItem_Category=TC_CONDITION\n\nOperatorCompareItemType=1,itemtype,EqualNotEqualOperator,itemtype\n_OperatorCompareItemType_Defaults=GetItemType,OperatorEqualENE,ItemTypePowerup\n_OperatorCompareItemType_Category=TC_CONDITION\n\nOperatorCompareItemCode=0,itemcode,EqualNotEqualOperator,itemcode\n_OperatorCompareItemCode_Defaults=GetItemTypeId,OperatorEqualENE,texp\n_OperatorCompareItemCode_Category=TC_CONDITION\n\nOperatorCompareMouseButton=1,mousebuttontype,EqualNotEqualOperator,mousebuttontype\n_OperatorCompareMouseButton_Defaults=GetTriggerPlayerMouseButton,OperatorEqualENE,MouseButtonTypeLeft\n_OperatorCompareMouseButton_Categroy=TC_CONDITION\n\nOperatorCompareMeleeDifficulty=1,aidifficulty,EqualNotEqualOperator,aidifficulty\n_OperatorCompareMeleeDifficulty_Defaults=GetAIDifficulty,OperatorEqualENE,AIDifficultyNormal\n_OperatorCompareMeleeDifficulty_Category=TC_CONDITION\n\nOperatorCompareOrderCode=0,ordercode,EqualNotEqualOperator,ordercode\n_OperatorCompareOrderCode_Defaults=GetIssuedOrderIdBJ,OperatorEqualENE,String2OrderIdBJ\n_OperatorCompareOrderCode_Category=TC_CONDITION\n\nOperatorComparePlayer=0,player,EqualNotEqualOperator,player\n_OperatorComparePlayer_Defaults=GetOwningPlayer,OperatorEqualENE,Player00\n_OperatorComparePlayer_Category=TC_CONDITION\n\nOperatorComparePlayerColor=0,playercolor,EqualNotEqualOperator,playercolor\n_OperatorComparePlayerColor_Defaults=GetPlayerColor,OperatorEqualENE,Color00\n_OperatorComparePlayerColor_Category=TC_CONDITION\n\nOperatorComparePlayerControl=0,mapcontrol,EqualNotEqualOperator,mapcontrol\n_OperatorComparePlayerControl_Defaults=GetPlayerController,OperatorEqualENE,MapControlUser\n_OperatorComparePlayerControl_Category=TC_CONDITION\n\nOperatorComparePlayerSlotStatus=0,playerslotstate,EqualNotEqualOperator,playerslotstate\n_OperatorComparePlayerSlotStatus_Defaults=GetPlayerSlotState,OperatorEqualENE,PlayerSlotStatePlaying\n_OperatorComparePlayerSlotStatus_Category=TC_CONDITION\n\n//OperatorComparePoint=0,location,EqualNotEqualOperator,location\n//_OperatorComparePoint_Defaults=_,OperatorEqualENE,_\n//_OperatorComparePoint_Category=TC_CONDITION\n\nOperatorCompareRace=0,race,EqualNotEqualOperator,race\n_OperatorCompareRace_Defaults=GetPlayerRace,OperatorEqualENE,RaceHuman\n_OperatorCompareRace_Category=TC_CONDITION\n\nOperatorCompareReal=0,real,ComparisonOperator,real\n_OperatorCompareReal_Defaults=GetUnitStateSwap,OperatorGreaterEq,10\n_OperatorCompareReal_Category=TC_CONDITION\n\n//OperatorCompareRegion=0,rect,EqualNotEqualOperator,rect\n//_OperatorCompareRegion_Defaults=_,OperatorEqualENE,_\n//_OperatorCompareRegion_Category=TC_CONDITION\n\nOperatorCompareString=0,string,EqualNotEqualOperator,string\n_OperatorCompareString_Defaults=GetEventPlayerChatString,OperatorEqualENE,_\n_OperatorCompareString_Category=TC_CONDITION\n\nOperatorCompareTechCode=0,techcode,EqualNotEqualOperator,techcode\n_OperatorCompareTechCode_Defaults=GetResearched,OperatorEqualENE,_\n_OperatorCompareTechCode_Category=TC_CONDITION\n\nOperatorCompareTerrainType=1,terraintype,EqualNotEqualOperator,terraintype\n_OperatorCompareTerrainType_Defaults=GetTerrainTypeBJ,OperatorEqualENE,TerrainTypeLdrt\n_OperatorCompareTerrainType_Category=TC_CONDITION\n\nOperatorCompareTrigger=0,trigger,EqualNotEqualOperator,trigger\n_OperatorCompareTrigger_Defaults=_,OperatorEqualENE,_\n_OperatorCompareTrigger_Category=TC_CONDITION\n\nOperatorCompareUnit=0,unit,EqualNotEqualOperator,unit\n_OperatorCompareUnit_Defaults=GetTriggerUnit,OperatorEqualENE,_\n_OperatorCompareUnit_Category=TC_CONDITION\n\nOperatorCompareUnitCode=0,unitcode,EqualNotEqualOperator,unitcode\n_OperatorCompareUnitCode_Defaults=GetUnitTypeId,OperatorEqualENE,hfoo\n_OperatorCompareUnitCode_Category=TC_CONDITION\n\nGetBooleanAnd=0,boolcall,boolcall\n_GetBooleanAnd_Defaults=_,_\n_GetBooleanAnd_Category=TC_CONDITION\n_GetBooleanAnd_UseWithAI=1\n\nGetBooleanOr=0,boolcall,boolcall\n_GetBooleanOr_Defaults=_,_\n_GetBooleanOr_Category=TC_CONDITION\n_GetBooleanOr_UseWithAI=1\n\n// Specially handled by the editor\nAndMultiple=1,nothing\n_AndMultiple_Category=TC_CONDITION\n\n// Specially handled by the editor\nOrMultiple=1,nothing\n_OrMultiple_Category=TC_CONDITION\n\n\n//***************************************************************************\n[TriggerActions]\n// Defines action functions\n// Key: action function name\n// Value 0: first game version in which this function is valid\n// Value 1+: argument types\n\nDoNothing=0,nothing\n_DoNothing_Defaults=\n_DoNothing_Category=TC_NOTHING\n\nCommentString=0,scriptcode\n_CommentString_Defaults=_\n_CommentString_Category=TC_COMMENT\n\nCustomScriptCode=1,scriptcode\n_CustomScriptCode_Defaults=_\n_CustomScriptCode_Category=TC_CUSTOM\n\nTriggerSleepAction=0,real\n_TriggerSleepAction_Defaults=2\n_TriggerSleepAction_Limits=0,_\n_TriggerSleepAction_Category=TC_WAIT\n\nPolledWait=1,real\n_PolledWait_Defaults=2\n_PolledWait_Limits=0,_\n_PolledWait_Category=TC_WAIT\n\nWaitForCondition=1,boolexpr,real\n_WaitForCondition_Defaults=_,1\n_WaitForCondition_Limits=_,_,0.1,_\n_WaitForCondition_Category=TC_WAIT\n\nWaitForSoundBJ=0,sound,real\n_WaitForSoundBJ_Defaults=GetLastPlayedSound,0\n_WaitForSoundBJ_Category=TC_WAIT\n\n\n// Specially handled by the editor\nSetVariable=0,AnyGlobal,Null\n_SetVariable_Defaults=_,_\n_SetVariable_Category=TC_SETVARIABLE\n\n\n// Specially handled by the editor\nReturnAction=0,nothing\n_ReturnAction_Defaults=\n_ReturnAction_Category=TC_SKIPACTIONS\n\n\n// Specially handled by the editor\nIfThenElseMultiple=1,nothing\n_IfThenElseMultiple_Category=TC_LOGIC\n\n// Specially handled by the editor\nIfThenElse=0,boolexpr,code,code\n_IfThenElse_Defaults=_,DoNothing,DoNothing\n_IfThenElse_Category=TC_LOGIC\n\n// Specially handled by the editor\nForLoopAMultiple=1,integer,integer\n_ForLoopAMultiple_Defaults=1,10\n_ForLoopAMultiple_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopBMultiple=1,integer,integer\n_ForLoopBMultiple_Defaults=1,10\n_ForLoopBMultiple_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopVarMultiple=1,integervar,integer,integer\n_ForLoopVarMultiple_Defaults=_,1,10\n_ForLoopVarMultiple_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopA=0,integer,integer,code\n_ForLoopA_Defaults=1,10,DoNothing\n_ForLoopA_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopB=0,integer,integer,code\n_ForLoopB_Defaults=1,10,DoNothing\n_ForLoopB_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopVar=1,integervar,integer,integer,code\n_ForLoopVar_Defaults=_,1,10,DoNothing\n_ForLoopVar_Category=TC_FORLOOP\n\n// AI actions\nStartMeleeAI=0,player,aiscript\n_StartMeleeAI_Defaults=Player00,\"map.ai\"\n_StartMeleeAI_Category=TC_AI\n\nStartCampaignAI=0,player,aiscript\n_StartCampaignAI_Defaults=Player00,\"map.ai\"\n_StartCampaignAI_Category=TC_AI\n\nCommandAI=0,player,integer,integer\n_CommandAI_Defaults=Player00,_,_\n_CommandAI_Category=TC_AI\n\nRemoveGuardPosition=0,unit\n_RemoveGuardPosition_Defaults=_\n_RemoveGuardPosition_Category=TC_AI\n\nRemoveAllGuardPositions=0,player\n_RemoveAllGuardPositions_Defaults=Player00\n_RemoveAllGuardPositions_Category=TC_AI\n\nRecycleGuardPosition=0,unit\n_RecycleGuardPosition_Defaults=_\n_RecycleGuardPosition_Category=TC_AI\n\nLockGuardPosition=1,unit\n_LockGuardPosition_Defaults=_\n_LockGuardPosition_Category=TC_AI\n\n// Animation actions\nSetUnitAnimation=0,unit,string\n_SetUnitAnimation_Defaults=_,\"stand\"\n_SetUnitAnimation_Category=TC_ANIMATION\n\nSetUnitAnimationWithRarity=0,unit,string,raritycontrol\n_SetUnitAnimationWithRarity_Defaults=_,\"stand\",RarityControlFrequent\n_SetUnitAnimationWithRarity_Category=TC_ANIMATION\n\nQueueUnitAnimationBJ=0,unit,string\n_QueueUnitAnimationBJ_Defaults=_,\"stand\"\n_QueueUnitAnimationBJ_Category=TC_ANIMATION\n\nResetUnitAnimation=0,unit\n_ResetUnitAnimation_Defaults=_\n_ResetUnitAnimation_Category=TC_ANIMATION\n\nAddUnitAnimationPropertiesBJ=0,addremoveoption,string,unit\n_AddUnitAnimationPropertiesBJ_Defaults=AddRemoveAdd,\"gold\",_\n_AddUnitAnimationPropertiesBJ_Category=TC_ANIMATION\n\nSetUnitLookAt=0,unit,unitfacingbone,unit,real,real,real\n_SetUnitLookAt_Defaults=_,UnitFacingBoneHead,_,0,0,90\n_SetUnitLookAt_Category=TC_ANIMATION\n\nResetUnitLookAt=0,unit\n_ResetUnitLookAt_Defaults=_\n_ResetUnitLookAt_Category=TC_ANIMATION\n\nSetUnitScalePercent=0,unit,real,real,real\n_SetUnitScalePercent_Defaults=_,100,100,100\n_SetUnitScalePercent_Limits=_,_,0,_,0,_,0,_\n_SetUnitScalePercent_Category=TC_ANIMATION\n\nSetUnitVertexColorBJ=0,unit,real,real,real,real\n_SetUnitVertexColorBJ_Defaults=_,100,100,100,0\n_SetUnitVertexColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_SetUnitVertexColorBJ_Category=TC_ANIMATION\n\nSetUnitTimeScalePercent=0,unit,real\n_SetUnitTimeScalePercent_Defaults=_,100\n_SetUnitTimeScalePercent_Limits=_,_,0,_\n_SetUnitTimeScalePercent_Category=TC_ANIMATION\n\nSetUnitTurnSpeedBJ=0,unit,real\n_SetUnitTurnSpeedBJ_Defaults=GetTriggerUnit,0.5\n_SetUnitTurnSpeedBJ_Limits=_,_,0,1\n_SetUnitTurnSpeedBJ_Category=TC_ANIMATION\n\nSetUnitBlendTimeBJ=0,unit,real\n_SetUnitBlendTimeBJ_Defaults=GetTriggerUnit,_\n_SetUnitBlendTimeBJ_Category=TC_ANIMATION\n\nSetUnitFlyHeightBJ=0,unit,real,real\n_SetUnitFlyHeightBJ_Defaults=GetTriggerUnit,_,_\n_SetUnitFlyHeightBJ_Category=TC_ANIMATION\n\nSetUnitPropWindowBJ=0,unit,real\n_SetUnitPropWindowBJ_Defaults=GetTriggerUnit,_\n_SetUnitPropWindowBJ_Category=TC_ANIMATION\n\nSetDestructableAnimationBJ=0,destructable,string\n_SetDestructableAnimationBJ_Defaults=_,\"stand\"\n_SetDestructableAnimationBJ_Category=TC_ANIMATION\n\nQueueDestructableAnimationBJ=0,destructable,string\n_QueueDestructableAnimationBJ_Defaults=_,\"stand\"\n_QueueDestructableAnimationBJ_Category=TC_ANIMATION\n\nSetDestAnimationSpeedPercent=1,destructable,real\n_SetDestAnimationSpeedPercent_Defaults=_,100\n_SetDestAnimationSpeedPercent_Category=TC_ANIMATION\n\nSetDoodadAnimationRectBJ=0,string,doodadcode,rect\n_SetDoodadAnimationRectBJ_Defaults=\"death\",_,GetPlayableMapRect\n_SetDoodadAnimationRectBJ_Category=TC_ANIMATION\n\nSetDoodadAnimationBJ=0,string,doodadcode,real,location\n_SetDoodadAnimationBJ_Defaults=\"death\",_,128,GetRectCenter\n_SetDoodadAnimationBJ_Category=TC_ANIMATION\n\n\n// Camera actions\nCameraSetupApplyForPlayer=0,cameraapplyoption,camerasetup,player,real\n_CameraSetupApplyForPlayer_Defaults=CameraApply,_,Player00,0\n_CameraSetupApplyForPlayer_Limits=_,_,_,_,_,_,0,_\n_CameraSetupApplyForPlayer_Category=TC_CAMERA\n\nPanCameraToTimedLocForPlayer=0,player,location,real\n_PanCameraToTimedLocForPlayer_Defaults=Player00,GetRectCenter,0\n_PanCameraToTimedLocForPlayer_Limits=_,_,_,_,0,_\n_PanCameraToTimedLocForPlayer_Category=TC_CAMERA\n\nPanCameraToTimedLocWithZForPlayer=0,player,location,real,real\n_PanCameraToTimedLocWithZForPlayer_Defaults=Player00,GetRectCenter,0,0\n_PanCameraToTimedLocWithZForPlayer_Limits=_,_,_,_,_,_,0,_\n_PanCameraToTimedLocWithZForPlayer_Category=TC_CAMERA\n\nSmartCameraPanBJ=0,player,location,real\n_SmartCameraPanBJ_Defaults=Player00,GetRectCenter,0.5\n_SmartCameraPanBJ_Limits=_,_,_,_,0,_\n_SmartCameraPanBJ_Category=TC_CAMERA\n\nSetCameraFieldForPlayer=0,player,camerafield,real,real\n_SetCameraFieldForPlayer_Defaults=Player00,CameraFieldTargetDistance,CameraSetupGetFieldSwap,0\n_SetCameraFieldForPlayer_Limits=_,_,_,_,_,_,0,_\n_SetCameraFieldForPlayer_Category=TC_CAMERA\n\nRotateCameraAroundLocBJ=1,real,location,player,real\n_RotateCameraAroundLocBJ_Defaults=90,GetRectCenter,Player00,2\n_RotateCameraAroundLocBJ_Limits=_,_,_,_,_,_,0,_\n_RotateCameraAroundLocBJ_Category=TC_CAMERA\n\nSetCameraTargetControllerNoZForPlayer=0,player,unit,real,real,cameraorientationoption\n_SetCameraTargetControllerNoZForPlayer_Defaults=Player00,GetTriggerUnit,0,0,CameraOrientationNormal\n_SetCameraTargetControllerNoZForPlayer_Category=TC_CAMERA\n\nSetCameraOrientControllerForPlayerBJ=0,player,unit,real,real\n_SetCameraOrientControllerForPlayerBJ_Defaults=Player00,GetTriggerUnit,0,0\n_SetCameraOrientControllerForPlayerBJ_Category=TC_CAMERA\n\nSetCinematicCameraForPlayer=0,player,modelfile\n_SetCinematicCameraForPlayer_Defaults=Player00,\"cinematic.mdl\"\n_SetCinematicCameraForPlayer_Category=TC_CAMERA\n\nStopCameraForPlayerBJ=0,player\n_StopCameraForPlayerBJ_Defaults=Player00\n_StopCameraForPlayerBJ_Category=TC_CAMERA\n\nResetToGameCameraForPlayer=0,player,real\n_ResetToGameCameraForPlayer_Defaults=Player00,0\n_ResetToGameCameraForPlayer_Limits=_,_,0,_\n_ResetToGameCameraForPlayer_Category=TC_CAMERA\n\nCameraSetSmoothingFactorBJ=0,real\n_CameraSetSmoothingFactorBJ_Defaults=1\n_CameraSetSmoothingFactorBJ_Limits=0,_\n_CameraSetSmoothingFactorBJ_Category=TC_CAMERA\n\nCameraResetSmoothingFactorBJ=0,nothing\n_CameraResetSmoothingFactorBJ_Defaults=\n_CameraResetSmoothingFactorBJ_Category=TC_CAMERA\n\nCameraSetSourceNoiseForPlayer=0,player,real,real\n_CameraSetSourceNoiseForPlayer_Defaults=Player00,10,0.1\n_CameraSetSourceNoiseForPlayer_Category=TC_CAMERA\n\nCameraSetTargetNoiseForPlayer=0,player,real,real\n_CameraSetTargetNoiseForPlayer_Defaults=Player00,10,0.1\n_CameraSetTargetNoiseForPlayer_Category=TC_CAMERA\n\nCameraSetEQNoiseForPlayer=1,player,real\n_CameraSetEQNoiseForPlayer_Defaults=Player00,3\n_CameraSetEQNoiseForPlayer_Limits=_,_,0,_\n_CameraSetEQNoiseForPlayer_Category=TC_CAMERA\n\nCameraClearNoiseForPlayer=0,player\n_CameraClearNoiseForPlayer_Defaults=Player00\n_CameraClearNoiseForPlayer_Category=TC_CAMERA\n\nAdjustCameraBoundsForPlayerBJ=0,cameraboundsadjusttype,player,real,real,real,real\n_AdjustCameraBoundsForPlayerBJ_Defaults=CameraBoundsAdjustAdd,Player00,0,0,0,0\n_AdjustCameraBoundsForPlayerBJ_Category=TC_CAMERA\n\nSetCameraBoundsToRectForPlayerBJ=0,player,rect\n_SetCameraBoundsToRectForPlayerBJ_Defaults=Player00,_\n_SetCameraBoundsToRectForPlayerBJ_Category=TC_CAMERA\n\nSetCameraQuickPositionLocForPlayer=0,player,location\n_SetCameraQuickPositionLocForPlayer_Defaults=Player00,GetRectCenter\n_SetCameraQuickPositionLocForPlayer_Category=TC_CAMERA\n\n\n// Cinematic actions\nTransmissionFromUnitWithNameBJ=0,force,unit,StringExt,sound,StringExt,addsettooption,real,waitdontoption\n_TransmissionFromUnitWithNameBJ_Defaults=GetPlayersAll,_,_,SoundNull,_,AddSetToAdd,0,WaitDontWait\n_TransmissionFromUnitWithNameBJ_Category=TC_CINEMATIC\n\nTransmissionFromUnitTypeWithNameBJ=0,force,player,unitcode,StringExt,location,sound,StringExt,addsettooption,real,waitdontoption\n_TransmissionFromUnitTypeWithNameBJ_Defaults=GetPlayersAll,Player00,hfoo,_,GetRectCenter,SoundNull,_,AddSetToAdd,0,WaitDontWait\n_TransmissionFromUnitTypeWithNameBJ_Category=TC_CINEMATIC\n\nForceCinematicSubtitlesBJ=1,onoffoption\n_ForceCinematicSubtitlesBJ_Defaults=OnOffOn\n_ForceCinematicSubtitlesBJ_Category=TC_CINEMATIC\n\nCinematicModeBJ=0,onoffoption,force\n_CinematicModeBJ_Defaults=OnOffOn,GetPlayersAll\n_CinematicModeBJ_Category=TC_CINEMATIC\n\nCinematicModeExBJ=1,onoffoption,force,real\n_CinematicModeExBJ_Defaults=OnOffOn,GetPlayersAll,0.2\n_CinematicModeExBJ_Category=TC_CINEMATIC\n\nCinematicFadeBJ=0,fadetypeoption,real,cinefiltertexture,real,real,real,real\n_CinematicFadeBJ_Defaults=FadeTypeOptionFadeOutIn,2,CineFilterTextureWhite,0,0,0,0\n_CinematicFadeBJ_Limits=_,_,0,_,_,_,0,100,0,100,0,100,0,100\n_CinematicFadeBJ_Category=TC_CINEMATIC\n\nCinematicFilterGenericBJ=0,real,blendmode,cinefiltertexture,real,real,real,real,real,real,real,real\n_CinematicFilterGenericBJ_Defaults=2,BlendModeBlend,CineFilterTextureWhite,100,100,100,100,0,0,0,0\n_CinematicFilterGenericBJ_Limits=0,_,_,_,_,_,0,100,0,100,0,100,0,100,0,100,0,100,0,100,0,100\n_CinematicFilterGenericBJ_Category=TC_CINEMATIC\n\nDisplayCineFilterBJ=0,showhideoption\n_DisplayCineFilterBJ_Defaults=ShowHideHide\n_DisplayCineFilterBJ_Category=TC_CINEMATIC\n\nPingMinimapLocForForce=0,force,location,real\n_PingMinimapLocForForce_Defaults=GetPlayersAll,GetRectCenter,1\n_PingMinimapLocForForce_Limits=_,_,_,_,0,_\n_PingMinimapLocForForce_Category=TC_CINEMATIC\n\nPingMinimapLocForForceEx=1,force,location,real,minimappingstyle,real,real,real\n_PingMinimapLocForForceEx_Defaults=GetPlayersAll,GetRectCenter,1,MinimapPingStyleSimple,100,100,100\n_PingMinimapLocForForceEx_Limits=_,_,_,_,0,_,_,_,0,100,0,100,0,100\n_PingMinimapLocForForceEx_Category=TC_CINEMATIC\n\nUnitAddIndicatorBJ=0,unit,real,real,real,real\n_UnitAddIndicatorBJ_Defaults=_,100,100,100,0\n_UnitAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_UnitAddIndicatorBJ_Category=TC_CINEMATIC\n\nDestructableAddIndicatorBJ=0,destructable,real,real,real,real\n_DestructableAddIndicatorBJ_Defaults=_,100,100,100,0\n_DestructableAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_DestructableAddIndicatorBJ_Category=TC_CINEMATIC\n\nItemAddIndicatorBJ=0,item,real,real,real,real\n_ItemAddIndicatorBJ_Defaults=_,100,100,100,0\n_ItemAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_ItemAddIndicatorBJ_Category=TC_CINEMATIC\n\nClearTextMessagesBJ=0,force\n_ClearTextMessagesBJ_Defaults=GetPlayersAll\n_ClearTextMessagesBJ_Category=TC_CINEMATIC\n\nShowInterfaceForceOff=0,force,real\n_ShowInterfaceForceOff_Defaults=GetPlayersAll,2\n_ShowInterfaceForceOff_Limits=_,_,0,_\n_ShowInterfaceForceOff_Category=TC_CINEMATIC\n\nShowInterfaceForceOn=0,force,real\n_ShowInterfaceForceOn_Defaults=GetPlayersAll,2\n_ShowInterfaceForceOn_Limits=_,_,0,_\n_ShowInterfaceForceOn_Category=TC_CINEMATIC\n\nSetUserControlForceOff=0,force\n_SetUserControlForceOff_Defaults=GetPlayersAll\n_SetUserControlForceOff_Category=TC_CINEMATIC\n\nSetUserControlForceOn=0,force\n_SetUserControlForceOn_Defaults=GetPlayersAll\n_SetUserControlForceOn_Category=TC_CINEMATIC\n\nEnableOcclusionBJ=0,enabledisableoption,force\n_EnableOcclusionBJ_Defaults=EnableDisableDisable,GetPlayersAll\n_EnableOcclusionBJ_Category=TC_CINEMATIC\n\nEnableWorldFogBoundaryBJ=0,enabledisableoption,force\n_EnableWorldFogBoundaryBJ_Defaults=EnableDisableDisable,GetPlayersAll\n_EnableWorldFogBoundaryBJ_Category=TC_CINEMATIC\n\n\n// Countdown Timer actions\nStartTimerBJ=0,timer,periodicoption,real\n_StartTimerBJ_Defaults=_,PeriodicOptionOneTime,30\n_StartTimerBJ_Limits=_,_,_,_,0,_\n_StartTimerBJ_Category=TC_TIMER\n\nPauseTimerBJ=0,pauseresumeoption,timer\n_PauseTimerBJ_Defaults=PauseResumePause,GetLastCreatedTimerBJ\n_PauseTimerBJ_Category=TC_TIMER\n\nCreateTimerDialogBJ=0,timer,StringExt\n_CreateTimerDialogBJ_Defaults=GetLastCreatedTimerBJ,_\n_CreateTimerDialogBJ_Category=TC_TIMER\n\nDestroyTimerDialogBJ=0,timerdialog\n_DestroyTimerDialogBJ_Defaults=GetLastCreatedTimerDialogBJ\n_DestroyTimerDialogBJ_Category=TC_TIMER\n\nTimerDialogDisplayForPlayerBJ=1,showhideoption,timerdialog,player\n_TimerDialogDisplayForPlayerBJ_Defaults=ShowHideHide,GetLastCreatedTimerDialogBJ,Player00\n_TimerDialogDisplayForPlayerBJ_Category=TC_TIMER\n\nTimerDialogDisplayBJ=0,showhideoption,timerdialog\n_TimerDialogDisplayBJ_Defaults=ShowHideHide,GetLastCreatedTimerDialogBJ\n_TimerDialogDisplayBJ_Category=TC_TIMER\n\nTimerDialogSetTitleBJ=0,timerdialog,StringExt\n_TimerDialogSetTitleBJ_Defaults=GetLastCreatedTimerDialogBJ,_\n_TimerDialogSetTitleBJ_Category=TC_TIMER\n\nTimerDialogSetTitleColorBJ=0,timerdialog,real,real,real,real\n_TimerDialogSetTitleColorBJ_Defaults=GetLastCreatedTimerDialogBJ,100,80,20,0\n_TimerDialogSetTitleColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_TimerDialogSetTitleColorBJ_Category=TC_TIMER\n\nTimerDialogSetTimeColorBJ=0,timerdialog,real,real,real,real\n_TimerDialogSetTimeColorBJ_Defaults=GetLastCreatedTimerDialogBJ,100,80,20,0\n_TimerDialogSetTimeColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_TimerDialogSetTimeColorBJ_Category=TC_TIMER\n\n//TimerDialogSetSpeedBJ=0,timerdialog,real\n//_TimerDialogSetSpeedBJ_Defaults=GetLastCreatedTimerDialogBJ,1\n//_TimerDialogSetSpeedBJ_Category=TC_TIMER\n\n\n// Destructable actions\nCreateDestructableLoc=0,destructablecode,location,real,real,integer\n_CreateDestructableLoc_Defaults=LTlt,GetRectCenter,GetRandomDirectionDeg,1,0\n_CreateDestructableLoc_Limits=_,_,_,_,_,_,0,_,0,_\n_CreateDestructableLoc_Category=TC_DESTRUCT\n\nCreateDeadDestructableLocBJ=0,destructablecode,location,real,real,integer\n_CreateDeadDestructableLocBJ_Defaults=LTlt,GetRectCenter,GetRandomDirectionDeg,1,0\n_CreateDeadDestructableLocBJ_Limits=_,_,_,_,_,_,0,_,0,_\n_CreateDeadDestructableLocBJ_Category=TC_DESTRUCT\n\nKillDestructable=0,destructable\n_KillDestructable_Defaults=GetLastCreatedDestructable\n_KillDestructable_Category=TC_DESTRUCT\n\nRemoveDestructable=0,destructable\n_RemoveDestructable_Defaults=GetLastCreatedDestructable\n_RemoveDestructable_Category=TC_DESTRUCT\n\nDestructableRestoreLife=0,destructable,real,showhideoption\n_DestructableRestoreLife_Defaults=GetLastCreatedDestructable,GetDestructableMaxLife,ShowHideShow\n_DestructableRestoreLife_Category=TC_DESTRUCT\n\nShowDestructableBJ=1,showhideoption,destructable\n_ShowDestructableBJ_Defaults=ShowHideHide,GetLastCreatedDestructable\n_ShowDestructableBJ_Category=TC_DESTRUCT\n\nSetDestructableLifePercentBJ=0,destructable,real\n_SetDestructableLifePercentBJ_Defaults=GetLastCreatedDestructable,100\n_SetDestructableLifePercentBJ_Limits=_,_,0,100\n_SetDestructableLifePercentBJ_Category=TC_DESTRUCT\n\nSetDestructableLife=0,destructable,real\n_SetDestructableLife_Defaults=GetLastCreatedDestructable,GetDestructableMaxLife\n_SetDestructableLife_Limits=_,_,0,_\n_SetDestructableLife_Category=TC_DESTRUCT\n\nSetDestructableMaxLifeBJ=0,destructable,real\n_SetDestructableMaxLifeBJ_Defaults=GetLastCreatedDestructable,100\n_SetDestructableMaxLifeBJ_Limits=_,_,0,_\n_SetDestructableMaxLifeBJ_Category=TC_DESTRUCT\n\nModifyGateBJ=0,gateoperation,destructable\n_ModifyGateBJ_Defaults=GateOperationOpen,_\n_ModifyGateBJ_Category=TC_DESTRUCT\n\nChangeElevatorWalls=1,elevatorwallop,elevatorwalltype,destructable\n_ChangeElevatorWalls_Defaults=ElevatorWallOpClose,ElevatorWallTypeAll,_\n_ChangeElevatorWalls_Category=TC_DESTRUCT\n\nChangeElevatorHeight=1,destructable,integer\n_ChangeElevatorHeight_Defaults=_,1\n_ChangeElevatorHeight_Limits=_,_,1,3\n_ChangeElevatorHeight_Category=TC_DESTRUCT\n\nSetDestructableInvulnerableBJ=0,destructable,invulnerableoption\n_SetDestructableInvulnerableBJ_Defaults=GetLastCreatedDestructable,InvulnerabilityInvulnerable\n_SetDestructableInvulnerableBJ_Category=TC_DESTRUCT\n\nSetDestructableOccluderHeight=1,destructable,real\n_SetDestructableOccluderHeight_Defaults=_,128\n_SetDestructableOccluderHeight_Category=TC_DESTRUCT\n\nEnumDestructablesInRectAllMultiple=1,rect\n_EnumDestructablesInRectAllMultiple_Defaults=GetPlayableMapRect\n_EnumDestructablesInRectAllMultiple_Category=TC_DESTRUCT\n_EnumDestructablesInRectAllMultiple_ScriptName=EnumDestructablesInRectAll\n\nEnumDestructablesInCircleBJMultiple=1,real,location\n_EnumDestructablesInCircleBJMultiple_Defaults=256,GetRectCenter\n_EnumDestructablesInCircleBJMultiple_Category=TC_DESTRUCT\n_EnumDestructablesInCircleBJMultiple_ScriptName=EnumDestructablesInCircleBJ\n\nEnumDestructablesInRectAll=0,rect,code\n_EnumDestructablesInRectAll_Defaults=GetPlayableMapRect,DoNothing\n_EnumDestructablesInRectAll_Category=TC_DESTRUCT\n\nEnumDestructablesInCircleBJ=0,real,location,code\n_EnumDestructablesInCircleBJ_Defaults=256,GetRectCenter,DoNothing\n_EnumDestructablesInCircleBJ_Category=TC_DESTRUCT\n\n\n// Dialog actions\nDialogDisplayBJ=0,showhideoption,dialog,player\n_DialogDisplayBJ_Defaults=ShowHideShow,_,Player00\n_DialogDisplayBJ_Category=TC_DIALOG\n\nDialogSetMessageBJ=0,dialog,StringExt\n_DialogSetMessageBJ_Defaults=_,_\n_DialogSetMessageBJ_Category=TC_DIALOG\n\nDialogAddButtonBJ=0,dialog,StringExt\n_DialogAddButtonBJ_Defaults=_,_\n_DialogAddButtonBJ_Category=TC_DIALOG\n\nDialogClearBJ=0,dialog\n_DialogClearBJ_Defaults=_\n_DialogClearBJ_Category=TC_DIALOG\n\n\n// Environment actions\nAddWeatherEffectSaveLast=0,rect,weathereffectcode\n_AddWeatherEffectSaveLast_Defaults=GetPlayableMapRect,WeatherAshenvaleHeavyRain\n_AddWeatherEffectSaveLast_Category=TC_ENVIRONMENT\n\nEnableWeatherEffect=0,weathereffect,onoffoption\n_EnableWeatherEffect_Defaults=GetLastCreatedWeatherEffect,OnOffOn\n_EnableWeatherEffect_Category=TC_ENVIRONMENT\n\nRemoveWeatherEffectBJ=0,weathereffect\n_RemoveWeatherEffectBJ_Defaults=GetLastCreatedWeatherEffect\n_RemoveWeatherEffectBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationCraterBJ=1,real,cratertype,location,real,real\n_TerrainDeformationCraterBJ_Defaults=0.5,CraterTypeTemporary,GetRectCenter,512,64\n_TerrainDeformationCraterBJ_Limits=0.01,_,_,_,_,_,1,_,_,_\n_TerrainDeformationCraterBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationRippleBJ=1,real,rippletype,location,real,real,real,real,real\n_TerrainDeformationRippleBJ_Defaults=4,RippleTypeNormal,GetRectCenter,1024,1024,64,1,512\n_TerrainDeformationRippleBJ_Limits=0.01,_,_,_,_,_,0,_,1,_,_,_,0.01,_,1,_\n_TerrainDeformationRippleBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationWaveBJ=1,real,location,location,real,real,real\n_TerrainDeformationWaveBJ_Defaults=0.5,GetRectCenter,GetRectCenter,256,96,0\n_TerrainDeformationWaveBJ_Limits=0.01,_,_,_,_,_,0,_,_,_,0,_\n_TerrainDeformationWaveBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationRandomBJ=1,real,location,real,real,real,real\n_TerrainDeformationRandomBJ_Defaults=4,GetRectCenter,512,-32,32,0.1\n_TerrainDeformationRandomBJ_Limits=0.01,_,_,_,0,_,_,_,_,_,0.01,_\n_TerrainDeformationRandomBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationStopBJ=1,terraindeformation,real\n_TerrainDeformationStopBJ_Defaults=GetLastCreatedTerrainDeformation,0\n_TerrainDeformationStopBJ_Limits=_,_,0,_\n_TerrainDeformationStopBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformStopAll=1,nothing\n_TerrainDeformStopAll_Defaults=\n_TerrainDeformStopAll_Category=TC_ENVIRONMENT\n\nSetWaterDeforms=1,onoffoption\n_SetWaterDeforms_Defaults=OnOffOn\n_SetWaterDeforms_Category=TC_ENVIRONMENT\n\nSetTerrainTypeBJ=1,location,terraintype,integer,integer,terrainshape\n_SetTerrainTypeBJ_Defaults=GetRectCenter,TerrainTypeLdrt,-1,1,TerrainShapeCircle\n_SetTerrainTypeBJ_Category=TC_ENVIRONMENT\n\nSetTerrainPathableBJ=1,location,pathingtype,onoffoption\n_SetTerrainPathableBJ_Defaults=GetRectCenter,PathingTypeWalkability,OnOffOn\n_SetTerrainPathableBJ_Category=TC_ENVIRONMENT\n\nSetWaterBaseColorBJ=1,real,real,real,real\n_SetWaterBaseColorBJ_Defaults=100,100,100,0\n_SetWaterBaseColorBJ_Limits=0,100,0,100,0,100,0,100\n_SetWaterBaseColorBJ_Category=TC_ENVIRONMENT\n\nSetSkyModel=0,skymodelstring\n_SetSkyModel_Defaults=SkyModelNone\n_SetSkyModel_Category=TC_ENVIRONMENT\n\nSetTerrainFogExBJ=0,fogstyle,real,real,real,real,real,real\n_SetTerrainFogExBJ_Defaults=FogStyleLinear,1000,8000,0,100,100,100\n_SetTerrainFogExBJ_Limits=_,_,0,_,0,_,0,_,0,100,0,100,0,100\n_SetTerrainFogExBJ_Category=TC_ENVIRONMENT\n\nResetTerrainFogBJ=0,nothing\n_ResetTerrainFogBJ_Defaults=\n_ResetTerrainFogBJ_Category=TC_ENVIRONMENT\n\nSetBlightRectBJ=0,createremoveoption,player,rect\n_SetBlightRectBJ_Defaults=CreateRemoveCreate,Player00,GetPlayableMapRect\n_SetBlightRectBJ_Category=TC_ENVIRONMENT\n\nSetBlightRadiusLocBJ=0,createremoveoption,player,location,real\n_SetBlightRadiusLocBJ_Defaults=CreateRemoveCreate,Player00,GetRectCenter,512\n_SetBlightRadiusLocBJ_Limits=_,_,_,_,_,_,0,_\n_SetBlightRadiusLocBJ_Category=TC_ENVIRONMENT\n\n// Text Tag actions\nCreateTextTagLocBJ=1,StringExt,location,real,real,real,real,real,real\n_CreateTextTagLocBJ_Defaults=_,GetRectCenter,0,10,100,100,100,0\n_CreateTextTagLocBJ_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100\n_CreateTextTagLocBJ_Category=TC_TEXTTAG\n\nCreateTextTagUnitBJ=1,StringExt,unit,real,real,real,real,real,real\n_CreateTextTagUnitBJ_Defaults=_,_,0,10,100,100,100,0\n_CreateTextTagUnitBJ_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100\n_CreateTextTagUnitBJ_Category=TC_TEXTTAG\n\nDestroyTextTagBJ=1,texttag\n_DestroyTextTagBJ_Defaults=GetLastCreatedTextTag\n_DestroyTextTagBJ_Category=TC_TEXTTAG\n\nShowTextTagForceBJ=1,showhideoption,texttag,force\n_ShowTextTagForceBJ_Defaults=ShowHideShow,GetLastCreatedTextTag,GetPlayersAll\n_ShowTextTagForceBJ_Category=TC_TEXTTAG\n\nSetTextTagVelocityBJ=1,texttag,real,real\n_SetTextTagVelocityBJ_Defaults=GetLastCreatedTextTag,64,90\n_SetTextTagVelocityBJ_Category=TC_TEXTTAG\n\nSetTextTagColorBJ=1,texttag,real,real,real,real\n_SetTextTagColorBJ_Defaults=GetLastCreatedTextTag,100,100,100,0\n_SetTextTagColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_SetTextTagColorBJ_Category=TC_TEXTTAG\n\nSetTextTagPosBJ=1,texttag,location,real\n_SetTextTagPosBJ_Defaults=GetLastCreatedTextTag,GetRectCenter,0\n_SetTextTagPosBJ_Category=TC_TEXTTAG\n\nSetTextTagPosUnitBJ=1,texttag,unit,real\n_SetTextTagPosUnitBJ_Defaults=GetLastCreatedTextTag,_,0\n_SetTextTagPosUnitBJ_Category=TC_TEXTTAG\n\nSetTextTagTextBJ=1,texttag,StringExt,real\n_SetTextTagTextBJ_Defaults=GetLastCreatedTextTag,_,10\n_SetTextTagTextBJ_Category=TC_TEXTTAG\n\nSetTextTagSuspendedBJ=1,texttag,enabledisableoption\n_SetTextTagSuspendedBJ_Defaults=GetLastCreatedTextTag,EnableDisableEnable\n_SetTextTagSuspendedBJ_Category=TC_TEXTTAG\n\nSetTextTagPermanentBJ=1,texttag,enabledisableoption\n_SetTextTagPermanentBJ_Defaults=GetLastCreatedTextTag,EnableDisableEnable\n_SetTextTagPermanentBJ_Category=TC_TEXTTAG\n\nSetTextTagLifespanBJ=1,texttag,real\n_SetTextTagLifespanBJ_Defaults=GetLastCreatedTextTag,5\n_SetTextTagLifespanBJ_Category=TC_TEXTTAG\n\nSetTextTagFadepointBJ=1,texttag,real\n_SetTextTagFadepointBJ_Defaults=GetLastCreatedTextTag,4\n_SetTextTagFadepointBJ_Category=TC_TEXTTAG\n\nSetTextTagAgeBJ=1,texttag,real\n_SetTextTagAgeBJ_Defaults=GetLastCreatedTextTag,0\n_SetTextTagAgeBJ_Category=TC_TEXTTAG\n\n\n// Game actions\nDisplayTextToForce=0,force,StringExt\n_DisplayTextToForce_Defaults=GetPlayersAll,_\n_DisplayTextToForce_Category=TC_GAME\n\nDisplayTimedTextToForce=0,force,real,StringExt\n_DisplayTimedTextToForce_Defaults=GetPlayersAll,30,_\n_DisplayTimedTextToForce_Limits=_,_,0,_,_,_\n_DisplayTimedTextToForce_Category=TC_GAME\n\nPauseGameOn=0,nothing\n_PauseGameOn_Defaults=\n_PauseGameOn_Category=TC_GAME\n\nPauseGameOff=0,nothing\n_PauseGameOff_Defaults=\n_PauseGameOff_Category=TC_GAME\n\nSetGameSpeed=0,gamespeed\n_SetGameSpeed_Defaults=GameSpeedNormal\n_SetGameSpeed_Category=TC_GAME\n\nLockGameSpeedBJ=0,nothing\n_LockGameSpeedBJ_Defaults=\n_LockGameSpeedBJ_Category=TC_GAME\n\nUnlockGameSpeedBJ=0,nothing\n_UnlockGameSpeedBJ_Defaults=\n_UnlockGameSpeedBJ_Category=TC_GAME\n\nSetMapFlag=0,mapflag,onoffoption\n_SetMapFlag_Defaults=MapFlagUseHandicaps,OnOffOn\n_SetMapFlag_Category=TC_GAME\n\nSetTimeOfDay=0,real\n_SetTimeOfDay_Defaults=12\n_SetTimeOfDay_Limits=0,24\n_SetTimeOfDay_Category=TC_GAME\n\nSetTimeOfDayScalePercentBJ=0,real\n_SetTimeOfDayScalePercentBJ_Defaults=100\n_SetTimeOfDayScalePercentBJ_Defaults=0,_\n_SetTimeOfDayScalePercentBJ_Category=TC_GAME\n\nUseTimeOfDayBJ=0,onoffoption\n_UseTimeOfDayBJ_Defaults=OnOffOff\n_UseTimeOfDayBJ_Category=TC_GAME\n\nShareEverythingWithTeam=0,player\n_ShareEverythingWithTeam_Defaults=Player00\n_ShareEverythingWithTeam_Category=TC_GAME\n\nMakeUnitsPassiveForPlayer=0,player\n_MakeUnitsPassiveForPlayer_Defaults=Player00\n_MakeUnitsPassiveForPlayer_Category=TC_GAME\n\nSetNextLevelBJ=0,string\n_SetNextLevelBJ_Defaults=\"Maps\\MapName.w3m\"\n_SetNextLevelBJ_Category=TC_GAME\n\nCustomVictoryBJ=0,player,useskipoption,useskipoption\n_CustomVictoryBJ_Defaults=Player00,UseSkipOptionUse,UseSkipOptionUse\n_CustomVictoryBJ_Category=TC_GAME\n\nCustomDefeatBJ=0,player,StringExt\n_CustomDefeatBJ_Defaults=Player00,WESTRING_PEVENT_DEFEAT_MSG\n_CustomDefeatBJ_Category=TC_GAME\n\nLoadGameBJ=1,anyfile,useskipoption\n_LoadGameBJ_Defaults=\"LoadFile.w3z\",UseSkipOptionSkip\n_LoadGameBJ_Category=TC_GAME\n\nSaveAndLoadGameBJ=1,anyfile,anyfile,useskipoption\n_SaveAndLoadGameBJ_Defaults=\"SaveFile.w3z\",\"LoadFile.w3z\",UseSkipOptionSkip\n_SaveAndLoadGameBJ_Category=TC_GAME\n\nSaveAndChangeLevelBJ=1,anyfile,anyfile,useskipoption\n_SaveAndChangeLevelBJ_Defaults=\"SaveFile.w3z\",\"Maps\\MapName.w3x\",UseSkipOptionSkip\n_SaveAndChangeLevelBJ_Category=TC_GAME\n\nRenameSaveDirectoryBJ=1,anyfile,anyfile\n_RenameSaveDirectoryBJ_Defaults=_,_\n_RenameSaveDirectoryBJ_Category=TC_GAME\n\nRemoveSaveDirectoryBJ=1,anyfile\n_RemoveSaveDirectoryBJ_Defaults=_\n_RemoveSaveDirectoryBJ_Category=TC_GAME\n\nCopySaveGameBJ=1,anyfile,anyfile\n_CopySaveGameBJ_Defaults=_,_\n_CopySaveGameBJ_Category=TC_GAME\n\nSetCampaignMenuRaceBJ=0,campaignindex\n_SetCampaignMenuRaceBJ_Defaults=CampaignIndexH\n_SetCampaignMenuRaceBJ_Category=TC_GAME\n\nSetMissionAvailableBJ=0,enabledisableoption,missionindex\n_SetMissionAvailableBJ_Defaults=EnableDisableEnable,MissionIndexH01\n_SetMissionAvailableBJ_Category=TC_GAME\n\nSetCampaignAvailableBJ=0,enabledisableoption,campaignindex\n_SetCampaignAvailableBJ_Defaults=EnableDisableEnable,CampaignIndexH\n_SetCampaignAvailableBJ_Category=TC_GAME\n\nSetCinematicAvailableBJ=0,enabledisableoption,cinematicindex\n_SetCinematicAvailableBJ_Defaults=EnableDisableEnable,CinematicIndexHED\n_SetCinematicAvailableBJ_Category=TC_GAME\n\nShowCustomCampaignButton=1,showhideoption,integer\n_ShowCustomCampaignButton_Defaults=ShowHideShow,1\n_ShowCustomCampaignButton_Limits=_,_,1,_\n_ShowCustomCampaignButton_Category=TC_GAME\n\nSetAllyColorFilterState=1,integer\n_SetAllyColorFilterState_Defaults=0\n_SetAllyColorFilterState_Limits=0,2\n_SetAllyColorFilterState_Category=TC_GAME\n\nSetCreepCampFilterState=1,showhideoption\n_SetCreepCampFilterState_Defaults=ShowHideHide\n_SetCreepCampFilterState_Category=TC_GAME\n\nEnableMinimapFilterButtons=1,enabledisableoption,enabledisableoption\n_EnableMinimapFilterButtons_Defaults=EnableDisableDisable,EnableDisableDisable\n_EnableMinimapFilterButtons_Category=TC_GAME\n\nEnableSelect=1,enabledisableoption,enabledisableoption\n_EnableSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnableSelect_Category=TC_GAME\n\nEnableDragSelect=1,enabledisableoption,enabledisableoption\n_EnableDragSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnableDragSelect_Category=TC_GAME\n\nEnablePreSelect=1,enabledisableoption,enabledisableoption\n_EnablePreSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnablePreSelect_Category=TC_GAME\n\nForceUIKeyBJ=0,player,string\n_ForceUIKeyBJ_Defaults=Player00,\"A\"\n_ForceUIKeyBJ_Category=TC_GAME\n\nForceUICancelBJ=0,player\n_ForceUICancelBJ_Defaults=Player00\n_ForceUICancelBJ_Category=TC_GAME\n\nPreload=0,anyfile\n_Preload_Defaults=_\n_Preload_Category=TC_GAME\n\nPreloadEnd=0,real\n_PreloadEnd_Defaults=0.5\n_PreloadEnd_Category=TC_GAME\n\nPreloader=0,preloadfile\n_Preloader_Defaults=\n_Preloader_Category=TC_GAME\n\n\n// Game Cache actions\nInitGameCacheBJ=0,string\n_InitGameCacheBJ_Defaults=\"MapName.w3v\"\n_InitGameCacheBJ_Category=TC_GAMECACHE\n\nSaveGameCacheBJ=0,gamecache\n_SaveGameCacheBJ_Defaults=GetLastCreatedGameCacheBJ\n_SaveGameCacheBJ_Category=TC_GAMECACHE\n\nStoreUnitBJ=0,unit,string,string,gamecache\n_StoreUnitBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreUnitBJ_Category=TC_GAMECACHE\n\nStoreRealBJ=0,real,string,string,gamecache\n_StoreRealBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreRealBJ_Category=TC_GAMECACHE\n\nStoreIntegerBJ=0,integer,string,string,gamecache\n_StoreIntegerBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreIntegerBJ_Category=TC_GAMECACHE\n\nStoreBooleanBJ=0,boolean,string,string,gamecache\n_StoreBooleanBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreBooleanBJ_Category=TC_GAMECACHE\n\nStoreStringBJ=1,string,string,string,gamecache\n_StoreStringBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreStringBJ_Category=TC_GAMECACHE\n\n// Hashtable actions\nInitHashtableBJ=0\n_InitHashtableBJ_Defaults=\n_InitHashtableBJ_Category=TC_HASHTABLE\n\nSaveRealBJ=0,real,integer,integer,hashtable\n_SaveRealBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveRealBJ_Category=TC_HASHTABLE\n\nSaveIntegerBJ=0,integer,integer,integer,hashtable\n_SaveIntegerBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveIntegerBJ_Category=TC_HASHTABLE\n\nSaveBooleanBJ=0,boolean,integer,integer,hashtable\n_SaveBooleanBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveBooleanBJ_Category=TC_HASHTABLE\n\nSaveStringBJ=1,string,integer,integer,hashtable\n_SaveStringBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveStringBJ_Category=TC_HASHTABLE\n\nSavePlayerHandleBJ=0,player,integer,integer,hashtable\n_SavePlayerHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SavePlayerHandleBJ_Category=TC_HASHTABLE\n\nSaveWidgetHandleBJ=0,widget,integer,integer,hashtable\n_SaveWidgetHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveWidgetHandleBJ_Category=TC_HASHTABLE\n\nSaveDestructableHandleBJ=0,destructable,integer,integer,hashtable\n_SaveDestructableHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveDestructableHandleBJ_Category=TC_HASHTABLE\n\nSaveItemHandleBJ=0,item,integer,integer,hashtable\n_SaveItemHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveItemHandleBJ_Category=TC_HASHTABLE\n\nSaveUnitHandleBJ=0,unit,integer,integer,hashtable\n_SaveUnitHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveUnitHandleBJ_Category=TC_HASHTABLE\n\nSaveAbilityHandleBJ=0,ability,integer,integer,hashtable\n_SaveAbilityHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveAbilityHandleBJ_Category=TC_HASHTABLE\n\nSaveTimerHandleBJ=0,timer,integer,integer,hashtable\n_SaveTimerHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTimerHandleBJ_Category=TC_HASHTABLE\n\n//SaveTriggerRegionHandleBJ=0,region,integer,integer,hashtable\n//_SaveTriggerRegionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveTriggerRegionHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerHandleBJ=0,trigger,integer,integer,hashtable\n_SaveTriggerHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerConditionHandleBJ=0,triggercondition,integer,integer,hashtable\n_SaveTriggerConditionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerConditionHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerActionHandleBJ=0,triggeraction,integer,integer,hashtable\n_SaveTriggerActionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerActionHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerEventHandleBJ=0,eventid,integer,integer,hashtable\n_SaveTriggerEventHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerEventHandleBJ_Category=TC_HASHTABLE\n\nSaveForceHandleBJ=0,force,integer,integer,hashtable\n_SaveForceHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveForceHandleBJ_Category=TC_HASHTABLE\n\nSaveGroupHandleBJ=0,group,integer,integer,hashtable\n_SaveGroupHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveGroupHandleBJ_Category=TC_HASHTABLE\n\nSaveLocationHandleBJ=0,location,integer,integer,hashtable\n_SaveLocationHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveLocationHandleBJ_Category=TC_HASHTABLE\n\nSaveRegionHandleBJ=0,region,integer,integer,hashtable\n_SaveRegionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveRegionHandleBJ_Category=TC_HASHTABLE\n\nSaveRectHandleBJ=0,rect,integer,integer,hashtable\n_SaveRectHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveRectHandleBJ_Category=TC_HASHTABLE\n\nSaveBooleanExprHandleBJ=0,boolexpr,integer,integer,hashtable\n_SaveBooleanExprHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveBooleanExprHandleBJ_Category=TC_HASHTABLE\n\n//SaveConditionFuncHandleBJ=0,conditionfunc,integer,integer,hashtable\n//_SaveConditionFuncHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveConditionFuncHandleBJ_Category=TC_HASHTABLE\n\n//SaveFilterFuncHandleBJ=0,filterfunc,integer,integer,hashtable\n//_SaveFilterFuncHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveFilterFuncHandleBJ_Category=TC_HASHTABLE\n\nSaveSoundHandleBJ=0,sound,integer,integer,hashtable\n_SaveSoundHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveSoundHandleBJ_Category=TC_HASHTABLE\n\n//SaveRaceHandleBJ=0,race,integer,integer,hashtable\n//_SaveRaceHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveRaceHandleBJ_Category=TC_HASHTABLE\n\nSaveEffectHandleBJ=0,effect,integer,integer,hashtable\n_SaveEffectHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveEffectHandleBJ_Category=TC_HASHTABLE\n\nSaveUnitPoolHandleBJ=0,unitpool,integer,integer,hashtable\n_SaveUnitPoolHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveUnitPoolHandleBJ_Category=TC_HASHTABLE\n\nSaveItemPoolHandleBJ=0,itempool,integer,integer,hashtable\n_SaveItemPoolHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveItemPoolHandleBJ_Category=TC_HASHTABLE\n\nSaveQuestHandleBJ=0,quest,integer,integer,hashtable\n_SaveQuestHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveQuestHandleBJ_Category=TC_HASHTABLE\n\nSaveQuestItemHandleBJ=0,questitem,integer,integer,hashtable\n_SaveQuestItemHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveQuestItemHandleBJ_Category=TC_HASHTABLE\n\nSaveDefeatConditionHandleBJ=0,defeatcondition,integer,integer,hashtable\n_SaveDefeatConditionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveDefeatConditionHandleBJ_Category=TC_HASHTABLE\n\nSaveTimerDialogHandleBJ=0,timerdialog,integer,integer,hashtable\n_SaveTimerDialogHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTimerDialogHandleBJ_Category=TC_HASHTABLE\n\nSaveLeaderboardHandleBJ=0,leaderboard,integer,integer,hashtable\n_SaveLeaderboardHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveLeaderboardHandleBJ_Category=TC_HASHTABLE\n\nSaveMultiboardHandleBJ=0,multiboard,integer,integer,hashtable\n_SaveMultiboardHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveMultiboardHandleBJ_Category=TC_HASHTABLE\n\nSaveMultiboardItemHandleBJ=0,multiboarditem,integer,integer,hashtable\n_SaveMultiboardItemHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveMultiboardItemHandleBJ_Category=TC_HASHTABLE\n\nSaveTrackableHandleBJ=0,trackable,integer,integer,hashtable\n_SaveTrackableHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTrackableHandleBJ_Category=TC_HASHTABLE\n\nSaveGameCacheHandleBJ=0,gamecache,integer,integer,hashtable\n_SaveGameCacheHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveGameCacheHandleBJ_Category=TC_HASHTABLE\n\nSaveDialogHandleBJ=0,dialog,integer,integer,hashtable\n_SaveDialogHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveDialogHandleBJ_Category=TC_HASHTABLE\n\nSaveButtonHandleBJ=0,button,integer,integer,hashtable\n_SaveButtonHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveButtonHandleBJ_Category=TC_HASHTABLE\n\n//SaveVersionHandleBJ=0,version,integer,integer,hashtable\n//_SaveVersionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveVersionHandleBJ_Category=TC_HASHTABLE\n\n//SaveItemTypeHandleBJ=0,itemtype,integer,integer,hashtable\n//_SaveItemTypeHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveItemTypeHandleBJ_Category=TC_HASHTABLE\n\nSaveTextTagHandleBJ=0,texttag,integer,integer,hashtable\n_SaveTextTagHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTextTagHandleBJ_Category=TC_HASHTABLE\n\nSaveLightningHandleBJ=0,lightning,integer,integer,hashtable\n_SaveLightningHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveLightningHandleBJ_Category=TC_HASHTABLE\n\nSaveImageHandleBJ=0,image,integer,integer,hashtable\n_SaveImageHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveImageHandleBJ_Category=TC_HASHTABLE\n\nSaveUbersplatHandleBJ=0,ubersplat,integer,integer,hashtable\n_SaveUbersplatHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveUbersplatHandleBJ_Category=TC_HASHTABLE\n\nSaveFogStateHandleBJ=0,fogstate,integer,integer,hashtable\n_SaveFogStateHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveFogStateHandleBJ_Category=TC_HASHTABLE\n\nSaveFogModifierHandleBJ=0,fogmodifier,integer,integer,hashtable\n_SaveFogModifierHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveFogModifierHandleBJ_Category=TC_HASHTABLE\n\nRestoreUnitLocFacingAngleBJ=0,string,string,gamecache,player,location,real\n_RestoreUnitLocFacingAngleBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ,Player00,GetRectCenter,0\n_RestoreUnitLocFacingAngleBJ_Category=TC_GAMECACHE\n\nRestoreUnitLocFacingPointBJ=0,string,string,gamecache,player,location,location\n_RestoreUnitLocFacingPointBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ,Player00,GetRectCenter,GetUnitLoc\n_RestoreUnitLocFacingPointBJ_Category=TC_GAMECACHE\n\nReloadGameCachesFromDisk=1,nothing\n_ReloadGameCachesFromDisk_Defaults=\n_ReloadGameCachesFromDisk_Category=TC_GAMECACHE\n\nFlushGameCacheBJ=1,gamecache\n_FlushGameCacheBJ_Defaults=GetLastCreatedGameCacheBJ\n_FlushGameCacheBJ_Category=TC_GAMECACHE\n\nFlushStoredMissionBJ=1,string,gamecache\n_FlushStoredMissionBJ_Defaults=\"Category\",GetLastCreatedGameCacheBJ\n_FlushStoredMissionBJ_Category=TC_GAMECACHE\n\nFlushParentHashtableBJ=1,hashtable\n_FlushParentHashtableBJ_Defaults=GetLastCreatedHashtableBJ\n_FlushParentHashtableBJ_Category=TC_HASHTABLE\n\nFlushChildHashtableBJ=1,integer,hashtable\n_FlushChildHashtableBJ_Defaults=_,GetLastCreatedHashtableBJ\n_FlushChildHashtableBJ_Category=TC_HASHTABLE\n\n\n// Hero actions\nSelectHeroSkill=0,unit,heroskillcode\n_SelectHeroSkill_Defaults=GetTriggerUnit,HeroSkillBlizzard\n_SelectHeroSkill_Category=TC_HERO\n\nSetHeroLevel=0,unit,integer,showhideoption\n_SetHeroLevel_Defaults=GetTriggerUnit,2,ShowHideHide\n_SetHeroLevel_Limits=_,_,1,_,_,_\n_SetHeroLevel_Category=TC_HERO\n_SetHeroLevel_ScriptName=SetHeroLevelBJ\n\nSetHeroXP=0,unit,integer,showhideoption\n_SetHeroXP_Defaults=GetTriggerUnit,4000,ShowHideHide\n_SetHeroXP_Limits=_,_,0,_,_,_\n_SetHeroXP_Category=TC_HERO\n\nAddHeroXPSwapped=0,integer,unit,showhideoption\n_AddHeroXPSwapped_Defaults=1000,GetTriggerUnit,ShowHideHide\n_AddHeroXPSwapped_Category=TC_HERO\n\nSuspendHeroXPBJ=0,enabledisableoption,unit\n_SuspendHeroXPBJ_Defaults=EnableDisableDisable,GetTriggerUnit\n_SuspendHeroXPBJ_Category=TC_HERO\n\nSetPlayerHandicapXPBJ=0,player,real\n_SetPlayerHandicapXPBJ_Defaults=Player00,100\n_SetPlayerHandicapXPBJ_Limits=_,_,0,_\n_SetPlayerHandicapXPBJ_Category=TC_HERO\n\nReviveHeroLoc=0,unit,location,showhideoption\n_ReviveHeroLoc_Defaults=_,GetRectCenter,ShowHideHide\n_ReviveHeroLoc_Category=TC_HERO\n\nModifyHeroStat=1,herostat,unit,modifymethod,integer\n_ModifyHeroStat_Defaults=HeroStatStr,_,ModifyMethodAdd,10\n_ModifyHeroStat_Category=TC_HERO\n\nModifyHeroSkillPoints=1,unit,modifymethod,integer\n_ModifyHeroSkillPoints_Defaults=_,ModifyMethodAdd,1\n_ModifyHeroSkillPoints_Category=TC_HERO\n\nSetReservedLocalHeroButtons=1,integer\n_SetReservedLocalHeroButtons_Defaults=3\n_SetReservedLocalHeroButtons_Limits=0,6\n_SetReservedLocalHeroButtons_Category=TC_HERO\n\nUnitAddItemSwapped=0,item,unit\n_UnitAddItemSwapped_Defaults=GetLastCreatedItem,GetTriggerUnit\n_UnitAddItemSwapped_Category=TC_HERO\n\nUnitAddItemByIdSwapped=0,itemcode,unit\n_UnitAddItemByIdSwapped_Defaults=texp,GetTriggerUnit\n_UnitAddItemByIdSwapped_Category=TC_HERO\n\nUnitRemoveItemSwapped=0,item,unit\n_UnitRemoveItemSwapped_Defaults=_,_\n_UnitRemoveItemSwapped_Category=TC_HERO\n\nUnitRemoveItemFromSlotSwapped=0,integer,unit\n_UnitRemoveItemFromSlotSwapped_Defaults=1,_\n_UnitRemoveItemFromSlotSwapped_Limits=1,6,_,_\n_UnitRemoveItemFromSlotSwapped_Category=TC_HERO\n\nUnitUseItemTarget=0,unit,item,unit\n_UnitUseItemTarget_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemTarget_Category=TC_HERO\n\nUnitUseItemPointLoc=0,unit,item,location\n_UnitUseItemPointLoc_Defaults=_,GetLastCreatedItem,GetRectCenter\n_UnitUseItemPointLoc_Category=TC_HERO\n\nUnitUseItemDestructable=0,unit,item,destructable\n_UnitUseItemDestructable_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemDestructable_Category=TC_HERO\n\nUnitUseItem=0,unit,item\n_UnitUseItem_Defaults=_,GetLastCreatedItem\n_UnitUseItem_Category=TC_HERO\n\n\n// Item actions\nCreateItemLoc=0,itemcode,location\n_CreateItemLoc_Defaults=texp,GetRectCenter\n_CreateItemLoc_Category=TC_ITEM\n\nRemoveItem=0,item\n_RemoveItem_Defaults=GetLastCreatedItem\n_RemoveItem_Category=TC_ITEM\n\nSetItemVisibleBJ=1,showhideoption,item\n_SetItemVisibleBJ_Defaults=ShowHideHide,GetLastCreatedItem\n_SetItemVisibleBJ_Category=TC_ITEM\n\nSetItemPositionLoc=0,item,location\n_SetItemPositionLoc_Defaults=GetLastCreatedItem,GetRectCenter\n_SetItemPositionLoc_Category=TC_ITEM\n\nSetItemLifeBJ=0,item,real\n_SetItemLifeBJ_Defaults=GetLastCreatedItem,50\n_SetItemLifeBJ_Limits=_,_,0,_\n_SetItemLifeBJ_Category=TC_ITEM\n\nSetItemCharges=1,item,integer\n_SetItemCharges_Defaults=GetLastCreatedItem,1\n_SetItemCharges_Limits=_,_,0,_\n_SetItemCharges_Category=TC_ITEM\n\nSetItemInvulnerableBJ=0,item,invulnerableoption\n_SetItemInvulnerableBJ_Defaults=GetLastCreatedItem,InvulnerabilityInvulnerable\n_SetItemInvulnerableBJ_Category=TC_ITEM\n\nSetItemPawnable=1,item,pawnableoption\n_SetItemPawnable_Defaults=GetLastCreatedItem,PawnableOptionPawnable\n_SetItemPawnable_Category=TC_ITEM\n\nSetItemDroppableBJ=0,item,dropnodropoption\n_SetItemDroppableBJ_Defaults=GetLastCreatedItem,DropNoDropOptionNoDrop\n_SetItemDroppableBJ_Category=TC_ITEM\n\nSetItemDropOnDeathBJ=0,item,droppableoption\n_SetItemDropOnDeathBJ_Defaults=GetLastCreatedItem,DroppableOptionDrop\n_SetItemDropOnDeathBJ_Category=TC_ITEM\n\nSetItemPlayerBJ=0,item,player,colorchangeoption\n_SetItemPlayerBJ_Defaults=GetLastCreatedItem,Player00,ChangeColorTrue\n_SetItemPlayerBJ_Category=TC_ITEM\n\nSetItemUserData=1,item,integer\n_SetItemUserData_Defaults=_,0\n_SetItemUserData_Category=TC_ITEM\n\nEnumItemsInRectBJMultiple=1,rect\n_EnumItemsInRectBJMultiple_Defaults=GetPlayableMapRect\n_EnumItemsInRectBJMultiple_Category=TC_ITEM\n_EnumItemsInRectBJMultiple_ScriptName=EnumItemsInRectBJ\n\nEnumItemsInRectBJ=1,rect,code\n_EnumItemsInRectBJ_Defaults=GetPlayableMapRect,DoNothing\n_EnumItemsInRectBJ_Category=TC_ITEM\n\n\n// Image actions\nCreateImageBJ=1,string,real,location,real,imagetype\n_CreateImageBJ_Defaults=\"ReplaceableTextures\\Splats\\AuraRune9b.blp\",256,GetRectCenter,0,ImageTypeIndicator\n_CreateImageBJ_Category=TC_IMAGE\n\nDestroyImage=1,image\n_DestroyImage_Defaults=GetLastCreatedImage\n_DestroyImage_Category=TC_IMAGE\n\nShowImageBJ=1,showhideoption,image\n_ShowImageBJ_Defaults=ShowHideShow,GetLastCreatedImage\n_ShowImageBJ_Category=TC_IMAGE\n\nSetImageConstantHeight=1,image,enabledisableoption,real\n_SetImageConstantHeight_Defaults=GetLastCreatedImage,EnableDisableEnable,0\n_SetImageConstantHeight_Category=TC_IMAGE\n\nSetImagePositionBJ=1,image,location,real\n_SetImagePositionBJ_Defaults=GetLastCreatedImage,GetRectCenter,0\n_SetImagePositionBJ_Category=TC_IMAGE\n\nSetImageColorBJ=1,image,real,real,real,real\n_SetImageColorBJ_Defaults=GetLastCreatedImage,100,100,100,0\n_SetImageColorBJ_Category=TC_IMAGE\n\nSetImageRender=1,image,enabledisableoption\n_SetImageRender_Defaults=GetLastCreatedImage,EnableDisableEnable\n_SetImageRender_Category=TC_IMAGE\n\nSetImageRenderAlways=1,image,enabledisableoption\n_SetImageRenderAlways_Defaults=GetLastCreatedImage,EnableDisableEnable\n_SetImageRenderAlways_Category=TC_IMAGE\n\nSetImageAboveWater=1,image,enabledisableoption,enabledisableoption\n_SetImageAboveWater_Defaults=GetLastCreatedImage,EnableDisableEnable,EnableDisableEnable\n_SetImageAboveWater_Category=TC_IMAGE\n\nSetImageType=1,image,imagetype\n_SetImageType_Defaults=GetLastCreatedImage,ImageTypeIndicator\n_SetImageType_Category=TC_IMAGE\n\n\n// Leaderboard actions\nCreateLeaderboardBJ=0,force,StringExt\n_CreateLeaderboardBJ_Defaults=GetPlayersAll,_\n_CreateLeaderboardBJ_Category=TC_LEADERBOARD\n\nDestroyLeaderboardBJ=0,leaderboard\n_DestroyLeaderboardBJ_Defaults=GetLastCreatedLeaderboard\n_DestroyLeaderboardBJ_Category=TC_LEADERBOARD\n\nLeaderboardSortItemsBJ=0,leaderboard,leaderboardsortoption,ascendingoption\n_LeaderboardSortItemsBJ_Defaults=GetLastCreatedLeaderboard,LeaderboardSortByValue,AscendingOptionDescending\n_LeaderboardSortItemsBJ_Category=TC_LEADERBOARD\n\nLeaderboardDisplayBJ=0,showhideoption,leaderboard\n_LeaderboardDisplayBJ_Defaults=ShowHideHide,GetLastCreatedLeaderboard\n_LeaderboardDisplayBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetLabelBJ=0,leaderboard,StringExt\n_LeaderboardSetLabelBJ_Defaults=GetLastCreatedLeaderboard,_\n_LeaderboardSetLabelBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetLabelColorBJ=0,leaderboard,real,real,real,real\n_LeaderboardSetLabelColorBJ_Defaults=GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetLabelColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetLabelColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetValueColorBJ=0,leaderboard,real,real,real,real\n_LeaderboardSetValueColorBJ_Defaults=GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetValueColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetValueColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetStyleBJ=0,leaderboard,showhideoption,showhideoption,showhideoption,showhideoption\n_LeaderboardSetStyleBJ_Defaults=GetLastCreatedLeaderboard,ShowHideShow,ShowHideShow,ShowHideShow,ShowHideShow\n_LeaderboardSetStyleBJ_Category=TC_LEADERBOARD\n\nLeaderboardAddItemBJ=0,player,leaderboard,StringExt,integer\n_LeaderboardAddItemBJ_Defaults=Player00,GetLastCreatedLeaderboard,_,0\n_LeaderboardAddItemBJ_Category=TC_LEADERBOARD\n\nLeaderboardRemovePlayerItemBJ=0,player,leaderboard\n_LeaderboardRemovePlayerItemBJ_Defaults=Player00,GetLastCreatedLeaderboard\n_LeaderboardRemovePlayerItemBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemLabelBJ=0,player,leaderboard,StringExt\n_LeaderboardSetPlayerItemLabelBJ_Defaults=Player00,GetLastCreatedLeaderboard,_\n_LeaderboardSetPlayerItemLabelBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemLabelColorBJ=0,player,leaderboard,real,real,real,real\n_LeaderboardSetPlayerItemLabelColorBJ_Defaults=Player00,GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetPlayerItemLabelColorBJ_Limits=_,_,_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetPlayerItemLabelColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemValueBJ=0,player,leaderboard,integer\n_LeaderboardSetPlayerItemValueBJ_Defaults=Player00,GetLastCreatedLeaderboard,0\n_LeaderboardSetPlayerItemValueBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemValueColorBJ=0,player,leaderboard,real,real,real,real\n_LeaderboardSetPlayerItemValueColorBJ_Defaults=Player00,GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetPlayerItemValueColorBJ_Limits=_,_,_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetPlayerItemValueColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemStyleBJ=0,player,leaderboard,showhideoption,showhideoption,showhideoption\n_LeaderboardSetPlayerItemStyleBJ_Defaults=Player00,GetLastCreatedLeaderboard,ShowHideShow,ShowHideShow,ShowHideShow\n_LeaderboardSetPlayerItemStyleBJ_Category=TC_LEADERBOARD\n\n\n// Lightning actions\nAddLightningLoc=1,lightningtype,location,location\n_AddLightningLoc_Defaults=LightningTypeCLPB,GetUnitLoc,GetRectCenter\n_AddLightningLoc_Category=TC_LIGHTNING\n\nDestroyLightningBJ=1,lightning\n_DestroyLightningBJ_Defaults=GetLastCreatedLightningBJ\n_DestroyLightningBJ_Category=TC_LIGHTNING\n\nMoveLightningLoc=1,lightning,location,location\n_MoveLightningLoc_Defaults=GetLastCreatedLightningBJ,GetUnitLoc,GetRectCenter\n_MoveLightningLoc_Category=TC_LIGHTNING\n\nSetLightningColorBJ=1,lightning,real,real,real,real\n_SetLightningColorBJ_Defaults=GetLastCreatedLightningBJ,1,1,1,1\n_SetLightningColorBJ_Category=TC_LIGHTNING\n\n\n// Melee Game actions\nMeleeStartingVisibility=0,nothing\n_MeleeStartingVisibility_Defaults=\n_MeleeStartingVisibility_Category=TC_MELEE\n\nMeleeStartingHeroLimit=0,nothing\n_MeleeStartingHeroLimit_Defaults=\n_MeleeStartingHeroLimit_Category=TC_MELEE\n\nMeleeGrantHeroItems=0,nothing\n_MeleeGrantHeroItems_Defaults=\n_MeleeGrantHeroItems_Category=TC_MELEE\n\nMeleeStartingResources=0,nothing\n_MeleeStartingResources_Defaults=\n_MeleeStartingResources_Category=TC_MELEE\n\nMeleeClearExcessUnits=0,nothing\n_MeleeClearExcessUnits_Defaults=\n_MeleeClearExcessUnits_Category=TC_MELEE\n\nMeleeStartingUnits=0,nothing\n_MeleeStartingUnits_Defaults=\n_MeleeStartingUnits_Category=TC_MELEE\n\nMeleeStartingAI=0,nothing\n_MeleeStartingAI_Defaults=\n_MeleeStartingAI_Category=TC_MELEE\n\nMeleeInitVictoryDefeat=0,nothing\n_MeleeInitVictoryDefeat_Defaults=\n_MeleeInitVictoryDefeat_Category=TC_MELEE\n\nMeleeStartingUnitsForPlayer=1,race,player,location,includeoption\n_MeleeStartingUnitsForPlayer_Defaults=RaceHuman,Player00,GetPlayerStartLocationLoc,InclusionInclude\n_MeleeStartingUnitsForPlayer_Category=TC_MELEE\n\n\n// Multiboard actions\nCreateMultiboardBJ=1,integer,integer,StringExt\n_CreateMultiboardBJ_Defaults=1,1,_\n_CreateMultiboardBJ_Limits=1,28,1,32,_,512\n_CreateMultiboardBJ_Category=TC_MULTIBOARD\n\nDestroyMultiboardBJ=1,multiboard\n_DestroyMultiboardBJ_Defaults=GetLastCreatedMultiboard\n_DestroyMultiboardBJ_Category=TC_MULTIBOARD\n\nMultiboardDisplayBJ=1,showhideoption,multiboard\n_MultiboardDisplayBJ_Defaults=ShowHideHide,GetLastCreatedMultiboard\n_MultiboardDisplayBJ_Category=TC_MULTIBOARD\n\nMultiboardAllowDisplayBJ=1,showhideoption\n_MultiboardAllowDisplayBJ_Defaults=ShowHideHide\n_MultiboardAllowDisplayBJ_Category=TC_MULTIBOARD\n\nMultiboardMinimizeBJ=1,minimizeoption,multiboard\n_MultiboardMinimizeBJ_Defaults=Minimize,GetLastCreatedMultiboard\n_MultiboardMinimizeBJ_Category=TC_MULTIBOARD\n\nMultiboardClear=1,multiboard\n_MultiboardClear_Defaults=GetLastCreatedMultiboard\n_MultiboardClear_Category=TC_MULTIBOARD\n\nMultiboardSetTitleText=1,multiboard,StringExt\n_MultiboardSetTitleText_Defaults=GetLastCreatedMultiboard,_\n_MultiboardSetTitleText_Limits=_,_,_,512\n_MultiboardSetTitleText_Category=TC_MULTIBOARD\n\nMultiboardSetTitleTextColorBJ=1,multiboard,real,real,real,real\n_MultiboardSetTitleTextColorBJ_Defaults=GetLastCreatedMultiboard,100,80,20,0\n_MultiboardSetTitleTextColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_MultiboardSetTitleTextColorBJ_Category=TC_MULTIBOARD\n\nMultiboardSetRowCount=1,multiboard,integer\n_MultiboardSetRowCount_Defaults=GetLastCreatedMultiboard,1\n_MultiboardSetRowCount_Limits=_,_,1,32\n_MultiboardSetRowCount_Category=TC_MULTIBOARD\n\nMultiboardSetColumnCount=1,multiboard,integer\n_MultiboardSetColumnCount_Defaults=GetLastCreatedMultiboard,1\n_MultiboardSetColumnCount_Limits=_,_,1,28\n_MultiboardSetColumnCount_Category=TC_MULTIBOARD\n\nMultiboardSetItemStyleBJ=1,multiboard,integer,integer,showhideoption,showhideoption\n_MultiboardSetItemStyleBJ_Defaults=GetLastCreatedMultiboard,1,1,ShowHideShow,ShowHideShow\n_MultiboardSetItemStyleBJ_Limits=_,_,0,_,0,_,_,_,_,_\n_MultiboardSetItemStyleBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemValueBJ=1,multiboard,integer,integer,StringExt\n_MultiboardSetItemValueBJ_Defaults=GetLastCreatedMultiboard,1,1,_\n_MultiboardSetItemValueBJ_Limits=_,_,0,_,0,_,_,128\n_MultiboardSetItemValueBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemColorBJ=1,multiboard,integer,integer,real,real,real,real\n_MultiboardSetItemColorBJ_Defaults=GetLastCreatedMultiboard,1,1,100,80,20,0\n_MultiboardSetItemColorBJ_Limits=_,_,0,_,0,_,0,100,0,100,0,100,0,100\n_MultiboardSetItemColorBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemWidthBJ=1,multiboard,integer,integer,real\n_MultiboardSetItemWidthBJ_Defaults=GetLastCreatedMultiboard,1,1,3\n_MultiboardSetItemWidthBJ_Limits=_,_,0,_,0,_,0,100\n_MultiboardSetItemWidthBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemIconBJ=1,multiboard,integer,integer,imagefile\n_MultiboardSetItemIconBJ_Defaults=GetLastCreatedMultiboard,1,1,\"UI\\Feedback\\Resources\\ResourceGold.blp\"\n_MultiboardSetItemIconBJ_Limits=_,_,0,_,0,_,_,_\n_MultiboardSetItemIconBJ_Category=TC_MULTIBOARD\n\n\n// Neutral Building actions\nAddResourceAmountBJ=0,integer,unit\n_AddResourceAmountBJ_Defaults=5000,_\n_AddResourceAmountBJ_Category=TC_NEUTRALBUILDING\n\nSetResourceAmount=0,unit,integer\n_SetResourceAmount_Defaults=_,12500\n_SetResourceAmount_Limits=_,_,0,_\n_SetResourceAmount_Category=TC_NEUTRALBUILDING\n\nBlightGoldMineForPlayer=0,unit,player\n_BlightGoldMineForPlayer_Defaults=_,Player00\n_BlightGoldMineForPlayer_Category=TC_NEUTRALBUILDING\n\nWaygateActivateBJ=0,enabledisableoption,unit\n_WaygateActivateBJ_Defaults=EnableDisableEnable,_\n_WaygateActivateBJ_Category=TC_NEUTRALBUILDING\n\nWaygateSetDestinationLocBJ=0,unit,location\n_WaygateSetDestinationLocBJ_Defaults=_,GetRectCenter\n_WaygateSetDestinationLocBJ_Category=TC_NEUTRALBUILDING\n\nSetAltMinimapIcon=1,imagefile\n_SetAltMinimapIcon_Defaults=\"UI\\Minimap\\Minimap-Tower\"\n_SetAltMinimapIcon_Category=TC_NEUTRALBUILDING\n\nUnitSetUsesAltIconBJ=1,onoffoption,unit\n_UnitSetUsesAltIconBJ_Defaults=OnOffOn,_\n_UnitSetUsesAltIconBJ_Category=TC_NEUTRALBUILDING\n\nAddItemToStockBJ=1,itemcode,unit,integer,integer\n_AddItemToStockBJ_Defaults=texp,GetTriggerUnit,0,1\n_AddItemToStockBJ_Category=TC_NEUTRALBUILDING\n\nAddItemToAllStock=1,itemcode,integer,integer\n_AddItemToAllStock_Defaults=texp,0,1\n_AddItemToAllStock_Category=TC_NEUTRALBUILDING\n\nAddUnitToStockBJ=1,unitcode,unit,integer,integer\n_AddUnitToStockBJ_Defaults=hfoo,GetTriggerUnit,0,1\n_AddUnitToStockBJ_Category=TC_NEUTRALBUILDING\n\nAddUnitToAllStock=1,unitcode,integer,integer\n_AddUnitToAllStock_Defaults=hfoo,0,1\n_AddUnitToAllStock_Category=TC_NEUTRALBUILDING\n\nRemoveItemFromStockBJ=1,itemcode,unit\n_RemoveItemFromStockBJ_Defaults=texp,GetTriggerUnit\n_RemoveItemFromStockBJ_Category=TC_NEUTRALBUILDING\n\nRemoveItemFromAllStock=1,itemcode\n_RemoveItemFromAllStock_Defaults=texp\n_RemoveItemFromAllStock_Category=TC_NEUTRALBUILDING\n\nRemoveUnitFromStockBJ=1,unitcode,unit\n_RemoveUnitFromStockBJ_Defaults=hfoo,GetTriggerUnit\n_RemoveUnitFromStockBJ_Category=TC_NEUTRALBUILDING\n\nRemoveUnitFromAllStock=1,unitcode\n_RemoveUnitFromAllStock_Defaults=hfoo\n_RemoveUnitFromAllStock_Category=TC_NEUTRALBUILDING\n\nSetItemTypeSlots=1,unit,integer\n_SetItemTypeSlots_Defaults=GetTriggerUnit,6\n_SetItemTypeSlots_Category=TC_NEUTRALBUILDING\n\nSetAllItemTypeSlots=1,integer\n_SetAllItemTypeSlots_Defaults=6\n_SetAllItemTypeSlots_Category=TC_NEUTRALBUILDING\n\nSetUnitTypeSlots=1,unit,integer\n_SetUnitTypeSlots_Defaults=GetTriggerUnit,6\n_SetUnitTypeSlots_Category=TC_NEUTRALBUILDING\n\nSetAllUnitTypeSlots=1,integer\n_SetAllUnitTypeSlots_Defaults=6\n_SetAllUnitTypeSlots_Category=TC_NEUTRALBUILDING\n\n\n// Player actions\nSetPlayerState=0,player,playerstate,integer\n_SetPlayerState_Defaults=Player00,PlayerStateGold,750\n_SetPlayerState_Category=TC_PLAYER\n_SetPlayerState_ScriptName=SetPlayerStateBJ\n\nAdjustPlayerStateBJ=0,integer,player,playerstate\n_AdjustPlayerStateBJ_Defaults=1000,Player00,PlayerStateGold\n_AdjustPlayerStateBJ_Category=TC_PLAYER\n\nSetPlayerFlagBJ=0,playerflag,onoffoption,player\n_SetPlayerFlagBJ_Defaults=PlayerFlagGivesBounty,OnOffOff,PlayerNA\n_SetPlayerFlagBJ_Category=TC_PLAYER\n\nSetPlayerTaxRateBJ=1,integer,playerresource,player,player,\n_SetPlayerTaxRateBJ_Defaults=0,PlayerResourceGold,Player00,Player01\n_SetPlayerTaxRateBJ_Limits=0,100,_,_,_,_,_,_\n_SetPlayerTaxRateBJ_Category=TC_PLAYER\n\nEnableCreepSleepBJ=1,enabledisableoption\n_EnableCreepSleepBJ_Defaults=EnableDisableDisable\n_EnableCreepSleepBJ_Category=TC_PLAYER\n\nSetPlayerAllianceStateBJ=0,player,player,alliancesetting\n_SetPlayerAllianceStateBJ_Defaults=Player00,Player01,AllianceSettingAlliedVision\n_SetPlayerAllianceStateBJ_Category=TC_PLAYER\n\nSetPlayerAllianceBJ=0,player,alliancetype,onoffoption,player\n_SetPlayerAllianceBJ_Defaults=Player00,AllianceTypePassive,OnOffOn,Player01\n_SetPlayerAllianceBJ_Category=TC_PLAYER\n\nSetPlayerAbilityAvailableBJ=0,enabledisableoption,abilcode,player\n_SetPlayerAbilityAvailableBJ_Defaults=EnableDisableDisable,_,Player00\n_SetPlayerAbilityAvailableBJ_Category=TC_PLAYER\n\nSetPlayerUnitAvailableBJ=0,unitcode,availabilityoption,player\n_SetPlayerUnitAvailableBJ_Defaults=hfoo,AvailabilityOptionAvailable,Player00\n_SetPlayerUnitAvailableBJ_Category=TC_PLAYER\n\nSetPlayerUnitMaxAllowed=1,unitcode,integer,player\n_SetPlayerUnitMaxAllowed_Defaults=hfoo,1,Player00\n_SetPlayerUnitMaxAllowed_Limits=_,_,-1,_,_,_\n_SetPlayerUnitMaxAllowed_Category=TC_PLAYER\n_SetPlayerUnitMaxAllowed_ScriptName=SetPlayerTechMaxAllowedSwap\n\nSetPlayerMaxHeroesAllowed=1,integer,player\n_SetPlayerMaxHeroesAllowed_Defaults=3,Player00\n_SetPlayerMaxHeroesAllowed_Limits=-1,_,_,_\n_SetPlayerMaxHeroesAllowed_Category=TC_PLAYER\n\nSetPlayerTechResearchedSwap=0,techcode,integer,player\n_SetPlayerTechResearchedSwap_Defaults=_,0,Player00\n_SetPlayerTechResearchedSwap_Limits=_,_,0,_,_,_\n_SetPlayerTechResearchedSwap_Category=TC_PLAYER\n\nSetPlayerTechMaxAllowedSwap=0,techcode,integer,player\n_SetPlayerTechMaxAllowedSwap_Defaults=_,0,Player00\n_SetPlayerTechMaxAllowedSwap_Limits=_,_,0,_,_,_\n_SetPlayerTechMaxAllowedSwap_Category=TC_PLAYER\n\nSetPlayerColorBJ=0,player,playercolor,playerchangecoloroption\n_SetPlayerColorBJ_Defaults=Player00,Color00,PlayerChangeColorChange\n_SetPlayerColorBJ_Category=TC_PLAYER\n\nSetPlayerHandicapBJ=0,player,real\n_SetPlayerHandicapBJ_Defaults=Player00,100\n_SetPlayerHandicapBJ_Limits=_,_,1,10000\n_SetPlayerHandicapBJ_Category=TC_PLAYER\n\nSetPlayerOnScoreScreenBJ=0,showhideoption,player\n_SetPlayerOnScoreScreenBJ_Defaults=ShowHideHide,Player00\n_SetPlayerOnScoreScreenBJ_Category=TC_PLAYER\n\nSetPlayerName=1,player,StringExt\n_SetPlayerName_Defaults=Player00,_\n_SetPlayerName_Category=TC_PLAYER\n\n\n// Player Group actions\n// Specially handled by the editor\nForForceMultiple=1,force\n_ForForceMultiple_Defaults=GetPlayersAll\n_ForForceMultiple_Category=TC_PLAYERGROUP\n_ForForceMultiple_ScriptName=ForForce\n\nForForce=0,force,code\n_ForForce_Defaults=GetPlayersAll,DoNothing\n_ForForce_Category=TC_PLAYERGROUP\n\nForceAddPlayerSimple=0,player,force\n_ForceAddPlayerSimple_Defaults=Player00,_\n_ForceAddPlayerSimple_Category=TC_PLAYERGROUP\n\nForceRemovePlayerSimple=0,player,force\n_ForceRemovePlayerSimple_Defaults=Player00,_\n_ForceRemovePlayerSimple_Category=TC_PLAYERGROUP\n\nForceClear=0,force\n_ForceClear_Defaults=_\n_ForceClear_Category=TC_PLAYERGROUP\n\nSetForceAllianceStateBJ=1,force,force,alliancesetting\n_SetForceAllianceStateBJ_Defaults=GetPlayersAll,GetPlayersAll,AllianceSettingAlliedVision\n_SetForceAllianceStateBJ_Category=TC_PLAYERGROUP\n\n\n// Quest actions\nQuestMessageBJ=0,force,questmessagetype,StringExt\n_QuestMessageBJ_Defaults=GetPlayersAll,QuestMessageTypeUpdated,_\n_QuestMessageBJ_Category=TC_QUEST\n\nCreateQuestBJ=0,questtypeoption,StringExt,StringExt,imagefile\n_CreateQuestBJ_Defaults=QuestTypeReqDiscovered,_,_,\"ReplaceableTextures\\CommandButtons\\BTNAmbush.blp\"\n_CreateQuestBJ_Limits=_,_,_,24,_,_,_,_\n_CreateQuestBJ_Category=TC_QUEST\n\nDestroyQuestBJ=0,quest\n_DestroyQuestBJ_Defaults=GetLastCreatedQuestBJ\n_DestroyQuestBJ_Category=TC_QUEST\n\nQuestSetEnabledBJ=0,enabledisableoption,quest\n_QuestSetEnabledBJ_Defaults=EnableDisableDisable,GetLastCreatedQuestBJ\n_QuestSetEnabledBJ_Category=TC_QUEST\n\nQuestSetCompletedBJ=0,quest,completionoption\n_QuestSetCompletedBJ_Defaults=GetLastCreatedQuestBJ,CompletionOptionCompleted\n_QuestSetCompletedBJ_Category=TC_QUEST\n\nQuestSetFailedBJ=0,quest,failureoption\n_QuestSetFailedBJ_Defaults=GetLastCreatedQuestBJ,FailureOptionFailed\n_QuestSetFailedBJ_Category=TC_QUEST\n\nQuestSetDiscoveredBJ=0,quest,discoveredoption\n_QuestSetDiscoveredBJ_Defaults=GetLastCreatedQuestBJ,DiscoveredOptionDiscovered\n_QuestSetDiscoveredBJ_Category=TC_QUEST\n\nQuestSetTitleBJ=0,quest,StringExt\n_QuestSetTitleBJ_Defaults=GetLastCreatedQuestBJ,_\n_QuestSetTitleBJ_Category=TC_QUEST\n\nQuestSetDescriptionBJ=0,quest,StringExt\n_QuestSetDescriptionBJ_Defaults=GetLastCreatedQuestBJ,_\n_QuestSetDescriptionBJ_Category=TC_QUEST\n\nCreateQuestItemBJ=0,quest,StringExt\n_CreateQuestItemBJ_Defaults=GetLastCreatedQuestBJ,_\n_CreateQuestItemBJ_Category=TC_QUEST\n\nQuestItemSetCompletedBJ=0,questitem,completionoption\n_QuestItemSetCompletedBJ_Defaults=GetLastCreatedQuestItemBJ,CompletionOptionCompleted\n_QuestItemSetCompletedBJ_Category=TC_QUEST\n\nQuestItemSetDescriptionBJ=0,questitem,StringExt\n_QuestItemSetDescriptionBJ_Defaults=GetLastCreatedQuestItemBJ,_\n_QuestItemSetDescriptionBJ_Category=TC_QUEST\n\nCreateDefeatConditionBJ=0,StringExt\n_CreateDefeatConditionBJ_Defaults=_\n_CreateDefeatConditionBJ_Category=TC_QUEST\n\nDestroyDefeatConditionBJ=0,defeatcondition\n_DestroyDefeatConditionBJ_Defaults=GetLastCreatedDefeatConditionBJ\n_DestroyDefeatConditionBJ_Category=TC_QUEST\n\nDefeatConditionSetDescriptionBJ=0,defeatcondition,StringExt\n_DefeatConditionSetDescriptionBJ_Defaults=GetLastCreatedDefeatConditionBJ,_\n_DefeatConditionSetDescriptionBJ_Category=TC_QUEST\n\nFlashQuestDialogButtonBJ=0,nothing\n_FlashQuestDialogButtonBJ_Defaults=\n_FlashQuestDialogButtonBJ_Category=TC_QUEST\n\n\n// Region actions\nMoveRectToLoc=0,rect,location\n_MoveRectToLoc_Defaults=_,GetRectCenter\n_MoveRectToLoc_Category=TC_REGION\n\n\n// Selection actions\nClearSelectionForPlayer=1,player\n_ClearSelectionForPlayer_Defaults=Player00\n_ClearSelectionForPlayer_Category=TC_UNITSEL\n\nSelectGroupForPlayerBJ=1,group,player\n_SelectGroupForPlayerBJ_Defaults=_,Player00\n_SelectGroupForPlayerBJ_Category=TC_UNITSEL\n\nSelectUnitForPlayerSingle=1,unit,player\n_SelectUnitForPlayerSingle_Defaults=GetTriggerUnit,Player00\n_SelectUnitForPlayerSingle_Category=TC_UNITSEL\n\nSelectUnitAddForPlayer=1,unit,player\n_SelectUnitAddForPlayer_Defaults=GetTriggerUnit,Player00\n_SelectUnitAddForPlayer_Category=TC_UNITSEL\n\nSelectUnitRemoveForPlayer=1,unit,player\n_SelectUnitRemoveForPlayer_Defaults=GetTriggerUnit,Player00\n_SelectUnitRemoveForPlayer_Category=TC_UNITSEL\n\nClearSelection=0,nothing\n_ClearSelection_Defaults=\n_ClearSelection_Category=TC_UNITSEL\n\nSelectGroupBJ=0,group\n_SelectGroupBJ_Defaults=_\n_SelectGroupBJ_Category=TC_UNITSEL\n\nSelectUnitSingle=0,unit\n_SelectUnitSingle_Defaults=GetTriggerUnit\n_SelectUnitSingle_Category=TC_UNITSEL\n\nSelectUnitAdd=0,unit\n_SelectUnitAdd_Defaults=GetTriggerUnit\n_SelectUnitAdd_Category=TC_UNITSEL\n\nSelectUnitRemove=0,unit\n_SelectUnitRemove_Defaults=GetTriggerUnit\n_SelectUnitRemove_Category=TC_UNITSEL\n\n\n// Sound actions\nPlaySoundBJ=0,sound\n_PlaySoundBJ_Defaults=_\n_PlaySoundBJ_Category=TC_SOUND\n\nPlaySoundAtPointBJ=1,sound,real,location,real\n_PlaySoundAtPointBJ_Defaults=_,100,GetRectCenter,0\n_PlaySoundAtPointBJ_Limits=_,_,0,100,_,_,_,_\n_PlaySoundAtPointBJ_Category=TC_SOUND\n\nPlaySoundOnUnitBJ=1,sound,real,unit\n_PlaySoundOnUnitBJ_Defaults=_,100,_\n_PlaySoundOnUnitBJ_Limits=_,_,0,100,_,_\n_PlaySoundOnUnitBJ_Category=TC_SOUND\n\nPlaySoundFromOffsetBJ=1,sound,real,real\n_PlaySoundFromOffsetBJ_Defaults=_,100,0,0\n_PlaySoundFromOffsetBJ_Limits=_,_,0,100,0,_,0,_\n_PlaySoundFromOffsetBJ_Category=TC_SOUND\n\nStopSoundBJ=0,sound,fadedontoption\n_StopSoundBJ_Defaults=_,FadeDontFade\n_StopSoundBJ_Category=TC_SOUND\n\nKillSoundWhenDoneBJ=0,sound\n_KillSoundWhenDoneBJ_Defaults=_\n_KillSoundWhenDoneBJ_Category=TC_SOUND\n\nSetSoundVolumeBJ=0,sound,real\n_SetSoundVolumeBJ_Defaults=_,100\n_SetSoundVolumeBJ_Limits=_,_,0,100\n_SetSoundVolumeBJ_Category=TC_SOUND\n\nSetSoundOffsetBJ=1,real,sound\n_SetSoundOffsetBJ_Defaults=0,_\n_SetSoundOffsetBJ_Limits=0,_,_,_\n_SetSoundOffsetBJ_Category=TC_SOUND\n\nSetSoundDistanceCutoffBJ=0,sound,real\n_SetSoundDistanceCutoffBJ_Defaults=_,_\n_SetSoundDistanceCutoffBJ_Category=TC_SOUND\n\nSetSoundPitchBJ=0,sound,real\n_SetSoundPitchBJ_Defaults=_,_\n_SetSoundPitchBJ_Category=TC_SOUND\n\nAttachSoundToUnitBJ=0,sound,unit\n_AttachSoundToUnitBJ_Defaults=_,_\n_AttachSoundToUnitBJ_Category=TC_SOUND\n\nSetSoundPositionLocBJ=0,sound,location,real\n_SetSoundPositionLocBJ_Defaults=_,GetRectCenter,0\n_SetSoundPositionLocBJ_Category=TC_SOUND\n\nSetSoundDistances=0,sound,real,real\n_SetSoundDistances_Defaults=_,_,_\n_SetSoundDistances_Limits=_,_,0,_,0,_\n_SetSoundDistances_Category=TC_SOUND\n\nSetStackedSoundBJ=0,addremoveoption,sound,rect\n_SetStackedSoundBJ_Defaults=AddRemoveAdd,_,_\n_SetStackedSoundBJ_Category=TC_SOUND\n\nSetAmbientDaySound=0,ambientthemeday\n_SetAmbientDaySound_Defaults=AmbientThemeDayL\n_SetAmbientDaySound_Category=TC_SOUND\n\nSetAmbientNightSound=0,ambientthemenight\n_SetAmbientNightSound_Defaults=AmbientThemeNightL\n_SetAmbientNightSound_Category=TC_SOUND\n\nEnableDawnDusk=0,enabledisableoption\n_EnableDawnDusk_Defaults=EnableDisableEnable\n_EnableDawnDusk_Category=TC_SOUND\n\nSetMapMusicIndexedBJ=0,musicfile,integer\n_SetMapMusicIndexedBJ_Defaults=MusicFileMusic,0\n_SetMapMusicIndexedBJ_Category=TC_SOUND\n\nSetMapMusicRandomBJ=0,musicfile\n_SetMapMusicRandomBJ_Defaults=MusicFileMusic\n_SetMapMusicRandomBJ_Category=TC_SOUND\n\nClearMapMusicBJ=0,nothing\n_ClearMapMusicBJ_Defaults=\n_ClearMapMusicBJ_Category=TC_SOUND\n\nPlayMusicBJ=0,musicfile\n_PlayMusicBJ_Defaults=_\n_PlayMusicBJ_Category=TC_SOUND\n\nPlayMusicExBJ=1,musicfile,real,real\n_PlayMusicExBJ_Defaults=_,0,0\n_PlayMusicExBJ_Limits=_,_,0,_,0,_\n_PlayMusicExBJ_Category=TC_SOUND\n\nPlayThematicMusicBJ=0,musictheme\n_PlayThematicMusicBJ_Defaults=MusicThemeHeroicVictory\n_PlayThematicMusicBJ_Category=TC_SOUND\n\nPlayThematicMusicExBJ=1,musictheme,real\n_PlayThematicMusicExBJ_Defaults=MusicThemeHeroicVictory,0\n_PlayThematicMusicExBJ_Limits=_,_,0,_\n_PlayThematicMusicExBJ_Category=TC_SOUND\n\nEndThematicMusicBJ=0,nothing\n_EndThematicMusicBJ_Defaults=\n_EndThematicMusicBJ_Category=TC_SOUND\n\nStopMusicBJ=0,fadedontoption\n_StopMusicBJ_Defaults=FadeDontFade\n_StopMusicBJ_Category=TC_SOUND\n\nResumeMusicBJ=0,nothing\n_ResumeMusicBJ_Defaults=\n_ResumeMusicBJ_Category=TC_SOUND\n\nSetMusicVolumeBJ=0,real\n_SetMusicVolumeBJ_Defaults=100\n_SetMusicVolumeBJ_Limits=0,100\n_SetMusicVolumeBJ_Category=TC_SOUND\n\nSetMusicOffsetBJ=1,real\n_SetMusicOffsetBJ_Defaults=0\n_SetMusicOffsetBJ_Limits=0,_\n_SetMusicOffsetBJ_Category=TC_SOUND\n\nSetThematicMusicOffsetBJ=1,real\n_SetThematicMusicOffsetBJ_Defaults=0\n_SetThematicMusicOffsetBJ_Limits=0,_\n_SetThematicMusicOffsetBJ_Category=TC_SOUND\n\nVolumeGroupSetVolumeBJ=0,volumegroup,real\n_VolumeGroupSetVolumeBJ_Defaults=VolumeGroupMusic,100\n_VolumeGroupSetVolumeBJ_Limits=_,_,0,100\n_VolumeGroupSetVolumeBJ_Category=TC_SOUND\n\nSetCineModeVolumeGroupsBJ=0,nothing\n_SetCineModeVolumeGroupsBJ_Defaults=\n_SetCineModeVolumeGroupsBJ_Category=TC_SOUND\n\nSetSpeechVolumeGroupsBJ=0,nothing\n_SetSpeechVolumeGroupsBJ_Defaults=\n_SetSpeechVolumeGroupsBJ_Category=TC_SOUND\n\nVolumeGroupResetBJ=0,nothing\n_VolumeGroupResetBJ_Defaults=\n_VolumeGroupResetBJ_Category=TC_SOUND\n\n\n// Special Effect actions\nAddSpecialEffectLocBJ=0,location,modelfile\n_AddSpecialEffectLocBJ_Defaults=GetRectCenter,\"Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl\"\n_AddSpecialEffectLocBJ_Category=TC_SPECIALEFFECT\n\nAddSpecialEffectTargetUnitBJ=0,string,unit,modelfile\n_AddSpecialEffectTargetUnitBJ_Defaults=\"overhead\",GetTriggerUnit,\"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl\"\n_AddSpecialEffectTargetUnitBJ_Category=TC_SPECIALEFFECT\n\nDestroyEffectBJ=0,effect\n_DestroyEffectBJ_Defaults=GetLastCreatedEffectBJ\n_DestroyEffectBJ_Category=TC_SPECIALEFFECT\n\n\n// Trigger actions\nDisableTrigger=0,trigger\n_DisableTrigger_Defaults=GetTriggeringTrigger\n_DisableTrigger_Category=TC_TRIGGER\n\nEnableTrigger=0,trigger\n_EnableTrigger_Defaults=GetTriggeringTrigger\n_EnableTrigger_Category=TC_TRIGGER\n\nConditionalTriggerExecute=0,trigger\n_ConditionalTriggerExecute_Defaults=_\n_ConditionalTriggerExecute_Category=TC_TRIGGER\n\nTriggerExecute=0,trigger\n_TriggerExecute_Defaults=_\n_TriggerExecute_Category=TC_TRIGGER\n\nQueuedTriggerAddBJ=0,trigger,checkingignoringoption\n_QueuedTriggerAddBJ_Defaults=_,CheckingIgnoringChecking\n_QueuedTriggerAddBJ_Category=TC_TRIGGER\n\nQueuedTriggerRemoveBJ=0,trigger\n_QueuedTriggerRemoveBJ_Defaults=GetTriggeringTrigger\n_QueuedTriggerRemoveBJ_Category=TC_TRIGGER\n\nQueuedTriggerClearBJ=0,nothing\n_QueuedTriggerClearBJ_Defaults=\n_QueuedTriggerClearBJ_Category=TC_TRIGGER\n\nQueuedTriggerClearInactiveBJ=0,nothing\n_QueuedTriggerClearInactiveBJ_Defaults=\n_QueuedTriggerClearInactiveBJ_Category=TC_TRIGGER\n\n// This function is handled internally by the editor\nAddTriggerEvent=1,trigger,eventcall\n_AddTriggerEvent_Defaults=GetTriggeringTrigger,_\n_AddTriggerEvent_Category=TC_TRIGGER\n\n// Unit actions\nCreateNUnitsAtLoc=0,integer,unitcode,player,location,real\n_CreateNUnitsAtLoc_Defaults=1,hfoo,Player00,GetRectCenter,RealUnitFacing\n_CreateNUnitsAtLoc_Limits=1,_,_,_,_,_,_,_,0,360\n_CreateNUnitsAtLoc_Category=TC_UNIT\n\nCreateNUnitsAtLocFacingLocBJ=0,integer,unitcode,player,location,location\n_CreateNUnitsAtLocFacingLocBJ_Defaults=1,hfoo,Player00,GetRectCenter,GetUnitLoc\n_CreateNUnitsAtLocFacingLocBJ_Limits=1,_,_,_,_,_,_,_,_,_\n_CreateNUnitsAtLocFacingLocBJ_Category=TC_UNIT\n\nCreateCorpseLocBJ=0,unitcode,player,location\n_CreateCorpseLocBJ_Defaults=hfoo,Player00,GetRectCenter\n_CreateCorpseLocBJ_Category=TC_UNIT\n\nCreatePermanentCorpseLocBJ=1,corpsetype,unitcode,player,location,real\n_CreatePermanentCorpseLocBJ_Defaults=CorpseTypeBone,hfoo,Player00,GetRectCenter,GetRandomDirectionDeg\n_CreatePermanentCorpseLocBJ_Limits=_,_,_,_,_,_,_,_,0,360\n_CreatePermanentCorpseLocBJ_Category=TC_UNIT\n\nKillUnit=0,unit\n_KillUnit_Defaults=GetTriggerUnit\n_KillUnit_Category=TC_UNIT\n\nRemoveUnit=0,unit\n_RemoveUnit_Defaults=GetTriggerUnit\n_RemoveUnit_Category=TC_UNIT\n\nExplodeUnitBJ=0,unit\n_ExplodeUnitBJ_Defaults=GetTriggerUnit\n_ExplodeUnitBJ_Category=TC_UNIT\n\nReplaceUnitBJ=0,unit,unitcode,unitstatemethod\n_ReplaceUnitBJ_Defaults=GetTriggerUnit,hfoo,UnitStateMethodRelative\n_ReplaceUnitBJ_Category=TC_UNIT\n\nShowUnitHide=0,unit\n_ShowUnitHide_Defaults=_\n_ShowUnitHide_Category=TC_UNIT\n\nShowUnitShow=0,unit\n_ShowUnitShow_Defaults=_\n_ShowUnitShow_Category=TC_UNIT\n\nSetUnitColor=0,unit,playercolor\n_SetUnitColor_Defaults=GetTriggerUnit,Color00\n_SetUnitColor_Category=TC_UNIT\n\nSetUnitOwner=0,unit,player,colorchangeoption\n_SetUnitOwner_Defaults=_,Player00,ChangeColorTrue\n_SetUnitOwner_Category=TC_UNIT\n\nUnitShareVisionBJ=0,sharedontoption,unit,player\n_UnitShareVisionBJ_Defaults=ShareDontOptionShare,GetTriggerUnit,Player00\n_UnitShareVisionBJ_Category=TC_UNIT\n\nSetUnitPositionLoc=0,unit,location\n_SetUnitPositionLoc_Defaults=GetTriggerUnit,GetRectCenter\n_SetUnitPositionLoc_Category=TC_UNIT\n\nSetUnitPositionLocFacingBJ=0,unit,location,real\n_SetUnitPositionLocFacingBJ_Defaults=GetTriggerUnit,GetRectCenter,RealUnitFacing\n_SetUnitPositionLocFacingBJ_Category=TC_UNIT\n\nSetUnitPositionLocFacingLocBJ=0,unit,location,location\n_SetUnitPositionLocFacingLocBJ_Defaults=GetTriggerUnit,GetRectCenter,GetUnitLoc\n_SetUnitPositionLocFacingLocBJ_Category=TC_UNIT\n\nSetUnitRallyPoint=1,unit,location\n_SetUnitRallyPoint_Defaults=GetTriggerUnit,GetRectCenter\n_SetUnitRallyPoint_Category=TC_UNIT\n\nSetUnitRallyUnit=1,unit,unit\n_SetUnitRallyUnit_Defaults=GetTriggerUnit,_\n_SetUnitRallyUnit_Category=TC_UNIT\n\nSetUnitRallyDestructable=1,unit,destructable\n_SetUnitRallyDestructable_Defaults=GetTriggerUnit,_\n_SetUnitRallyDestructable_Category=TC_UNIT\n\nSetUnitLifePercentBJ=0,unit,real\n_SetUnitLifePercentBJ_Defaults=GetTriggerUnit,100\n_SetUnitLifePercentBJ_Limits=_,_,0,100\n_SetUnitLifePercentBJ_Category=TC_UNIT\n\nSetUnitManaPercentBJ=0,unit,real\n_SetUnitManaPercentBJ_Defaults=GetTriggerUnit,100\n_SetUnitManaPercentBJ_Limits=_,_,0,100\n_SetUnitManaPercentBJ_Category=TC_UNIT\n\nSetUnitLifeBJ=0,unit,real\n_SetUnitLifeBJ_Defaults=GetTriggerUnit,GetUnitStateSwap\n_SetUnitLifeBJ_Defaults=_,_,0,_\n_SetUnitLifeBJ_Category=TC_UNIT\n\nSetUnitManaBJ=0,unit,real\n_SetUnitManaBJ_Defaults=GetTriggerUnit,0\n_SetUnitManaBJ_Limits=_,_,0,_\n_SetUnitManaBJ_Category=TC_UNIT\n\nEndUnitAbilityCooldown=0,unit,abilcode\n_EndUnitAbilityCooldown_Defaults=_,_\n_EndUnitAbilityCooldown_Category=TC_UNIT\n\nSetAbilityTooltip=0,abilcode,string,integer\n_SetAbilityTooltip_Defaults=_,_,1\n_SetAbilityTooltip_Limits=_,_,_,_,1,_\n_SetAbilityTooltip_Category=TC_GAME\n\nSetAbilityOnTooltip=0,abilcode,string,integer\n_SetAbilityOnTooltip_Defaults=_,_,1\n_SetAbilityOnTooltip_Limits=_,_,_,_,1,_\n_SetAbilityOnTooltip_Category=TC_GAME\n\nSetAbilityExtendedTooltip=0,abilcode,string,integer\n_SetAbilityExtendedTooltip_Defaults=_,_,1\n_SetAbilityExtendedTooltip_Limits=_,_,_,_,1,_\n_SetAbilityExtendedTooltip_Category=TC_GAME\n\nSetAbilityOnExtendedTooltip=0,abilcode,string,integer\n_SetAbilityOnExtendedTooltip_Defaults=_,_,1\n_SetAbilityOnExtendedTooltip_Limits=_,_,_,_,1,_\n_SetAbilityOnExtendedTooltip_Category=TC_GAME\n\nSetAbilityResearchTooltip=0,abilcode,string,integer\n_SetAbilityResearchTooltip_Defaults=_,_,1\n_SetAbilityResearchTooltip_Limits=_,_,_,_,1,_\n_SetAbilityResearchTooltip_Category=TC_GAME\n\nSetAbilityResearchExtendedTooltip=0,abilcode,string,integer\n_SetAbilityResearchExtendedTooltip_Defaults=_,_,1\n_SetAbilityResearchExtendedTooltip_Limits=_,_,_,_,1,_\n_SetAbilityResearchExtendedTooltip_Category=TC_GAME\n\nSetAbilityIcon=0,abilcode,string,integer\n_SetAbilityIcon_Defaults=_,_,1\n_SetAbilityIcon_Limits=_,_,_,_,1,_\n_SetAbilityIcon_Category=TC_GAME\n\nSetAbilityOnIcon=0,abilcode,string,integer\n_SetAbilityOnIcon_Defaults=_,_,1\n_SetAbilityOnIcon_Limits=_,_,_,_,1,_\n_SetAbilityOnIcon_Category=TC_GAME\n\nSetAbilityPosX=0,abilcode,integer\n_SetAbilityPosX_Defaults=_,0\n_SetAbilityPosX_Limits=_,_,0,3\n_SetAbilityPosX_Category=TC_GAME\n\nSetAbilityOnPosX=0,abilcode,integer\n_SetAbilityOnPosX_Defaults=_,0\n_SetAbilityOnPosX_Limits=_,_,0,3\n_SetAbilityOnPosX_Category=TC_GAME\n\nSetAbilityPosY=0,abilcode,integer\n_SetAbilityPosY_Defaults=_,0\n_SetAbilityPosY_Limits=_,_,0,2\n_SetAbilityPosY_Category=TC_GAME\n\nSetAbilityOnPosY=0,abilcode,integer\n_SetAbilityOnPosY_Defaults=_,0\n_SetAbilityOnPosY_Limits=_,_,0,2\n_SetAbilityOnPosY_Category=TC_GAME\n\nSetEventDamage=0,real\n_SetEventDamage_Defaults=0.0\n_SetEventDamage_Category=TC_EVENTRESPONSE\n\nSetItemName=0,item,string\n_SetItemName_Defaults=GetLastCreatedItem,_\n_SetItemName_Category=TC_ITEM\n\nSetItemTooltip=0,item,string\n_SetItemTooltip_Defaults=GetLastCreatedItem,_\n_SetItemTooltip_Category=TC_ITEM\n\nSetItemDescription=0,item,string\n_SetItemDescription_Defaults=GetLastCreatedItem,_\n_SetItemDescription_Category=TC_ITEM\n\nSetItemExtendedTooltip=0,item,string\n_SetItemExtendedTooltip_Defaults=GetLastCreatedItem,_\n_SetItemExtendedTooltip_Category=TC_ITEM\n\nSetItemIconPath=0,item,string\n_SetItemIconPath_Defaults=GetLastCreatedItem,_\n_SetItemIconPath_Category=TC_ITEM\n\nSetUnitMaxHP=0,unit,integer\n_SetUnitMaxHP_Defaults=GetTriggerUnit,500\n_SetUnitMaxHP_Limits=_,_,1,_\n_SetUnitMaxHP_Category=TC_UNIT\n\nSetUnitMaxMana=0,unit,integer\n_SetUnitMaxMana_Defaults=GetTriggerUnit,300\n_SetUnitMaxManaSetUnitMaxMana_Limits=_,_,0,_\n_SetUnitMaxMana_Category=TC_UNIT\n\nSetUnitArmor=0,unit,real\n_SetUnitArmor_Defaults=GetTriggerUnit,0.00\n_SetUnitArmor_Limits=_,_,0.00,_\n_SetUnitArmor_Category=TC_UNIT\n\nUnitHideAbility=0,unit,abilcode,boolean\n_UnitHideAbility_Defaults=GetTriggerUnit,_,true\n_UnitHideAbility_Category=TC_UNIT\n\nUnitDisableAbility=0,unit,abilcode,boolean,boolean\n_UnitDisableAbility_Defaults=GetTriggerUnit,_,true,true\n_UnitDisableAbility_Category=TC_UNIT\n\nUnitCancelTimedLife=0,unit\n_UnitCancelTimedLife_Defaults=GetTriggeredUnit\n_UnitCancelTimedLife_Category=TC_UNIT\n\nUnitInterruptAttack=0,unit\n_UnitInterruptAttack_Defaults=GetTriggeredUnit\n_UnitInterruptAttack_Category=TC_UNIT\n\nSetUnitAbilityCooldown=0,unit,abilcode,integer,real\n_SetUnitAbilityCooldown_Defaults=GetTriggerUnit,_,1,5.00\n_SetUnitAbilityCooldown_Limits=_,_,_,_,1,_,0.00,_\n_SetUnitAbilityCooldown_Category=TC_UNIT\n\nSetUnitBaseDamage=0,unit,integer,integer\n_SetUnitBaseDamage_Defaults=GetTriggerUnit,10,0\n_SetUnitBaseDamage_Limits=_,_,0,_,0,1\n_SetUnitBaseDamage_Category=TC_UNIT\n\nSetUnitDiceNumber=0,unit,integer,integer\n_SetUnitDiceNumber_Defaults=GetTriggerUnit,4,0\n_SetUnitDiceNumber_Limits=_,_,0,_,0,1\n_SetUnitDiceNumber_Category=TC_UNIT\n\nSetUnitDiceSides=0,unit,integer,integer\n_SetUnitDiceSides_Defaults=GetTriggerUnit,1,0\n_SetUnitDiceSides_Limits=_,_,0,_,0,\n_SetUnitDiceSides_Category=TC_UNIT\n\nSetUnitAttackCooldown=0,unit,real,integer\n_SetUnitAttackCooldown_Defaults=GetTriggerUnit,2.00,1\n_SetUnitAttackCooldown_Limits=_,_,0.001,_,1,2\n_SetUnitAttackCooldown_Category=TC_UNIT\n\nSetUnitName=0,unit,string\n_SetUnitName_Defaults=GetTriggerUnit,_\n_SetUnitName_Category=TC_UNIT\n\nSetUnitNameAll=0,unit,string\n_SetUnitNameAll_Defaults=GetTriggerUnit,_\n_SetUnitNameAll_Category=TC_UNIT\n\nSetHeroProperName=0,unit,string\n_SetHeroProperName_Defaults=GetTriggerUnit,_\n_SetHeroProperName_Category=TC_HERO\n\n// Special Effect\nSetSpecialEffectColorByPlayer=0,effect,player\n_SetSpecialEffectColorByPlayer_Defaults=GetLastCreatedEffectBJ,player(0)\n_SetSpecialEffectColorByPlayer_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectColor=0,effect,integer,integer,integer\n_SetSpecialEffectColor_Defaults=GetLastCreatedEffectBJ,255,255,255\n_SetSpecialEffectColor_Limits=_,_,0,255,0,255,0,255\n_SetSpecialEffectColor_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectAlpha=0,effect,integer\n_SetSpecialEffectAlpha_Defaults=GetLastCreatedEffectBJ,255\n_SetSpecialEffectAlpha_Limits=_,_,0,255\n_SetSpecialEffectAlpha_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectScale=0,effect,real\n_SetSpecialEffectScale_Defaults=GetLastCreatedEffectBJ,1.0\n_SetSpecialEffectScale_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectPosition=0,effect,real,real,real\n_SetSpecialEffectPosition_Defaults=GetLastCreatedEffectBJ,0.0,0.0,0.0\n_SetSpecialEffectPosition_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectX=0,effect,real\n_SetSpecialEffectX_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectX_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectY=0,effect,real\n_SetSpecialEffectY_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectY_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectZ=0,effect,real\n_SetSpecialEffectZ_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectZ_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectPositionLoc=0,effect,location\n_SetSpecialEffectPositionLoc_Defaults=GetLastCreatedEffectBJ,GetRectCenter\n_SetSpecialEffectPositionLoc_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectHeight=0,effect,real\n_SetSpecialEffectHeight_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectHeight_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectOrientation=0,effect,real,real,real\n_SetSpecialEffectOrientation_Defaults=GetLastCreatedEffectBJ,0.0,0.0,0.0\n_SetSpecialEffectOrientation_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectYaw=0,effect,real\n_SetSpecialEffectYaw_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectYaw_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectPitch=0,effect,real\n_SetSpecialEffectPitch_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectPitch_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectRoll=0,effect,real\n_SetSpecialEffectRoll_Defaults=GetLastCreatedEffectBJ,0.0\n_SetSpecialEffectRoll_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectTimeScale=0,effect,real\n_SetSpecialEffectTimeScale_Defaults=GetLastCreatedEffectBJ,1.0\n_SetSpecialEffectTimeScale_Category=TC_SPECIALEFFECT\n\nSetSpecialEffectTime=0,effect,real\n_SetSpecialEffectTime_Defaults=GetLastCreatedEffectBJ, 1.0\n_SetSpecialEffectTime_Category=TC_SPECIALEFFECT\n\nPlaySpecialEffect=0,effect,integer\n_PlaySpecialEffect_Defaults=GetLastCreatedEffectBJ, 0\n_PlaySpecialEffect_Category=TC_SPECIALEFFECT\n\nPlaySpecialEffectWithTimeScale=0,effect,integer,real\n_PlaySpecialEffectWithTimeScale_Defaults=GetLastCreatedEffectBJ, 0, 1.0\n_PlaySpecialEffectWithTimeScale_Category=TC_SPECIALEFFECT\n\nSetUnitInvulnerable=0,unit,invulnerableoption\n_SetUnitInvulnerable_Defaults=GetTriggerUnit,InvulnerabilityInvulnerable\n_SetUnitInvulnerable_Category=TC_UNIT\n\nPauseUnitBJ=0,pauseunpauseoption,unit\n_PauseUnitBJ_Defaults=PauseUnpauseOptionPause,GetTriggerUnit\n_PauseUnitBJ_Category=TC_UNIT\n\nPauseAllUnitsBJ=0,pauseunpauseoption\n_PauseAllUnitsBJ_Defaults=PauseUnpauseOptionPause\n_PauseAllUnitsBJ_Category=TC_UNIT\n\nUnitPauseTimedLifeBJ=1,pauseunpauseoption,unit\n_UnitPauseTimedLifeBJ_Defaults=PauseUnpauseOptionPause,GetTriggerUnit\n_UnitPauseTimedLifeBJ_Category=TC_UNIT\n\nUnitApplyTimedLifeBJ=1,real,timedlifebuffcode,unit\n_UnitApplyTimedLifeBJ_Defaults=60,TimedLifeBuffCodeGeneric,GetTriggerUnit\n_UnitApplyTimedLifeBJ_Limits=0,_,_,_,_,_\n_UnitApplyTimedLifeBJ_Category=TC_UNIT\n\nSetUnitExplodedBJ=0,unit,explodedontoption\n_SetUnitExplodedBJ_Defaults=GetTriggerUnit,ExplodeDontExplode\n_SetUnitExplodedBJ_Category=TC_UNIT\n\nUnitSuspendDecayBJ=0,suspendresumeoption,unit\n_UnitSuspendDecayBJ_Defaults=SuspendResumeSuspend,GetTriggerUnit\n_UnitSuspendDecayBJ_Category=TC_UNIT\n\nUnitResetCooldown=1,unit\n_UnitResetCooldown_Defaults=GetTriggerUnit\n_UnitResetCooldown_Category=TC_UNIT\n\nUnitSetConstructionProgress=1,unit,integer\n_UnitSetConstructionProgress_Defaults=GetTriggerUnit,50\n_UnitSetConstructionProgress_Limits=_,_,0,100\n_UnitSetConstructionProgress_Category=TC_UNIT\n\nUnitSetUpgradeProgress=1,unit,integer\n_UnitSetUpgradeProgress_Defaults=GetTriggerUnit,50\n_UnitSetUpgradeProgress_Limits=_,_,0,100\n_UnitSetUpgradeProgress_Category=TC_UNIT\n\nUnitAddSleepPerm=0,unit,sleepwakeoption\n_UnitAddSleepPerm_Defaults=GetTriggerUnit,SleepWakeOptionSleep\n_UnitAddSleepPerm_Category=TC_UNIT\n\nUnitSetCanSleepBJ=0,unit,sleepwakeoption\n_UnitSetCanSleepBJ_Defaults=GetTriggerUnit,SleepWakeOptionSleep\n_UnitSetCanSleepBJ_Category=TC_UNIT\n\nUnitWakeUpBJ=0,unit\n_UnitWakeUpBJ_Defaults=GetTriggerUnit\n_UnitWakeUpBJ_Category=TC_UNIT\n\nUnitGenerateAlarms=1,unit,onoffoption\n_UnitGenerateAlarms_Defaults=GetTriggerUnit,OnOffOff\n_UnitGenerateAlarms_Category=TC_UNIT\n\nRescueUnitBJ=0,unit,player,colorchangeoption\n_RescueUnitBJ_Defaults=_,Player00,ChangeColorTrue\n_RescueUnitBJ_Category=TC_UNIT\n\nMakeUnitRescuableToForceBJ=0,unit,rescuableoption,force\n_MakeUnitRescuableToForceBJ_Defaults=_,RescuableOptionRescuable,Force00\n_MakeUnitRescuableToForceBJ_Category=TC_UNIT\n\nSetUnitRescueRange=0,unit,real\n_SetUnitRescueRange_Defaults=_,384\n_SetUnitRescueRange_Limits=_,_,0,_\n_SetUnitRescueRange_Category=TC_UNIT\n\nSetRescueUnitColorChangeBJ=0,colorchangeoption\n_SetRescueUnitColorChangeBJ_Defaults=ChangeColorFalse\n_SetRescueUnitColorChangeBJ_Category=TC_UNIT\n\nSetRescueBuildingColorChangeBJ=0,colorchangeoption\n_SetRescueBuildingColorChangeBJ_Defaults=ChangeColorFalse\n_SetRescueBuildingColorChangeBJ_Category=TC_UNIT\n\nSetUnitUseFoodBJ=1,enabledisableoption,unit\n_SetUnitUseFoodBJ_Defaults=EnableDisableDisable,_\n_SetUnitUseFoodBJ_Category=TC_UNIT\n\nSetUnitFacingToFaceUnitTimed=0,unit,unit,real\n_SetUnitFacingToFaceUnitTimed_Defaults=_,_,0\n_SetUnitFacingToFaceUnitTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingToFaceUnitTimed_Category=TC_UNIT\n\nSetUnitFacingToFaceLocTimed=0,unit,location,real\n_SetUnitFacingToFaceLocTimed_Defaults=_,GetRectCenter,0\n_SetUnitFacingToFaceLocTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingToFaceLocTimed_Category=TC_UNIT\n\nSetUnitFacingTimed=0,unit,real,real\n_SetUnitFacingTimed_Defaults=_,RealUnitFacing,0\n_SetUnitFacingTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingTimed_Category=TC_UNIT\n\nSetUnitMoveSpeed=0,unit,real\n_SetUnitMoveSpeed_Defaults=_,GetUnitDefaultMoveSpeed\n_SetUnitMoveSpeed_Category=TC_UNIT\n\nSetUnitPathing=0,unit,pathingoption\n_SetUnitPathing_Defaults=_,PathingOff\n_SetUnitPathing_Category=TC_UNIT\n\nSetUnitAcquireRangeBJ=0,unit,real\n_SetUnitAcquireRangeBJ_Defaults=_,_\n_SetUnitAcquireRangeBJ_Category=TC_UNIT\n\nSetUnitUserData=1,unit,integer\n_SetUnitUserData_Defaults=_,0\n_SetUnitUserData_Category=TC_UNIT\n\nUnitRemoveBuffsBJ=0,bufftype,unit\n_UnitRemoveBuffsBJ_Defaults=BuffTypeAll,GetTriggerUnit\n_UnitRemoveBuffsBJ_Category=TC_UNIT\n\nUnitRemoveBuffsExBJ=1,buffpolarity,buffresist,unit,includeoption,includeoption\n_UnitRemoveBuffsExBJ_Defaults=BuffPolarityEither,BuffResistEither,GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitRemoveBuffsExBJ_Category=TC_UNIT\n\nUnitRemoveBuffBJ=1,buffcode,unit\n_UnitRemoveBuffBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveBuffBJ_Category=TC_UNIT\n\nUnitAddAbilityBJ=1,abilcode,unit\n_UnitAddAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitAddAbilityBJ_Category=TC_UNIT\n\nUnitRemoveAbilityBJ=0,abilcode,unit\n_UnitRemoveAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveAbilityBJ_Category=TC_UNIT\n\nUnitAddTypeBJ=1,unittype,unit\n_UnitAddTypeBJ_Defaults=UnitTypeMechanical,GetTriggerUnit\n_UnitAddTypeBJ_Category=TC_UNIT\n\nUnitRemoveTypeBJ=1,unittype,unit\n_UnitRemoveTypeBJ_Defaults=UnitTypeMechanical,GetTriggerUnit\n_UnitRemoveTypeBJ_Category=TC_UNIT\n\nIssueTargetOrder=0,unit,unitorderutarg,unit\n_IssueTargetOrder_Defaults=_,UnitOrderAttackUnit,_\n_IssueTargetOrder_Category=TC_UNIT\n_IssueTargetOrder_ScriptName=IssueTargetOrderBJ\n\nIssuePointOrderLoc=0,unit,unitorderptarg,location\n_IssuePointOrderLoc_Defaults=_,UnitOrderMove,GetRectCenter\n_IssuePointOrderLoc_Category=TC_UNIT\n_IssuePointOrderLoc_ScriptName=IssuePointOrderLocBJ\n\nIssueTargetDestructableOrder=0,unit,unitorderdtarg,destructable\n_IssueTargetDestructableOrder_Defaults=_,UnitOrderHarvestDestructible,_\n_IssueTargetDestructableOrder_Category=TC_UNIT\n\nIssueTargetItemOrder=0,unit,unitorderitarg,item\n_IssueTargetItemOrder_Defaults=_,UnitOrderSmartItem,_\n_IssueTargetItemOrder_Category=TC_UNIT\n\nIssueImmediateOrder=0,unit,unitordernotarg\n_IssueImmediateOrder_Defaults=_,UnitOrderStop\n_IssueImmediateOrder_Category=TC_UNIT\n_IssueImmediateOrder_ScriptName=IssueImmediateOrderBJ\n\nIssueTrainOrderByIdBJ=0,unit,unitcode\n_IssueTrainOrderByIdBJ_Defaults=_,hfoo\n_IssueTrainOrderByIdBJ_Category=TC_UNIT\n\nIssueUpgradeOrderByIdBJ=0,unit,techcode\n_IssueUpgradeOrderByIdBJ_Defaults=_,Rhde\n_IssueUpgradeOrderByIdBJ_Category=TC_UNIT\n\nIssueBuildOrderByIdLocBJ=0,unit,unitcode,location\n_IssueBuildOrderByIdLocBJ_Defaults=_,hbar,GetRectCenter\n_IssueBuildOrderByIdLocBJ_Category=TC_UNIT\n\nUnitDropItemPointLoc=1,unit,item,location\n_UnitDropItemPointLoc_Defaults=_,GetLastCreatedItem,GetRectCenter\n_UnitDropItemPointLoc_Category=TC_UNIT\n\nUnitDropItemSlotBJ=1,unit,item,integer\n_UnitDropItemSlotBJ_Defaults=_,GetLastCreatedItem,1\n_UnitDropItemSlotBJ_Limits=_,_,_,_,1,6\n_UnitDropItemSlotBJ_Category=TC_UNIT\n\nUnitDropItemTargetBJ=1,unit,item,unit\n_UnitDropItemTargetBJ_Defaults=_,GetLastCreatedItem,_\n_UnitDropItemTargetBJ_Category=TC_UNIT\n\nUnitDamagePointLoc=1,unit,real,real,location,real,attacktype,damagetype\n_UnitDamagePointLoc_Defaults=GetTriggerUnit,0,500,GetRectCenter,100,AttackTypeNormal,DamageTypeNormal\n_UnitDamagePointLoc_Category=TC_UNIT\n\nUnitDamageTargetBJ=1,unit,unit,real,attacktype,damagetype\n_UnitDamageTargetBJ_Defaults=GetTriggerUnit,GetTriggerUnit,500,AttackTypeNormal,DamageTypeNormal\n_UnitDamageTargetBJ_Category=TC_UNIT\n\nDecUnitAbilityLevelSwapped=1,abilcode,unit\n_DecUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_DecUnitAbilityLevelSwapped_Category=TC_UNIT\n\nIncUnitAbilityLevelSwapped=1,abilcode,unit\n_IncUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_IncUnitAbilityLevelSwapped_Category=TC_UNIT\n\nSetUnitAbilityLevelSwapped=1,abilcode,unit,integer\n_SetUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit,1\n_SetUnitAbilityLevelSwapped_Limits=_,_,_,_,1,_\n_SetUnitAbilityLevelSwapped_Category=TC_UNIT\n\n\n// Unit Group actions\n// Specially handled by the editor\nForGroupMultiple=1,group\n_ForGroupMultiple_Defaults=GetUnitsInRectAll\n_ForGroupMultiple_Category=TC_UNITGROUP\n_ForGroupMultiple_ScriptName=ForGroupBJ\n\nForGroup=0,group,code\n_ForGroup_Defaults=GetUnitsInRectAll,DoNothing\n_ForGroup_Category=TC_UNITGROUP\n_ForGroup_ScriptName=ForGroupBJ\n\nGroupAddUnitSimple=0,unit,group\n_GroupAddUnitSimple_Defaults=GetTriggerUnit,_\n_GroupAddUnitSimple_Category=TC_UNITGROUP\n\nGroupAddGroup=0,group,group\n_GroupAddGroup_Defaults=_,_\n_GroupAddGroup_Category=TC_UNITGROUP\n\nGroupRemoveUnitSimple=0,unit,group\n_GroupRemoveUnitSimple_Defaults=GetTriggerUnit,_\n_GroupRemoveUnitSimple_Category=TC_UNITGROUP\n\nGroupRemoveGroup=0,group,group\n_GroupRemoveGroup_Defaults=_,_\n_GroupRemoveGroup_Category=TC_UNITGROUP\n\nGroupClear=0,group\n_GroupClear_Defaults=_\n_GroupClear_Category=TC_UNITGROUP\n\nGroupTargetOrder=0,group,unitorderutarg,unit\n_GroupTargetOrder_Defaults=GetUnitsInRectAll,UnitOrderAttackUnit,_\n_GroupTargetOrder_Category=TC_UNITGROUP\n_GroupTargetOrder_ScriptName=GroupTargetOrderBJ\n\nGroupPointOrderLoc=0,group,unitorderptarg,location\n_GroupPointOrderLoc_Defaults=GetUnitsInRectAll,UnitOrderMove,GetRectCenter\n_GroupPointOrderLoc_Category=TC_UNITGROUP\n_GroupPointOrderLoc_ScriptName=GroupPointOrderLocBJ\n\nGroupTargetDestructableOrder=0,group,unitorderdtarg,destructable\n_GroupTargetDestructableOrder_Defaults=GetUnitsInRectAll,UnitOrderHarvestDestructible,_\n_GroupTargetDestructableOrder_Category=TC_UNITGROUP\n\nGroupTargetItemOrder=0,group,unitorderitarg,item\n_GroupTargetItemOrder_Defaults=GetUnitsInRectAll,UnitOrderAttackItem,_\n_GroupTargetItemOrder_Category=TC_UNITGROUP\n\nGroupImmediateOrder=0,group,unitordernotarg\n_GroupImmediateOrder_Defaults=GetUnitsInRectAll,UnitOrderStop\n_GroupImmediateOrder_Category=TC_UNITGROUP\n_GroupImmediateOrder_ScriptName=GroupImmediateOrderBJ\n\nGroupTrainOrderByIdBJ=0,group,unitcode\n_GroupTrainOrderByIdBJ_Defaults=GetUnitsInRectAll,hfoo\n_GroupTrainOrderByIdBJ_Category=TC_UNITGROUP\n\n\n// Ubersplat actions\nCreateUbersplatBJ=1,location,ubersplattype,real,real,real,real,enabledisableoption,enabledisableoption\n_CreateUberSplatBJ_Defaults=GetRectCenter,UbersplatTypeNGOL,100,100,100,0,EnableDisableDisable,EnableDisableDisable\n_CreateUberSplatBJ_Category=TC_UBERSPLAT\n\nDestroyUbersplat=1,ubersplat\n_DestroyUbersplat_Defaults=GetLastCreatedUbersplat\n_DestroyUbersplat_Category=TC_UBERSPLAT\n\nResetUbersplat=1,ubersplat\n_ResetUbersplat_Defaults=GetLastCreatedUbersplat\n_ResetUbersplat_Category=TC_UBERSPLAT\n\nFinishUbersplat=1,ubersplat\n_FinishUbersplat_Defaults=GetLastCreatedUbersplat\n_FinishUbersplat_Category=TC_UBERSPLAT\n\nShowUbersplatBJ=1,showhideoption,ubersplat\n_ShowUbersplatBJ_Defaults=ShowHideShow,GetLastCreatedUbersplat\n_ShowUbersplatBJ_Category=TC_UBERSPLAT\n\nSetUbersplatRender=1,ubersplat,enabledisableoption\n_SetUbersplatRender_Defaults=GetLastCreatedUbersplat,EnableDisableEnable\n_SetUbersplatRender_Category=TC_UBERSPLAT\n\nSetUbersplatRenderAlways=1,ubersplat,enabledisableoption\n_SetUbersplatRenderAlways_Defaults=GetLastCreatedUbersplat,EnableDisableEnable\n_SetUbersplatRenderAlways_Category=TC_UBERSPLAT\n\n\n// Visibility actions\nFogEnableOn=0,nothing\n_FogEnableOn_Defaults=\n_FogEnableOn_Category=TC_VISIBILITY\n\nFogEnableOff=0,nothing\n_FogEnableOff_Defaults=\n_FogEnableOff_Category=TC_VISIBILITY\n\nFogMaskEnableOn=0,nothing\n_FogMaskEnableOn_Defaults=\n_FogMaskEnableOn_Category=TC_VISIBILITY\n\nFogMaskEnableOff=0,nothing\n_FogMaskEnableOff_Defaults=\n_FogMaskEnableOff_Category=TC_VISIBILITY\n\nCreateFogModifierRectBJ=0,enableddisabledoption,player,fogstate,rect\n_CreateFogModifierRectBJ_Defaults=EnabledDisabledEnabled,Player00,FogStateVisible,GetPlayableMapRect\n_CreateFogModifierRectBJ_Category=TC_VISIBILITY\n\nCreateFogModifierRadiusLocBJ=0,enableddisabledoption,player,fogstate,location,real\n_CreateFogModifierRadiusLocBJ_Defaults=EnabledDisabledEnabled,Player00,FogStateVisible,GetRectCenter,512\n_CreateFogModifierRadiusLocBJ_Defaults=_,_,_,_,_,_,_,_,0,_\n_CreateFogModifierRadiusLocBJ_Category=TC_VISIBILITY\n\nFogModifierStart=0,fogmodifier\n_FogModifierStart_Defaults=GetLastCreatedFogModifier\n_FogModifierStart_Category=TC_VISIBILITY\n\nFogModifierStop=0,fogmodifier\n_FogModifierStop_Defaults=GetLastCreatedFogModifier\n_FogModifierStop_Category=TC_VISIBILITY\n\nDestroyFogModifier=0,fogmodifier\n_DestroyFogModifier_Defaults=GetLastCreatedFogModifier\n_DestroyFogModifier_Category=TC_VISIBILITY\n\n\n// Obsolete actions\n//AddPerfLogLabel=0,string\n//_AddPerfLogLabel_Defaults=\"Triggered Debug Label\"\n//_AddPerfLogLabel_Category=TC_OBSOLETE\n\n//Cheat=0,string\n//_Cheat_Defaults=\"warnings\"\n//_Cheat_Category=TC_OBSOLETE\n\n\n\n//***************************************************************************\n[TriggerCalls]\n// Defines function calls which may be used as parameter values\n// Key: Function name\n// Value 0: first game version in which this function is valid\n// Value 1: flag (0 or 1) indicating if the call can be used in events\n// Value 2: return type\n// Value 3+: argument types\n//\n// Note: Operators are specially handled by the editor\n\n// returns boolean\nIsDestructableAliveBJ=0,0,boolean,destructable\n_IsDestructableAliveBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableAliveBJ_Category=TC_DESTRUCT\n\nIsDestructableDeadBJ=0,0,boolean,destructable\n_IsDestructableDeadBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableDeadBJ_Category=TC_DESTRUCT\n\nIsDestructableInvulnerableBJ=0,0,boolean,destructable\n_IsDestructableInvulnerableBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableInvulnerableBJ_Category=TC_DESTRUCT\n\nIsPointBlightedBJ=1,1,boolean,location\n_IsPointBlightedBJ_Defaults=GetRectCenter\n_IsPointBlightedBJ_Category=TC_ENVIRONMENT\n\nIsTerrainPathableBJ=1,1,boolean,location,pathingtype\n_IsTerrainPathableBJ_Defaults=GetRectCenter,PathingTypeWalkability\n_IsTerrainPathableBJ_Category=TC_ENVIRONMENT\n\nIsMapFlagSet=0,1,boolean,mapflag\n_IsMapFlagSet_Defaults=MapFlagUseHandicaps\n_IsMapFlagSet_Category=TC_GAME\n\nIsCustomCampaignButtonVisibile=1,0,boolean,integer\n_IsCustomCampaignButtonVisibile_Defaults=1\n_IsCustomCampaignButtonVisibile_Limits=1,_\n_IsCustomCampaignButtonVisibile_Category=TC_GAME\n\nGetCreepCampFilterState=1,1,boolean\n_GetCreepCampFilterState_Category=TC_GAME\n\nSaveGameExists=1,0,boolean,anyfile\n_SaveGameExists_Defaults=_\n_SaveGameExists_Category=TC_GAME\n\nGetStoredBooleanBJ=0,0,boolean,string,string,gamecache\n_GetStoredBooleanBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredBooleanBJ_Category=TC_GAMECACHE\n\nIsUnitSelectable=0,1,boolean,unit\n_IsUnitSelectable_Defaults=GetTriggerUnit\n_IsUnitSelectable_Category=TC_UNIT\n\nIsUnitInvulnerable=0,1,boolean,unit\n_IsUnitInvulnerable_Defaults=GetTriggerUnit\n_IsUnitInvulnerable_Category=TC_UNIT\n\n// Hashtable\nGetHandleIdBJ=1,1,integer,handle\n_GetHandleIdBJ_Defaults=\n_GetHandleIdBJ_Category=TC_HASHTABLE\n\nStringHashBJ=1,1,integer,string\n_StringHashBJ_Defaults=\n_StringHashBJ_Category=TC_HASHTABLE\n\nLoadIntegerBJ=0,0,integer,integer,integer,hashtable\n_LoadIntegerBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadIntegerBJ_Category=TC_HASHTABLE\n\nLoadRealBJ=0,0,real,integer,integer,hashtable\n_LoadRealBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadRealBJ_Category=TC_HASHTABLE\n\nLoadStringBJ=1,0,string,integer,integer,hashtable\n_LoadStringBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadStringBJ_Category=TC_HASHTABLE\n\nLoadBooleanBJ=0,0,boolean,integer,integer,hashtable\n_LoadBooleanBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadBooleanBJ_Category=TC_HASHTABLE\n\nLoadPlayerHandleBJ=0,0,player,integer,integer,hashtable\n_LoadPlayerHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadPlayerHandleBJ_Category=TC_HASHTABLE\n\nLoadWidgetHandleBJ=0,0,widget,integer,integer,hashtable\n_LoadWidgetHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadWidgetHandleBJ_Category=TC_HASHTABLE\n\nLoadDestructableHandleBJ=0,0,destructable,integer,integer,hashtable\n_LoadDestructableHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadDestructableHandleBJ_Category=TC_HASHTABLE\n\nLoadItemHandleBJ=0,0,item,integer,integer,hashtable\n_LoadItemHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadItemHandleBJ_Category=TC_HASHTABLE\n\nLoadUnitHandleBJ=0,0,unit,integer,integer,hashtable\n_LoadUnitHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadUnitHandleBJ_Category=TC_HASHTABLE\n\nLoadAbilityHandleBJ=0,0,ability,integer,integer,hashtable\n_LoadAbilityHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadAbilityHandleBJ_Category=TC_HASHTABLE\n\nLoadTimerHandleBJ=0,0,timer,integer,integer,hashtable\n_LoadTimerHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTimerHandleBJ_Category=TC_HASHTABLE\n\n//LoadTriggerRegionHandleBJ=0,0,region,integer,integer,hashtable\n//_LoadTriggerRegionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadTriggerRegionHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerHandleBJ=0,0,trigger,integer,integer,hashtable\n_LoadTriggerHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerConditionHandleBJ=0,0,triggercondition,integer,integer,hashtable\n_LoadTriggerConditionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerConditionHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerActionHandleBJ=0,0,triggeraction,integer,integer,hashtable\n_LoadTriggerActionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerActionHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerEventHandleBJ=0,0,eventid,integer,integer,hashtable\n_LoadTriggerEventHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerEventHandleBJ_Category=TC_HASHTABLE\n\nLoadForceHandleBJ=0,0,force,integer,integer,hashtable\n_LoadForceHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadForceHandleBJ_Category=TC_HASHTABLE\n\nLoadGroupHandleBJ=0,0,group,integer,integer,hashtable\n_LoadGroupHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadGroupHandleBJ_Category=TC_HASHTABLE\n\nLoadLocationHandleBJ=0,0,location,integer,integer,hashtable\n_LoadLocationHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadLocationHandleBJ_Category=TC_HASHTABLE\n\nLoadRegionHandleBJ=0,0,region,integer,integer,hashtable\n_LoadRegionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadRegionHandleBJ_Category=TC_HASHTABLE\n\nLoadRectHandleBJ=0,0,rect,integer,integer,hashtable\n_LoadRectHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadRectHandleBJ_Category=TC_HASHTABLE\n\nLoadBooleanExprHandleBJ=0,0,boolexpr,integer,integer,hashtable\n_LoadBooleanExprHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadBooleanExprHandleBJ_Category=TC_HASHTABLE\n\n//LoadConditionFuncHandleBJ=0,0,conditionfunc,integer,integer,hashtable\n//_LoadConditionFuncHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadConditionFuncHandleBJ_Category=TC_HASHTABLE\n\n//LoadFilterFuncHandleBJ=0,0,filterfunc,integer,integer,hashtable\n//_LoadFilterFuncHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadFilterFuncHandleBJ_Category=TC_HASHTABLE\n\nLoadSoundHandleBJ=0,0,sound,integer,integer,hashtable\n_LoadSoundHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadSoundHandleBJ_Category=TC_HASHTABLE\n\n//LoadRaceHandleBJ=0,0,race,integer,integer,hashtable\n//_LoadRaceHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadRaceHandleBJ_Category=TC_HASHTABLE\n\nLoadEffectHandleBJ=0,0,effect,integer,integer,hashtable\n_LoadEffectHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadEffectHandleBJ_Category=TC_HASHTABLE\n\nLoadUnitPoolHandleBJ=0,0,unitpool,integer,integer,hashtable\n_LoadUnitPoolHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadUnitPoolHandleBJ_Category=TC_HASHTABLE\n\nLoadItemPoolHandleBJ=0,0,itempool,integer,integer,hashtable\n_LoadItemPoolHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadItemPoolHandleBJ_Category=TC_HASHTABLE\n\nLoadQuestHandleBJ=0,0,quest,integer,integer,hashtable\n_LoadQuestHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadQuestHandleBJ_Category=TC_HASHTABLE\n\nLoadQuestItemHandleBJ=0,0,questitem,integer,integer,hashtable\n_LoadQuestItemHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadQuestItemHandleBJ_Category=TC_HASHTABLE\n\nLoadDefeatConditionHandleBJ=0,0,defeatcondition,integer,integer,hashtable\n_LoadDefeatConditionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadDefeatConditionHandleBJ_Category=TC_HASHTABLE\n\nLoadTimerDialogHandleBJ=0,0,timerdialog,integer,integer,hashtable\n_LoadTimerDialogHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTimerDialogHandleBJ_Category=TC_HASHTABLE\n\nLoadLeaderboardHandleBJ=0,0,leaderboard,integer,integer,hashtable\n_LoadLeaderboardHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadLeaderboardHandleBJ_Category=TC_HASHTABLE\n\nLoadMultiboardHandleBJ=0,0,multiboard,integer,integer,hashtable\n_LoadMultiboardHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadMultiboardHandleBJ_Category=TC_HASHTABLE\n\nLoadMultiboardItemHandleBJ=0,0,multiboarditem,integer,integer,hashtable\n_LoadMultiboardItemHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadMultiboardItemHandleBJ_Category=TC_HASHTABLE\n\nLoadTrackableHandleBJ=0,0,trackable,integer,integer,hashtable\n_LoadTrackableHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTrackableHandleBJ_Category=TC_HASHTABLE\n\nLoadDialogHandleBJ=0,0,dialog,integer,integer,hashtable\n_LoadDialogHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadDialogHandleBJ_Category=TC_HASHTABLE\n\nLoadButtonHandleBJ=0,0,button,integer,integer,hashtable\n_LoadButtonHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadButtonHandleBJ_Category=TC_HASHTABLE\n\n//LoadVersionHandleBJ=0,0,version,integer,integer,hashtable\n//_LoadVersionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadVersionHandleBJ_Category=TC_HASHTABLE\n\n//LoadItemTypeHandleBJ=0,0,itemtype,integer,integer,hashtable\n//_LoadItemTypeHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadItemTypeHandleBJ_Category=TC_HASHTABLE\n\nLoadTextTagHandleBJ=0,0,texttag,integer,integer,hashtable\n_LoadTextTagHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTextTagHandleBJ_Category=TC_HASHTABLE\n\nLoadLightningHandleBJ=0,0,lightning,integer,integer,hashtable\n_LoadLightningHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadLightningHandleBJ_Category=TC_HASHTABLE\n\nLoadImageHandleBJ=0,0,image,integer,integer,hashtable\n_LoadImageHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadImageHandleBJ_Category=TC_HASHTABLE\n\nLoadUbersplatHandleBJ=0,0,ubersplat,integer,integer,hashtable\n_LoadUbersplatHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadUbersplatHandleBJ_Category=TC_HASHTABLE\n\nLoadFogStateHandleBJ=0,0,fogstate,integer,integer,hashtable\n_LoadFogStateHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadFogStateHandleBJ_Category=TC_HASHTABLE\n\nLoadFogModifierHandleBJ=0,0,fogmodifier,integer,integer,hashtable\n_LoadFogModifierHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadFogModifierHandleBJ_Category=TC_HASHTABLE\n\nHaveStoredValue=1,0,boolean,string,cachevaluetype,string,gamecache\n_HaveStoredValue_Defaults=_,CacheValueTypeUnit,\"Category\",GetLastCreatedGameCacheBJ\n_HaveStoredValue_Category=TC_GAMECACHE\n\nHaveSavedValue=1,0,boolean,integer,hashtablevaluetype,integer,hashtable\n_HaveSavedValue_Defaults=_,HashtableValueTypeHandle,_,GetLastCreatedHashtableBJ\n_HaveSavedValue_Category=TC_HASHTABLE\n\nUnitHasItem=0,1,boolean,unit,item\n_UnitHasItem_Defaults=GetTriggerUnit,GetLastCreatedItem\n_UnitHasItem_Category=TC_HERO\n\nUnitHasItemOfTypeBJ=0,1,boolean,unit,itemcode\n_UnitHasItemOfTypeBJ_Defaults=GetTriggerUnit,texp\n_UnitHasItemOfTypeBJ_Category=TC_HERO\n\nIsSuspendedXP=0,0,boolean,unit\n_IsSuspendedXP_Defaults=GetTriggerUnit\n_IsSuspendedXP_Category=TC_HERO\n\nCheckItemStatus=1,0,boolean,item,itemstatus\n_CheckItemStatus_Defaults=GetLastCreatedItem,ItemStatusHidden\n_CheckItemStatus_Category=TC_ITEM\n\nCheckItemcodeStatus=1,0,boolean,itemcode,itemcodestatus\n_CheckItemcodeStatus_Defaults=GetItemTypeId,ItemcodeStatusPowerup\n_CheckItemcodeStatus_Category=TC_ITEM\n\nIsItemHiddenBJ=1,0,boolean,item\n_IsItemHiddenBJ_Defaults=GetLastCreatedItem\n_IsItemHiddenBJ_Category=TC_ITEM\n\nIsItemOwned=1,0,boolean,item\n_IsItemOwned_Defaults=GetLastCreatedItem\n_IsItemOwned_Category=TC_ITEM\n\nRectContainsItem=1,1,boolean,item,rect\n_RectContainsItem_Defaults=GetLastCreatedItem,GetRectCenter\n_RectContainsItem_Category=TC_ITEM\n\nIsItemInvulnerable=0,0,boolean,item\n_IsItemInvulnerable_Defaults=GetLastCreatedItem\n_IsItemInvulnerable_Category=TC_ITEM\n\nLeaderboardHasPlayerItemBJ=0,0,boolean,leaderboard,player\n_LeaderboardHasPlayerItemBJ_Defaults=GetLastCreatedLeaderboard,Player00\n_LeaderboardHasPlayerItemBJ_Category=TC_LEADERBOARD\n\nIsMultiboardDisplayed=1,0,boolean,multiboard\n_IsMultiboardDisplayed_Defaults=GetLastCreatedMultiboard\n_IsMultiboardDisplayed_Category=TC_MULTIBOARD\n\nIsMultiboardMinimized=1,0,boolean,multiboard\n_IsMultiboardMinimized_Defaults=GetLastCreatedMultiboard\n_IsMultiboardMinimized_Category=TC_MULTIBOARD\n\nWaygateIsActiveBJ=0,0,boolean,unit\n_WaygateIsActiveBJ_Defaults=_\n_WaygateIsActiveBJ_Category=TC_NEUTRALBUILDING\n\nIsPlayerFlagSetBJ=0,0,boolean,playerflag,player\n_IsPlayerFlagSetBJ_Defaults=PlayerFlagGivesBounty,PlayerNA\n_IsPlayerFlagSetBJ_Category=TC_PLAYER\n\nIsPlayerAlly=0,1,boolean,player,player\n_IsPlayerAlly_Defaults=GetTriggerPlayer,Player00\n_IsPlayerAlly_Category=TC_PLAYER\n\nIsPlayerEnemy=0,1,boolean,player,player\n_IsPlayerEnemy_Defaults=GetTriggerPlayer,Player00\n_IsPlayerEnemy_Category=TC_PLAYER\n\nGetPlayerAlliance=0,1,boolean,player,player,alliancetype\n_GetPlayerAlliance_Defaults=GetTriggerPlayer,Player00,AllianceTypePassive\n_GetPlayerAlliance_Category=TC_PLAYER\n\nIsPlayerInForce=0,1,boolean,player,force\n_IsPlayerInForce_Defaults=Player00,GetPlayersAll\n_IsPlayerInForce_Category=TC_PLAYER\n\nIsQuestItemCompleted=0,0,boolean,questitem\n_IsQuestItemCompleted_Defaults=GetLastCreatedQuestItemBJ\n_IsQuestItemCompleted_Category=TC_QUEST\n\nIsQuestEnabled=0,0,boolean,quest\n_IsQuestEnabled_Defaults=GetLastCreatedQuestBJ\n_IsQuestEnabled_Category=TC_QUEST\n\nIsQuestCompleted=0,0,boolean,quest\n_IsQuestCompleted_Defaults=GetLastCreatedQuestBJ\n_IsQuestCompleted_Category=TC_QUEST\n\nIsQuestFailed=0,0,boolean,quest\n_IsQuestFailed_Defaults=GetLastCreatedQuestBJ\n_IsQuestFailed_Category=TC_QUEST\n\nIsQuestDiscovered=0,0,boolean,quest\n_IsQuestDiscovered_Defaults=GetLastCreatedQuestBJ\n_IsQuestDiscovered_Category=TC_QUEST\n\nIsQuestRequired=0,0,boolean,quest\n_IsQuestRequired_Defaults=GetLastCreatedQuestBJ\n_IsQuestRequired_Category=TC_QUEST\n\nRectContainsLoc=0,1,boolean,rect,location\n_RectContainsLoc_Defaults=GetPlayableMapRect,GetRectCenter\n_RectContainsLoc_Category=TC_REGION\n\nIsTriggerEnabled=0,1,boolean,trigger\n_IsTriggerEnabled_Defaults=GetTriggeringTrigger\n_IsTriggerEnabled_Category=TC_TRIGGER\n\nTriggerEvaluate=0,1,boolean,trigger\n_TriggerEvaluate_Defaults=_\n_TriggerEvaluate_Category=TC_TRIGGER\n\nIsTriggerQueuedBJ=0,0,boolean,trigger\n_IsTriggerQueuedBJ_Defaults=_\n_IsTriggerQueuedBJ_Category=TC_TRIGGER\n\nIsTriggerQueueEmptyBJ=0,0,boolean\n_IsTriggerQueueEmptyBJ_Defaults=\n_IsTriggerQueueEmptyBJ_Category=TC_TRIGGER\n\nIsUnitType=0,1,boolean,unit,unittype\n_IsUnitType_Defaults=GetTriggerUnit,UnitTypeStructure\n_IsUnitType_Category=TC_UNIT\n\nIsUnitIdType=1,1,boolean,unitcode,unittype\n_IsUnitIdType_Defaults=GetUnitTypeId,UnitTypeStructure\n_IsUnitIdType_Category=TC_UNIT\n\nIsUnitInGroup=0,1,boolean,unit,group\n_IsUnitInGroup_Defaults=GetTriggerUnit,GetUnitsInRectAll\n_IsUnitInGroup_Category=TC_UNIT\n\nRectContainsUnit=0,1,boolean,rect,unit\n_RectContainsUnit_Defaults=GetPlayableMapRect,GetTriggerUnit\n_RectContainsUnit_Category=TC_UNIT\n\nIsUnitAliveBJ=0,0,boolean,unit\n_IsUnitAliveBJ_Defaults=GetTriggerUnit\n_IsUnitAliveBJ_Category=TC_UNIT\n\nIsUnitDeadBJ=0,0,boolean,unit\n_IsUnitDeadBJ_Defaults=GetTriggerUnit\n_IsUnitDeadBJ_Category=TC_UNIT\n\nIsUnitPausedBJ=0,0,boolean,unit\n_IsUnitPausedBJ_Defaults=GetTriggerUnit\n_IsUnitPausedBJ_Category=TC_UNIT\n\nIsUnitHiddenBJ=0,0,boolean,unit\n_IsUnitHiddenBJ_Defaults=GetTriggerUnit\n_IsUnitHiddenBJ_Category=TC_UNIT\n\nIsUnitIllusionBJ=0,0,boolean,unit\n_IsUnitIllusionBJ_Defaults=GetTriggerUnit\n_IsUnitIllusionBJ_Category=TC_UNIT\n\nUnitCanSleepPerm=0,0,boolean,unit\n_UnitCanSleepPerm_Defaults=GetTriggerUnit\n_UnitCanSleepPerm_Category=TC_UNIT\n\nUnitCanSleepBJ=0,0,boolean,unit\n_UnitCanSleepBJ_Defaults=GetTriggerUnit\n_UnitCanSleepBJ_Category=TC_UNIT\n\nUnitIsSleepingBJ=0,0,boolean,unit\n_UnitIsSleepingBJ_Defaults=GetTriggerUnit\n_UnitIsSleepingBJ_Category=TC_UNIT\n\nDoesUnitGenerateAlarms=1,0,boolean,unit\n_DoesUnitGenerateAlarms_Defaults=GetTriggerUnit\n_DoesUnitGenerateAlarms_Category=TC_UNIT\n\nIsUnitLoadedBJ=0,0,boolean,unit\n_IsUnitLoadedBJ_Defaults=GetTriggerUnit\n_IsUnitLoadedBJ_Category=TC_UNIT\n\nIsUnitInTransportBJ=0,0,boolean,unit,unit\n_IsUnitInTransportBJ_Defaults=GetTriggerUnit,_\n_IsUnitInTransportBJ_Category=TC_UNIT\n\nIsUnitSelected=0,1,boolean,unit,player\n_IsUnitSelected_Defaults=GetTriggerUnit,Player00\n_IsUnitSelected_Category=TC_UNIT\n\nIsUnitAlly=0,1,boolean,unit,player\n_IsUnitAlly_Defaults=GetTriggerUnit,Player00\n_IsUnitAlly_Category=TC_UNIT\n\nIsUnitEnemy=0,1,boolean,unit,player\n_IsUnitEnemy_Defaults=GetTriggerUnit,Player00\n_IsUnitEnemy_Category=TC_UNIT\n\nUnitHasBuffBJ=1,1,boolean,unit,buffcode\n_UnitHasBuffBJ_Defaults=GetTriggerUnit,_\n_UnitHasBuffBJ_Category=TC_UNIT\n\nIsUnitGroupEmptyBJ=0,1,boolean,group\n_IsUnitGroupEmptyBJ_Defaults=_\n_IsUnitGroupEmptyBJ_Category=TC_UNITGROUP\n\nIsUnitGroupInRectBJ=0,1,boolean,group,rect\n_IsUnitGroupInRectBJ_Defaults=_\n_IsUnitGroupInRectBJ_Category=TC_UNITGROUP\n\nIsUnitGroupDeadBJ=0,1,boolean,group\n_IsUnitGroupDeadBJ_Defaults=_\n_IsUnitGroupDeadBJ_Category=TC_UNITGROUP\n\nIsFogEnabled=0,1,boolean\n_IsFogEnabled_Defaults=\n_IsFogEnabled_Category=TC_VISIBILITY\n\nIsFogMaskEnabled=0,1,boolean\n_IsFogMaskEnabled_Defaults=\n_IsFogMaskEnabled_Category=TC_VISIBILITY\n\nIsUnitVisible=0,1,boolean,unit,player\n_IsUnitVisible_Defaults=GetTriggerUnit,Player00\n_IsUnitVisible_Category=TC_VISIBILITY\n\nIsUnitInvisible=0,1,boolean,unit,player\n_IsUnitInvisible_Defaults=GetTriggerUnit,Player00\n_IsUnitInvisible_Category=TC_VISIBILITY\n\nIsUnitFogged=0,1,boolean,unit,player\n_IsUnitFogged_Defaults=GetTriggerUnit,Player00\n_IsUnitFogged_Category=TC_VISIBILITY\n\nIsUnitMasked=0,1,boolean,unit,player\n_IsUnitMasked_Defaults=GetTriggerUnit,Player00\n_IsUnitMasked_Category=TC_VISIBILITY\n\nIsLocationVisibleToPlayer=0,1,boolean,location,player\n_IsLocationVisibleToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationVisibleToPlayer_Category=TC_VISIBILITY\n\nIsLocationFoggedToPlayer=0,1,boolean,location,player\n_IsLocationFoggedToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationFoggedToPlayer_Category=TC_VISIBILITY\n\nIsLocationMaskedToPlayer=0,1,boolean,location,player\n_IsLocationMaskedToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationMaskedToPlayer_Category=TC_VISIBILITY\n\n\n// returns integer\nOperatorInt=0,1,integer,integer,ArithmeticOperator,integer\n_OperatorInt_Defaults=_,OperatorAdd,1\n_OperatorInt_Category=TC_ARITHMETIC\n_OperatorInt_UseWithAI=1\n\nGetForLoopIndexA=0,0,integer\n_GetForLoopIndexA_Defaults=\n_GetForLoopIndexA_Category=TC_FORLOOP\n\nGetForLoopIndexB=0,0,integer\n_GetForLoopIndexB_Defaults=\n_GetForLoopIndexB_Category=TC_FORLOOP\n\nStringLength=1,1,integer,string\n_StringLength_Defaults=GetEventPlayerChatString\n_StringLength_Category=TC_NOTHING\n\nR2I=0,1,integer,real\n_R2I_Defaults=GetUnitStateSwap\n_R2I_Category=TC_CONVERSION\n\nS2I=0,1,integer,string\n_S2I_Defaults=GetEventPlayerChatString\n_S2I_Category=TC_CONVERSION\n\nGetElevatorHeight=1,1,integer,destructable\n_GetElevatorHeight_Defaults=_\n_GetElevatorHeight_Category=TC_DESTRUCT\n\nGetTerrainCliffLevelBJ=1,1,integer,location\n_GetTerrainCliffLevelBJ_Defaults=GetRectCenter\n_GetTerrainCliffLevelBJ_Category=TC_ENVIRONMENT\n\nGetTerrainVarianceBJ=1,1,integer,location\n_GetTerrainVarianceBJ_Defaults=GetRectCenter\n_GetTerrainVarianceBJ_Category=TC_ENVIRONMENT\n\nGetLearnedSkillLevel=0,0,integer\n_GetLearnedSkillLevel_Defaults=\n_GetLearnedSkillLevel_Category=TC_EVENTRESPONSE\n\nGetPlayers=0,1,integer\n_GetPlayers_Defaults=\n_GetPlayers_Category=TC_GAME\n\nGetTeams=0,1,integer\n_GetTeams_Defaults=\n_GetTeams_Category=TC_GAME\n\nGetAllyColorFilterState=1,1,integer\n_GetAllyColorFilterState_Defaults=\n_GetAllyColorFilterState_Category=TC_GAME\n\nGetTournamentFinishNowRule=1,0,integer\n_GetTournamentFinishNowRule_Defaults=\n_GetTournamentFinishNowRule_Category=TC_GAME\n\nGetTournamentScore=1,0,integer,player\n_GetTournamentScore_Defaults=Player00\n_GetTournamentScore_Category=TC_GAME\n\nGetAbilityPosX=1,1,integer,abilcode\n_GetAbilityPosX_Defaults=_\n_GetAbilityPosX_Category=TC_GAME\n\nGetAbilityOnPosX=1,1,integer,abilcode\n_GetAbilityOnPosX_Defaults=_\n_GetAbilityOnPosX_Category=TC_GAME\n\nGetAbilityPosY=1,1,integer,abilcode\n_GetAbilityPosY_Defaults=_\n_GetAbilityPosY_Category=TC_GAME\n\nGetAbilityOnPosY=1,1,integer,abilcode\n_GetAbilityOnPosY_Defaults=_\n_GetAbilityOnPosY_Category=TC_GAME\n\nGetStoredIntegerBJ=0,0,integer,string,string,gamecache\n_GetStoredIntegerBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredIntegerBJ_Category=TC_GAMECACHE\n\nGetHeroLevel=0,1,integer,unit\n_GetHeroLevel_Defaults=GetTriggerUnit\n_GetHeroLevel_Category=TC_HERO\n\nGetHeroXP=0,1,integer,unit\n_GetHeroXP_Defaults=GetTriggerUnit\n_GetHeroXP_Category=TC_HERO\n\nGetHeroStatBJ=1,1,integer,herostat,unit,includeoption\n_GetHeroStatBJ_Defaults=HeroStatStr,_,InclusionExclude\n_GetHeroStatBJ_Category=TC_HERO\n\nGetHeroSkillPoints=1,1,integer,unit\n_GetHeroSkillPoints_Defaults=_\n_GetHeroSkillPoints_Category=TC_HERO\n\nGetItemLevel=1,1,integer,item\n_GetItemLevel_Defaults=GetLastCreatedItem\n_GetItemLevel_Category=TC_ITEM\n\nGetItemCharges=1,1,integer,item\n_GetItemCharges_Defaults=GetLastCreatedItem\n_GetItemCharges_Category=TC_ITEM\n\nGetItemUserData=1,1,integer,item\n_GetItemUserData_Defaults=_\n_GetItemUserData_Category=TC_ITEM\n\nLeaderboardGetPlayerIndexBJ=0,0,integer,player,leaderboard\n_LeaderboardGetPlayerIndexBJ_Defaults=Player00,GetLastCreatedLeaderboard\n_LeaderboardGetPlayerIndexBJ_Category=TC_LEADERBOARD\n\nGetRandomInt=0,1,integer,integer,integer\n_GetRandomInt_Defaults=1,10\n_GetRandomInt_Category=TC_MATH\n\nIMinBJ=0,1,integer,integer,integer\n_IMinBJ_Defaults=_,_\n_IMinBJ_Category=TC_MATH\n\nIMaxBJ=0,1,integer,integer,integer\n_IMaxBJ_Defaults=_,_\n_IMaxBJ_Category=TC_MATH\n\nIAbsBJ=0,1,integer,integer\n_IAbsBJ_Defaults=_\n_IAbsBJ_Category=TC_MATH\n\nISignBJ=0,1,integer,integer\n_ISignBJ_Defaults=_\n_ISignBJ_Category=TC_MATH\n\nModuloInteger=0,1,integer,integer,integer\n_ModuloInteger_Defaults=_,_\n_ModuloInteger_Category=TC_MATH\n\nMultiboardGetRowCount=1,1,integer,multiboard\n_MultiboardGetRowCount_Defaults=GetLastCreatedMultiboard\n_MultiboardGetRowCount_Category=TC_MULTIBOARD\n\nMultiboardGetColumnCount=1,1,integer,multiboard\n_MultiboardGetColumnCount_Defaults=GetLastCreatedMultiboard\n_MultiboardGetColumnCount_Category=TC_MULTIBOARD\n\nGetResourceAmount=0,1,integer,unit\n_GetResourceAmount_Defaults=_\n_GetResourceAmount_Category=TC_NEUTRALBUILDING\n\nGetPlayerState=0,1,integer,player,playerstate\n_GetPlayerState_Defaults=Player00,PlayerStateGold\n_GetPlayerState_Category=TC_PLAYER\n\nGetPlayerTaxRateBJ=1,1,integer,playerresource,player,player\n_GetPlayerTaxRateBJ_Defaults=PlayerResourceGold,Player00,Player01\n_GetPlayerTaxRateBJ_Category=TC_PLAYER\n\nGetPlayerScore=1,1,integer,player,playerscore\n_GetPlayerScore_Defaults=Player00,PlayerScoreTotal\n_GetPlayerScore_Category=TC_PLAYER\n\nGetConvertedPlayerId=0,1,integer,player\n_GetConvertedPlayerId_Defaults=GetTriggerPlayer\n_GetConvertedPlayerId_Category=TC_PLAYER\n\nGetPlayerStructureCount=0,1,integer,player,includeoption\n_GetPlayerStructureCount_Defaults=Player00,InclusionExclude\n_GetPlayerStructureCount_Category=TC_PLAYER\n\nGetPlayerUnitCount=0,1,integer,player,includeoption\n_GetPlayerUnitCount_Defaults=Player00,InclusionExclude\n_GetPlayerUnitCount_Category=TC_PLAYER\n\nGetPlayerTechCountSimple=0,1,integer,techcode,player\n_GetPlayerTechCountSimple_Defaults=_,Player00\n_GetPlayerTechCountSimple_Category=TC_PLAYER\n\nGetPlayerTechMaxAllowedSwap=0,1,integer,techcode,player\n_GetPlayerTechMaxAllowedSwap_Defaults=_,Player00\n_GetPlayerTechMaxAllowedSwap_Category=TC_PLAYER\n\nGetPlayerTeam=0,1,integer,player\n_GetPlayerTeam_Defaults=Player00\n_GetPlayerTeam_Category=TC_PLAYER\n\nCountPlayersInForceBJ=0,1,integer,force\n_CountPlayersInForceBJ_Defaults=GetPlayersByMapControl\n_CountPlayersInForceBJ_Category=TC_PLAYER\n\nGetTriggerPlayerMouseButton=1,1,mousebuttontype\n_GetTriggerPlayerMouseButton_Defaults=\n_GetTriggerPlayerMouseButton_Category=TC_PLAYER\n\nCountUnitsInGroup=0,1,integer,group\n_CountUnitsInGroup_Defaults=GetUnitsInRectAll\n_CountUnitsInGroup_Category=TC_UNIT\n\nCountLivingPlayerUnitsOfTypeId=1,1,integer,unitcode,player\n_CountLivingPlayerUnitsOfTypeId_Defaults=hfoo,Player00\n_CountLivingPlayerUnitsOfTypeId_Category=TC_UNIT\n\nGetUnitFoodUsed=0,1,integer,unit\n_GetUnitFoodUsed_Defaults=GetTriggerUnit\n_GetUnitFoodUsed_Category=TC_UNIT\n\nGetUnitFoodMade=0,1,integer,unit\n_GetUnitFoodMade_Defaults=GetTriggerUnit\n_GetUnitFoodMade_Category=TC_UNIT\n\nGetFoodUsed=1,1,integer,unitcode\n_GetFoodUsed_Defaults=hfoo\n_GetFoodUsed_Category=TC_UNIT\n\nGetFoodMade=0,1,integer,unitcode\n_GetFoodMade_Defaults=hfoo\n_GetFoodMade_Category=TC_UNIT\n\nGetUnitPointValue=0,1,integer,unit\n_GetUnitPointValue_Defaults=GetTriggerUnit\n_GetUnitPointValue_Category=TC_UNIT\n\nGetUnitPointValueByType=0,1,integer,unitcode\n_GetUnitPointValueByType_Defaults=hfoo\n_GetUnitPointValueByType_Category=TC_UNIT\n\nGetUnitUserData=1,1,integer,unit\n_GetUnitUserData_Defaults=_\n_GetUnitUserData_Category=TC_UNIT\n\nGetUnitLevel=1,1,integer,unit\n_GetUnitLevel_Defaults=GetTriggerUnit\n_GetUnitLevel_Category=TC_UNIT\n\nGetUnitAbilityLevelSwapped=1,1,integer,abilcode,unit\n_GetUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_GetUnitAbilityLevelSwapped_Category=TC_UNIT\n\nUnitInventoryCount=1,1,integer,unit\n_UnitInventoryCount_Defaults=GetTriggerUnit\n_UnitInventoryCount_Category=TC_UNIT\n\nUnitInventorySizeBJ=1,1,integer,unit\n_UnitInventorySizeBJ_Defaults=GetTriggerUnit\n_UnitInventorySizeBJ_Category=TC_UNIT\n\nUnitCountBuffsExBJ=1,1,integer,buffpolarity,buffresist,unit,includeoption,includeoption\n_UnitCountBuffsExBJ_Defaults=BuffPolarityEither,BuffResistEither,GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitCountBuffsExBJ_Category=TC_UNIT\n\nGetUnitMaxHP=0,1,integer,unit\n_GetUnitMaxHP_Defaults=GetTriggerUnit\n_GetUnitMaxHP_Category=TC_UNIT\n\nGetUnitMaxMana=0,1,integer,unit\n_GetUnitMaxMana_Defaults=GetTriggerUnit\n_GetUnitMaxMana_Category=TC_UNIT\n\nGetUnitBaseDamage=0,1,integer,unit,integer\n_GetUnitBaseDamage_Defaults=GetTriggerUnit,1\n_GetUnitBaseDamage_Category=TC_UNIT\n\nGetUnitDiceNumber=0,1,integer,unit,integer\n_GetUnitDiceNumber_Defaults=GetTriggerUnit,1\n_GetUnitDiceNumber_Category=TC_UNIT\n\nGetUnitDiceSides=0,1,integer,unit,integer\n_GetUnitDiceSides_Defaults=GetTriggerUnit,1\n_GetUnitDiceSides_Category=TC_UNIT\n\nGetTriggerEvalCount=0,1,integer,trigger\n_GetTriggerEvalCount_Defaults=GetTriggeringTrigger\n_GetTriggerEvalCount_Category=TC_TRIGGER\n\nGetTriggerExecCount=0,1,integer,trigger\n_GetTriggerExecCount_Defaults=GetTriggeringTrigger\n_GetTriggerExecCount_Category=TC_TRIGGER\n\nQueuedTriggerCountBJ=0,0,integer\n_QueuedTriggerCountBJ_Defaults=\n_QueuedTriggerCountBJ_Category=TC_TRIGGER\n\nGetAbilityManaCost=0,1,integer,abilcode,integer\n_GetAbilityManaCost_Defaults=_,1\n_GetAbilityManaCost_Limits=_,_,1,_\n_GetAbilityManaCost_Category=TC_GAME\n\nGetUnitAbilityManaCost=0,1,integer,unit,abilcode,integer\n_GetUnitAbilityManaCost_Defaults=GetTriggerUnit,_,1\n_GetUnitAbilityManaCost_Limits-_,_,_,_,1,_\n_GetUnitAbilityManaCost_Category=TC_UNIT\n\n// returns real\nOperatorReal=0,1,real,real,ArithmeticOperator,real\n_OperatorReal_Defaults=1,OperatorAdd,1\n_OperatorReal_Category=TC_ARITHMETIC\n\nGetLocationX=0,1,real,location\n_GetLocationX_Defaults=GetRectCenter\n_GetLocationX_Category=TC_NOTHING\n\nGetLocationY=0,1,real,location\n_GetLocationY_Defaults=GetRectCenter\n_GetLocationY_Category=TC_NOTHING\n\nCameraSetupGetFieldSwap=0,1,real,camerafield,camerasetup\n_CameraSetupGetFieldSwap_Defaults=CameraFieldTargetDistance,_\n_CameraSetupGetFieldSwap_Category=TC_CAMERA\n\nGetCameraField=0,1,real,camerafield\n_GetCameraField_Defaults=CameraFieldTargetDistance\n_GetCameraField_Category=TC_CAMERA\n\nGetCameraTargetPositionX=0,1,real\n_GetCameraTargetPositionX_Defaults=\n_GetCameraTargetPositionX_Category=TC_CAMERA\n\nGetCameraTargetPositionY=0,1,real\n_GetCameraTargetPositionY_Defaults=\n_GetCameraTargetPositionY_Category=TC_CAMERA\n\nGetCameraTargetPositionZ=0,1,real\n_GetCameraTargetPositionZ_Defaults=\n_GetCameraTargetPositionZ_Category=TC_CAMERA\n\nGetCameraEyePositionX=0,1,real\n_GetCameraEyePositionX_Defaults=\n_GetCameraEyePositionX_Category=TC_CAMERA\n\nGetCameraEyePositionY=0,1,real\n_GetCameraEyePositionY_Defaults=\n_GetCameraEyePositionY_Category=TC_CAMERA\n\nGetCameraEyePositionZ=0,1,real\n_GetCameraEyePositionZ_Defaults=\n_GetCameraEyePositionZ_Category=TC_CAMERA\n\nGetLastTransmissionDurationBJ=0,1,real\n_GetLastTransmissionDurationBJ_Defaults=\n_GetLastTransmissionDurationBJ_Category=TC_CINEMATIC\n\nI2R=0,1,real,integer\n_I2R_Defaults=GetUnitPointValueByType\n_I2R_Category=TC_CONVERSION\n\nS2R=0,1,real,string\n_S2R_Defaults=GetEventPlayerChatString\n_S2R_Category=TC_CONVERSION\n\nDeg2Rad=0,1,real,real\n_Deg2Rad_Defaults=0\n_Deg2Rad_Category=TC_CONVERSION\n\nRad2Deg=0,1,real,real\n_Rad2Deg_Defaults=0\n_Rad2Deg_Category=TC_CONVERSION\n\nTimerGetElapsed=0,1,real,timer\n_TimerGetElapsed_Defaults=_\n_TimerGetElapsed_Category=TC_TIMER\n\nTimerGetRemaining=0,1,real,timer\n_TimerGetRemaining_Defaults=_\n_TimerGetRemaining_Category=TC_TIMER\n\nTimerGetTimeout=0,1,real,timer\n_TimerGetTimeout_Defaults=_\n_TimerGetTimeout_Category=TC_TIMER\n\nGetDestructableLife=0,1,real,destructable\n_GetDestructableLife_Defaults=GetLastCreatedDestructable\n_GetDestructableLife_Category=TC_DESTRUCT\n\nGetDestructableMaxLife=0,1,real,destructable\n_GetDestructableMaxLife_Defaults=GetLastCreatedDestructable\n_GetDestructableMaxLife_Category=TC_DESTRUCT\n\nGetDestructableOccluderHeight=1,1,real,destructable\n_GetDestructableOccluderHeight_Defaults=GetLastCreatedDestructable\n_GetDestructableOccluderHeight_Category=TC_DESTRUCT\n\nGetEventDamage=0,0,real\n_GetEventDamage_Defaults=\n_GetEventDamage_Category=TC_EVENTRESPONSE\n\nGetTournamentFinishSoonTimeRemaining=1,0,real\n_GetTournamentFinishSoonTimeRemaining_Defaults=\n_GetTournamentFinishSoonTimeRemaining_Category=TC_EVENTRESPONSE\n\nGetTimeOfDay=0,1,real\n_GetTimeOfDay_Defaults=\n_GetTimeOfDay_Category=TC_GAME\n\nGetTimeOfDayScalePercentBJ=0,1,real\n_GetTimeOfDayScalePercentBJ_Defaults=\n_GetTimeOfDayScalePercentBJ_Category=TC_GAME\n\nGetStoredRealBJ=0,0,real,string,string,gamecache\n_GetStoredRealBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredRealBJ_Category=TC_GAMECACHE\n\nGetItemLifeBJ=0,0,real,item\n_GetItemLifeBJ_Defaults=GetLastCreatedItem\n_GetItemLifeBJ_Category=TC_ITEM\n\nGetLightningColorRBJ=1,0,real,lightning\n_GetLightningColorRBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorRBJ_Category=TC_LIGHTNING\n\nGetLightningColorGBJ=1,0,real,lightning\n_GetLightningColorGBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorGBJ_Category=TC_LIGHTNING\n\nGetLightningColorBBJ=1,0,real,lightning\n_GetLightningColorBBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorBBJ_Category=TC_LIGHTNING\n\nGetLightningColorABJ=1,0,real,lightning\n_GetLightningColorABJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorABJ_Category=TC_LIGHTNING\n\nGetRandomReal=0,1,real,real,real\n_GetRandomReal_Defaults=0,1\n_GetRandomReal_Category=TC_MATH\n\nGetRandomDirectionDeg=0,1,real\n_GetRandomDirectionDeg_Defaults=\n_GetRandomDirectionDeg_Category=TC_MATH\n\nGetRandomPercentageBJ=0,1,real\n_GetRandomPercentageBJ_Defaults=\n_GetRandomPercentageBJ_Category=TC_MATH\n\nDistanceBetweenPoints=0,1,real,location,location\n_DistanceBetweenPoints_Defaults=GetUnitLoc,GetUnitLoc\n_DistanceBetweenPoints_Category=TC_MATH\n\nAngleBetweenPoints=0,1,real,location,location\n_AngleBetweenPoints_Defaults=GetUnitLoc,GetUnitLoc\n_AngleBetweenPoints_Category=TC_MATH\n\nRMinBJ=0,1,real,real,real\n_RMinBJ_Defaults=_,_\n_RMinBJ_Category=TC_MATH\n\nRMaxBJ=0,1,real,real,real\n_RMaxBJ_Defaults=_,_\n_RMaxBJ_Category=TC_MATH\n\nRAbsBJ=0,1,real,real\n_RAbsBJ_Defaults=_\n_RAbsBJ_Category=TC_MATH\n\nRSignBJ=0,1,real,real\n_RSignBJ_Defaults=_\n_RSignBJ_Category=TC_MATH\n\nModuloReal=0,1,real,real,real\n_ModuloReal_Defaults=_,_\n_ModuloReal_Category=TC_MATH\n\nPow=0,1,real,real,real\n_Pow_Defaults=_,_\n_Pow_Category=TC_MATH\n\nSquareRoot=0,1,real,real\n_SquareRoot_Defaults=_\n_SquareRoot_Limits=0,_\n_SquareRoot_Category=TC_MATH\n\nSinBJ=0,1,real,real\n_SinBJ_Defaults=GetUnitFacing\n_SinBJ_Category=TC_MATH\n\nCosBJ=0,1,real,real\n_CosBJ_Defaults=GetUnitFacing\n_CosBJ_Category=TC_MATH\n\nTanBJ=0,1,real,real\n_TanBJ_Defaults=GetUnitFacing\n_TanBJ_Category=TC_MATH\n\nAsinBJ=0,1,real,real\n_AsinBJ_Defaults=_\n_AsinBJ_Limits=-1,1\n_AsinBJ_Category=TC_MATH\n\nAcosBJ=0,1,real,real\n_AcosBJ_Defaults=_\n_AcosBJ_Limits=-1,1\n_AcosBJ_Category=TC_MATH\n\nAtanBJ=0,1,real,real\n_AtanBJ_Defaults=_\n_AtanBJ_Category=TC_MATH\n\nAtan2BJ=0,1,real,real,real\n_Atan2BJ_Defaults=_,_\n_Atan2BJ_Category=TC_MATH\n\nGetPlayerHandicapXPBJ=0,0,real,player\n_GetPlayerHandicapXPBJ_Defaults=Player00\n_GetPlayerHandicapXPBJ_Category=TC_PLAYER\n\nGetPlayerHandicapBJ=0,0,real,player\n_GetPlayerHandicapBJ_Defaults=Player00\n_GetPlayerHandicapBJ_Category=TC_PLAYER\n\nGetTriggerPlayerMouseX=1,1,real\n_GetTriggerPlayerMouseX_Defaults=\n_GetTriggerPlayerMouseX_Category=TC_PLAYER\n\nGetTriggerPlayerMouseY=1,1,real\n_GetTriggerPlayerMouseY_Defaults=\n_GetTriggerPlayerMouseY_Category=TC_PLAYER\n\nGetTriggerPlayerMousePosition=1,1,location\n_GetTriggerPlayerMousePosition_Defaults=\n_GetTriggerPlayerMousePosition_Category=TC_PLAYER\n\nGetRectCenterX=0,1,real,rect\n_GetRectCenterX_Defaults=GetPlayableMapRect\n_GetRectCenterX_Category=TC_REGION\n\nGetRectCenterY=0,1,real,rect\n_GetRectCenterY_Defaults=GetPlayableMapRect\n_GetRectCenterY_Category=TC_REGION\n\nGetRectMinX=0,1,real,rect\n_GetRectMinX_Defaults=GetPlayableMapRect\n_GetRectMinX_Category=TC_REGION\n\nGetRectMinY=0,1,real,rect\n_GetRectMinY_Defaults=GetPlayableMapRect\n_GetRectMinY_Category=TC_REGION\n\nGetRectMaxX=0,1,real,rect\n_GetRectMaxX_Defaults=GetPlayableMapRect\n_GetRectMaxX_Category=TC_REGION\n\nGetRectMaxY=0,1,real,rect\n_GetRectMaxY_Defaults=GetPlayableMapRect\n_GetRectMaxY_Category=TC_REGION\n\nGetRectWidthBJ=0,1,real,rect\n_GetRectWidthBJ_Defaults=_\n_GetRectWidthBJ_Category=TC_REGION\n\nGetRectHeightBJ=0,1,real,rect\n_GetRectHeightBJ_Defaults=_\n_GetRectHeightBJ_Category=TC_REGION\n\nGetSoundDurationBJ=0,1,real,sound\n_GetSoundDurationBJ_Defaults=GetLastPlayedSound\n_GetSoundDurationBJ_Category=TC_SOUND\n\nGetSoundFileDurationBJ=0,1,real,musicfile\n_GetSoundFileDurationBJ_Defaults=GetLastPlayedMusic\n_GetSoundFileDurationBJ_Category=TC_SOUND\n\nGetUnitStateSwap=0,1,real,unitstate,unit\n_GetUnitStateSwap_Defaults=UnitStateLife,GetTriggerUnit\n_GetUnitStateSwap_Category=TC_UNIT\n\nGetUnitLifePercent=1,1,real,unit\n_GetUnitLifePercent_Defaults=GetTriggerUnit\n_GetUnitLifePercent_Category=TC_UNIT\n\nGetUnitManaPercent=1,1,real,unit\n_GetUnitManaPercent_Defaults=GetTriggerUnit\n_GetUnitManaPercent_Category=TC_UNIT\n\nGetUnitFacing=0,1,real,unit\n_GetUnitFacing_Defaults=GetTriggerUnit\n_GetUnitFacing_Category=TC_UNIT\n\nGetUnitMoveSpeed=0,1,real,unit\n_GetUnitMoveSpeed_Defaults=GetTriggerUnit\n_GetUnitMoveSpeed_Category=TC_UNIT\n\nGetUnitDefaultMoveSpeed=0,1,real,unit\n_GetUnitDefaultMoveSpeed_Defaults=GetTriggerUnit\n_GetUnitDefaultMoveSpeed_Category=TC_UNIT\n\nGetUnitAcquireRange=0,1,real,unit\n_GetUnitAcquireRange_Defaults=GetTriggerUnit\n_GetUnitAcquireRange_Category=TC_UNIT\n\nGetUnitDefaultAcquireRange=0,1,real,unit\n_GetUnitDefaultAcquireRange_Defaults=GetTriggerUnit\n_GetUnitDefaultAcquireRange_Category=TC_UNIT\n\nGetUnitTurnSpeed=0,1,real,unit\n_GetUnitTurnSpeed_Defaults=GetTriggerUnit\n_GetUnitTurnSpeed_Category=TC_UNIT\n\nGetUnitDefaultTurnSpeed=0,1,real,unit\n_GetUnitDefaultTurnSpeed_Defaults=GetTriggerUnit\n_GetUnitDefaultTurnSpeed_Category=TC_UNIT\n\nGetUnitPropWindowBJ=0,1,real,unit\n_GetUnitPropWindowBJ_Defaults=GetTriggerUnit\n_GetUnitPropWindowBJ_Category=TC_UNIT\n\nGetUnitDefaultPropWindowBJ=0,1,real,unit\n_GetUnitDefaultPropWindowBJ_Defaults=GetTriggerUnit\n_GetUnitDefaultPropWindowBJ_Category=TC_UNIT\n\nGetUnitFlyHeight=0,1,real,unit\n_GetUnitFlyHeight_Defaults=GetTriggerUnit\n_GetUnitFlyHeight_Category=TC_UNIT\n\nGetUnitDefaultFlyHeight=0,1,real,unit\n_GetUnitDefaultFlyHeight_Defaults=GetTriggerUnit\n_GetUnitDefaultFlyHeight_Category=TC_UNIT\n\nGetUnitAttackCooldown=0,1,real,unit,integer\n_GetUnitAttackCooldown_Defaults=GetTriggerUnit,1\n_GetUnitAttackCooldown_Category=TC_UNIT\n\nGetUnitArmor=0,1,real,unit\n_GetUnitArmor_Defaults=GetTriggerUnit\n_GetUnitArmor_Category=TC_UNIT\n\nGetAbilityCooldown=0,1,real,abilcode,integer\n_GetAbilityCooldown_Defaults=_,1\n_GetAbilityCooldown_Limits=_,_,1,_\n_GetAbilityCooldown_Category=TC_GAME\n\nGetUnitAbilityCooldown=0,1,real,unit,abilcode,integer\n_GetUnitAbilityCooldown_Defaults=GetTriggerUnit,_,1\n_GetUnitAbilityCooldown_Limits=_,_,_,_,1,_\n_GetUnitAbilityCooldown_Category=TC_UNIT\n\nGetUnitAbilityCooldownRemaining=0,1,real,unit,abilcode\n_GetUnitAbilityCooldownRemaining_Defaults=GetTriggerUnit,_\n_GetUnitAbilityCooldownRemaining_Category=TC_UNIT\n\nGetUnitCollisionSize=0,1,real,unit\n_GetUnitCollisionSize=GetTriggerUnit\n_GetUnitCollisionSize=TC_UNIT\n\nGetLocalUnitZ=0,1,real,unit\n_GetLocalUnitZ_Defaults=GetTriggerUnit\n_GetLocalUnitZ_Category=TC_UNIT\n\nGetLocalSpecialEffectX=0,1,real,effect\n_GetLocalSpecialEffectX_Defaults=GetLastCreatedEffectBJ\n_GetLocalSpecialEffectX_Category=TC_SPECIALEFFECT\n\nGetLocalSpecialEffectY=0,1,real,effect\n_GetLocalSpecialEffectY_Defaults=GetLastCreatedEffectBJ\n_GetLocalSpecialEffectY_Category=TC_SPECIALEFFECT\n\nGetLocalSpecialEffectZ=0,1,real,effect\n_GetLocalSpecialEffectZ_Defaults=GetLastCreatedEffectBJ\n_GetLocalSpecialEffectZ_Category=TC_SPECIALEFFECT\n\n\n// returns string\nOperatorString=0,1,string,string,string\n_OperatorString_Defaults=_,_\n_OperatorString_Category=TC_NOTHING\n\nSubStringBJ=0,1,string,string,integer,integer\n_SubStringBJ_Defaults=_,1,5\n_SubStringBJ_Category=TC_NOTHING\n\n\n\nI2S=0,1,string,integer\n_I2S_Defaults=GetConvertedPlayerId\n_I2S_Category=TC_CONVERSION\n\nR2S=0,1,string,real\n_R2S_Defaults=GetUnitStateSwap\n_R2S_Category=TC_CONVERSION\n\nR2SW=0,1,string,real,integer,integer\n_R2SW_Defaults=GetUnitStateSwap,1,2\n_R2SW_Limits=_,_,0,_,0,_\n_R2SW_Category=TC_CONVERSION\n\nOrderId2StringBJ=0,1,string,ordercode\n_OrderId2StringBJ_Defaults=GetIssuedOrderIdBJ\n_OrderId2StringBJ_Category=TC_CONVERSION\n\nUnitId2StringBJ=0,1,string,unitcode\n_UnitId2StringBJ_Defaults=GetUnitTypeId\n_UnitId2StringBJ_Category=TC_CONVERSION\n\nStringIdentity=1,0,string,StringExt\n_StringIdentity_Defaults=_\n_StringIdentity_Category=TC_CONVERSION\n\nStringCase=1,1,string,StringExt,stringcaseoption\n_StringCase_Defaults=_,StringCaseLower\n_StringCase_Category=TC_CONVERSION\n\nGetDestructableName=1,1,string,destructable\n_GetDestructableName_Defaults=GetLastCreatedDestructable\n_GetDestructableName_Category=TC_DESTRUCT\n\nGetEventPlayerChatString=0,0,string\n_GetEventPlayerChatString_Defaults=\n_GetEventPlayerChatString_Category=TC_EVENTRESPONSE\n\nGetEventPlayerChatStringMatched=0,0,string\n_GetEventPlayerChatStringMatched_Defaults=\n_GetEventPlayerChatStringMatched_Category=TC_EVENTRESPONSE\n\nGetSaveBasicFilename=1,0,string\n_GetSaveBasicFilename_Defaults=\n_GetSaveBasicFilename_Category=TC_EVENTRESPONSE\n\nGetAbilityName=1,1,string,abilcode\n_GetAbilityName_Defaults=_\n_GetAbilityName_Category=TC_GAME\n\nGetAbilityEffectBJ=1,1,string,abilcode,effecttype,integer\n_GetAbilityEffectBJ_Defaults=_,EffectTypeEffect,0\n_GetAbilityEffectBJ_Category=TC_GAME\n\nGetAbilitySoundBJ=1,1,string,abilcode,soundtype\n_GetAbilitySoundBJ_Defaults=_,SoundTypeEffect\n_GetAbilitySoundBJ_Category=TC_GAME\n\nGetAbilityTooltip=1,1,string,abilcode,integer\n_GetAbilityTooltip_Defaults=_,1\n_GetAbilityTooltip_Limits=_,_,1,_\n_GetAbilityTooltip_Category=TC_GAME\n\nGetAbilityOnTooltip=1,1,string,abilcode,integer\n_GetAbilityOnTooltip_Defaults=_,1\n_GetAbilityOnTooltip_Limits=_,_,1,_\n_GetAbilityOnTooltip_Category=TC_GAME\n\nGetAbilityExtendedTooltip=1,1,string,abilcode,integer\n_GetAbilityExtendedTooltip_Defaults=_,1\n_GetAbilityExtendedTooltip_Limits=_,_,1,_\n_GetAbilityExtendedTooltip_Category=TC_GAME\n\nGetAbilityOnExtendedTooltip=1,1,string,abilcode,integer\n_GetAbilityOnExtendedTooltip_Defaults=_,1\n_GetAbilityOnExtendedTooltip_Limits=_,_,1,_\n_GetAbilityOnExtendedTooltip_Category=TC_GAME\n\nGetAbilityResearchTooltip=1,1,string,abilcode,integer\n_GetAbilityResearchTooltip_Defaults=_,1\n_GetAbilityResearchTooltip_Limits=_,_,1,_\n_GetAbilityResearchTooltip_Category=TC_GAME\n\nGetAbilityResearchExtendedTooltip=1,1,string,abilcode,integer\n_GetAbilityResearchExtendedTooltip_Defaults=_,1\n_GetAbilityResearchExtendedTooltip_Limits=_,_,1,_\n_GetAbilityResearchExtendedTooltip_Category=TC_GAME\n\nGetAbilityIcon=1,1,string,abilcode,integer\n_GetAbilityIcon_Defaults=_,1\n_GetAbilityIcon_Limits=_,_,1,_\n_GetAbilityIcon_Category=TC_GAME\n\nGetAbilityOnIcon=1,1,string,abilcode,integer\n_GetAbilityOnIcon_Defaults=_,1\n_GetAbilityOnIcon_Limits=_,_,1,_\n_GetAbilityOnIcon_Category=TC_GAME\n\nGetStoredStringBJ=1,0,string,string,string,gamecache\n_GetStoredStringBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredStringBJ_Category=TC_GAMECACHE\n\nGetHeroProperName=1,1,string,unit\n_GetHeroProperName_Defaults=GetTriggerUnit\n_GetHeroProperName_Category=TC_HERO\n\nGetItemName=1,1,string,item\n_GetItemName_Defaults=GetLastCreatedItem\n_GetItemName_Category=TC_ITEM\n\nGetItemDescription=1,1,string,item\n_GetItemDescription_Defaults=GetLastCreatedItem\n_GetItemDescription_Category=TC_ITEM\n\nGetItemTooltip=1,1,string,item\n_GetItemTooltip_Defaults=GetLastCreatedItem\n_GetItemTooltip_Category=TC_ITEM\n\nGetItemExtendedTooltip=1,1,string,item\n_GetItemExtendedTooltip_Defaults=GetLastCreatedItem\n_GetItemExtendedTooltip_Category=TC_ITEM\n\nGetItemIconPath=1,1,string,item\n_GetItemIconPath_Defaults=GetLastCreatedItem\n_GetItemIconPath_Category=TC_ITEM\n\nMultiboardGetTitleText=1,1,string,multiboard\n_MultiboardGetTitleText_Defaults=GetLastCreatedMultiboard\n_MultiboardGetTitleText_Category=TC_MULTIBOARD\n\nGetPlayerName=0,1,string,player\n_GetPlayerName_Defaults=GetTriggerPlayer\n_GetPlayerName_Category=TC_PLAYER\n\nGetTriggerName=1,1,string\n_GetTriggerName_Defaults=\n_GetTriggerName_Category=TC_TRIGGER\n\nGetUnitName=0,1,string,unit\n_GetUnitName_Defaults=GetTriggerUnit\n_GetUnitName_Category=TC_UNIT\n\n\n// returns location\nGetRectCenter=0,1,location,rect\n_GetRectCenter_Defaults=GetPlayableMapRect\n_GetRectCenter_Category=TC_NOTHING\n\nGetRandomLocInRect=0,1,location,rect\n_GetRandomLocInRect_Defaults=GetPlayableMapRect\n_GetRandomLocInRect_Category=TC_NOTHING\n\nOffsetLocation=0,1,location,location,real,real\n_OffsetLocation_Defaults=GetRectCenter,0,0\n_OffsetLocation_Category=TC_NOTHING\n\nPolarProjectionBJ=0,1,location,location,real,real\n_PolarProjectionBJ_Defaults=GetRectCenter,256,0\n_PolarProjectionBJ_Category=TC_NOTHING\n\nCameraSetupGetDestPositionLoc=0,1,location,camerasetup\n_CameraSetupGetDestPositionLoc_Defaults=_\n_CameraSetupGetDestPositionLoc_Category=TC_CAMERA\n\nGetCameraTargetPositionLoc=0,1,location\n_GetCameraTargetPositionLoc_Defaults=\n_GetCameraTargetPositionLoc_Category=TC_CAMERA\n\nGetCameraEyePositionLoc=0,1,location\n_GetCameraEyePositionLoc_Defaults=\n_GetCameraEyePositionLoc_Category=TC_CAMERA\n\nLocation=0,1,location,real,real\n_Location_Defaults=0,0\n_Location_Category=TC_CONVERSION\n\nGetDestructableLoc=0,1,location,destructable\n_GetDestructableLoc_Defaults=GetLastCreatedDestructable\n_GetDestructableLoc_Category=TC_DESTRUCT\n\nGetOrderPointLoc=0,0,location\n_GetOrderPointLoc_Defaults=\n_GetOrderPointLoc_Category=TC_EVENTRESPONSE\n\nGetSpellTargetLoc=1,0,location\n_GetSpellTargetLoc_Defaults=\n_GetSpellTargetLoc_Category=TC_EVENTRESPONSE\n\nGetItemLoc=0,1,location,item\n_GetItemLoc_Defaults=GetLastCreatedItem\n_GetItemLoc_Category=TC_ITEM\n\nWaygateGetDestinationLocBJ=0,0,location,unit\n_WaygateGetDestinationLocBJ_Defaults=_\n_WaygateGetDestinationLocBJ_Category=TC_NEUTRALBUILDING\n\nGetPlayerStartLocationLoc=0,1,location,player\n_GetPlayerStartLocationLoc_Defaults=Player00\n_GetPlayerStartLocationLoc_Category=TC_PLAYER\n\nGetUnitLoc=0,1,location,unit\n_GetUnitLoc_Defaults=GetTriggerUnit\n_GetUnitLoc_Category=TC_UNIT\n\nGetUnitRallyPoint=1,1,location,unit\n_GetUnitRallyPoint_Defaults=GetTriggerUnit\n_GetUnitRallyPoint_Category=TC_UNIT\n\n\n// returns rect\nGetCurrentCameraBoundsMapRectBJ=0,1,rect\n_GetCurrentCameraBoundsMapRectBJ_Defaults=\n_GetCurrentCameraBoundsMapRectBJ_Category=TC_NOTHING\n\nGetCameraBoundsMapRect=0,1,rect\n_GetCameraBoundsMapRect_Defaults=\n_GetCameraBoundsMapRect_Category=TC_NOTHING\n\nGetPlayableMapRect=0,1,rect\n_GetPlayableMapRect_Defaults=\n_GetPlayableMapRect_Category=TC_NOTHING\n\nGetEntireMapRect=0,1,rect\n_GetEntireMapRect_Defaults=\n_GetEntireMapRect_Category=TC_NOTHING\n\nOffsetRectBJ=0,0,rect,rect,real,real\n_OffsetRectBJ_Defaults=_,0,0\n_OffsetRectBJ_Category=TC_NOTHING\n\nRectFromCenterSizeBJ=0,1,rect,location,real,real\n_RectFromCenterSizeBJ_Defaults=GetUnitLoc,_,_\n_RectFromCenterSizeBJ_Category=TC_CONVERSION\n\nRect=0,1,rect,real,real,real,real\n_Rect_Defaults=0,0,0,0\n_Rect_Category=TC_CONVERSION\n\nRectFromLoc=0,1,rect,location,location\n_RectFromLoc_Defaults=Location,Location\n_RectFromLoc_Category=TC_CONVERSION\n\n\n// returns unit\nGetLastCreatedUnit=0,0,unit\n_GetLastCreatedUnit_Defaults=\n_GetLastCreatedUnit_Category=TC_LAST\n\nGetLastRestoredUnitBJ=0,0,unit\n_GetLastRestoredUnitBJ_Defaults=\n_GetLastRestoredUnitBJ_Category=TC_LAST\n\nGetLastReplacedUnitBJ=0,0,unit\n_GetLastReplacedUnitBJ_Defaults=\n_GetLastReplacedUnitBJ_Category=TC_LAST\n\nGetLastHauntedGoldMine=0,0,unit\n_GetLastHauntedGoldMine_Defaults=\n_GetLastHauntedGoldMine_Category=TC_LAST\n\nGetEnumUnit=0,0,unit\n_GetEnumUnit_Defaults=\n_GetEnumUnit_Category=TC_NOTHING\n\nGetFilterUnit=0,0,unit\n_GetFilterUnit_Defaults=\n_GetFilterUnit_Category=TC_NOTHING\n\nGroupPickRandomUnit=0,0,unit,group\n_GroupPickRandomUnit_Defaults=_\n_GroupPickRandomUnit_Category=TC_NOTHING\n\nGetAttackedUnitBJ=0,0,unit\n_GetAttackedUnitBJ_Defaults=\n_GetAttackedUnitBJ_Category=TC_EVENTRESPONSE\n\nGetAttacker=0,0,unit\n_GetAttacker_Defaults=\n_GetAttacker_Category=TC_EVENTRESPONSE\n\nGetBuyingUnit=1,0,unit\n_GetBuyingUnit_Defaults=\n_GetBuyingUnit_Category=TC_EVENTRESPONSE\n\nGetCancelledStructure=0,0,unit\n_GetCancelledStructure_Defaults=\n_GetCancelledStructure_Category=TC_EVENTRESPONSE\n\nGetSpellAbilityUnit=1,0,unit\n_GetSpellAbilityUnit_Defaults=\n_GetSpellAbilityUnit_Category=TC_EVENTRESPONSE\n\nGetConstructingStructure=0,0,unit\n_GetConstructingStructure_Defaults=\n_GetConstructingStructure_Category=TC_EVENTRESPONSE\n\nGetConstructedStructure=0,0,unit\n_GetConstructedStructure_Defaults=\n_GetConstructedStructure_Category=TC_EVENTRESPONSE\n\nGetEventDamageSource=1,0,unit\n_GetEventDamageSource_Defaults=\n_GetEventDamageSource_Category=TC_EVENTRESPONSE\n\nGetDecayingUnit=0,0,unit\n_GetDecayingUnit_Defaults=\n_GetDecayingUnit_Category=TC_EVENTRESPONSE\n\nGetDyingUnit=0,0,unit\n_GetDyingUnit_Defaults=\n_GetDyingUnit_Category=TC_EVENTRESPONSE\n\nGetEnteringUnit=0,0,unit\n_GetEnteringUnit_Defaults=\n_GetEnteringUnit_Category=TC_EVENTRESPONSE\n\nGetManipulatingUnit=0,0,unit\n_GetManipulatingUnit_Defaults=\n_GetManipulatingUnit_Category=TC_EVENTRESPONSE\n\nGetKillingUnitBJ=0,0,unit\n_GetKillingUnitBJ_Defaults=\n_GetKillingUnitBJ_Category=TC_EVENTRESPONSE\n\nGetLearningUnit=0,0,unit\n_GetLearningUnit_Defaults=\n_GetLearningUnit_Category=TC_EVENTRESPONSE\n\nGetLeavingUnit=0,0,unit\n_GetLeavingUnit_Defaults=\n_GetLeavingUnit_Category=TC_EVENTRESPONSE\n\nGetLevelingUnit=0,0,unit\n_GetLevelingUnit_Defaults=\n_GetLevelingUnit_Category=TC_EVENTRESPONSE\n\nGetLoadedUnitBJ=0,0,unit\n_GetLoadedUnitBJ_Defaults=\n_GetLoadedUnitBJ_Category=TC_EVENTRESPONSE\n\nGetOrderedUnit=0,0,unit\n_GetOrderedUnit_Defaults=\n_GetOrderedUnit_Category=TC_EVENTRESPONSE\n\nGetChangingUnit=1,0,unit\n_GetChangingUnit_Defaults=\n_GetChangingUnit_Category=TC_EVENTRESPONSE\n\nGetResearchingUnit=0,0,unit\n_GetResearchingUnit_Defaults=\n_GetResearchingUnit_Category=TC_EVENTRESPONSE\n\nGetRevivableUnit=0,0,unit\n_GetRevivableUnit_Defaults=\n_GetRevivableUnit_Category=TC_EVENTRESPONSE\n\nGetRevivingUnit=0,0,unit\n_GetRevivingUnit_Defaults=\n_GetRevivingUnit_Category=TC_EVENTRESPONSE\n\nGetSellingUnit=1,0,unit\n_GetSellingUnit_Defaults=\n_GetSellingUnit_Category=TC_EVENTRESPONSE\n\nGetSoldUnit=1,0,unit\n_GetSoldUnit_Defaults=\n_GetSoldUnit_Category=TC_EVENTRESPONSE\n\nGetSummonedUnit=0,0,unit\n_GetSummonedUnit_Defaults=\n_GetSummonedUnit_Category=TC_EVENTRESPONSE\n\nGetSummoningUnit=0,0,unit\n_GetSummoningUnit_Defaults=\n_GetSummoningUnit_Category=TC_EVENTRESPONSE\n\nGetOrderTargetUnit=0,0,unit\n_GetOrderTargetUnit_Defaults=\n_GetOrderTargetUnit_Category=TC_EVENTRESPONSE\n\nGetSpellTargetUnit=1,0,unit\n_GetSpellTargetUnit_Defaults=\n_GetSpellTargetUnit_Category=TC_EVENTRESPONSE\n\nGetEventTargetUnit=0,0,unit\n_GetEventTargetUnit_Defaults=\n_GetEventTargetUnit_Category=TC_EVENTRESPONSE\n\nGetTrainedUnit=0,0,unit\n_GetTrainedUnit_Defaults=\n_GetTrainedUnit_Category=TC_EVENTRESPONSE\n\nGetTransportUnitBJ=0,0,unit\n_GetTransportUnitBJ_Defaults=\n_GetTransportUnitBJ_Category=TC_EVENTRESPONSE\n\nGetTriggerUnit=0,0,unit\n_GetTriggerUnit_Defaults=\n_GetTriggerUnit_Category=TC_EVENTRESPONSE\n\nGetUnitRallyUnit=1,0,unit,unit\n_GetUnitRallyUnit_Defaults=GetTriggerUnit\n_GetUnitRallyUnit_Category=TC_UNIT\n\n\n// returns unitcode\nGetUnitTypeId=0,1,unitcode,unit\n_GetUnitTypeId_Defaults=GetTriggerUnit\n_GetUnitTypeId_Category=TC_NOTHING\n\nChooseRandomCreepBJ=0,1,unitcode,integer\n_ChooseRandomCreepBJ_Defaults=1\n_ChooseRandomCreepBJ_Limits=-1,10\n_ChooseRandomCreepBJ_Category=TC_NOTHING\n\nChooseRandomNPBuildingBJ=0,1,unitcode\n_ChooseRandomNPBuildingBJ_Defaults=\n_ChooseRandomNPBuildingBJ_Category=TC_NOTHING\n\nString2UnitIdBJ=0,1,unitcode,string\n_String2UnitIdBJ_Defaults=footman\n_String2UnitIdBJ_Category=TC_CONVERSION\n\nGetTrainedUnitType=0,0,unitcode\n_GetTrainedUnitType_Defaults=\n_GetTrainedUnitType_Category=TC_EVENTRESPONSE\n\n\n// returns ordercode\nString2OrderIdBJ=0,0,ordercode,string\n_String2OrderIdBJ_Defaults=stop\n_String2OrderIdBJ_Category=TC_CONVERSION\n\nUnitId2OrderIdBJ=0,0,ordercode,unitcode\n_UnitId2OrderIdBJ_Defaults=hfoo\n_UnitId2OrderIdBJ_Category=TC_CONVERSION\n\nGetIssuedOrderIdBJ=0,0,ordercode\n_GetIssuedOrderIdBJ_Defaults=\n_GetIssuedOrderIdBJ_Category=TC_EVENTRESPONSE\n\nGetUnitCurrentOrder=1,0,ordercode,unit\n_GetUnitCurrentOrder_Defaults=GetTriggerUnit\n_GetUnitCurrentOrder_Category=TC_UNIT\n\n\n// returns destructable\nGetLastCreatedDestructable=0,0,destructable\n_GetLastCreatedDestructable_Defaults=\n_GetLastCreatedDestructable_Category=TC_LAST\n\nRandomDestructableInRectSimpleBJ=0,0,destructable,rect\n_RandomDestructableInRectSimpleBJ_Defaults=_\n_RandomDestructableInRectSimpleBJ_Category=TC_NOTHING\n\nRandomDestructableInRectBJ=0,0,destructable,rect,boolexpr\n_RandomDestructableInRectBJ_Defaults=_,_\n_RandomDestructableInRectBJ_Category=TC_NOTHING\n\nGetEnumDestructable=0,0,destructable\n_GetEnumDestructable_Defaults=\n_GetEnumDestructable_Category=TC_NOTHING\n\nGetFilterDestructable=0,0,destructable\n_GetFilterDestructable_Defaults=\n_GetFilterDestructable_Category=TC_NOTHING\n\nGetDyingDestructable=0,0,destructable\n_GetDyingDestructable_Defaults=\n_GetDyingDestructable_Category=TC_EVENTRESPONSE\n\nGetOrderTargetDestructable=0,0,destructable\n_GetOrderTargetDestructable_Defaults=\n_GetOrderTargetDestructable_Category=TC_EVENTRESPONSE\n\nGetSpellTargetDestructable=1,0,destructable\n_GetSpellTargetDestructable_Defaults=\n_GetSpellTargetDestructable_Category=TC_EVENTRESPONSE\n\nGetUnitRallyDestructable=1,0,destructable,unit\n_GetUnitRallyDestructable_Defaults=GetTriggerUnit\n_GetUnitRallyDestructable_Category=TC_UNIT\n\n\n// returns destructablecode\nGetDestructableTypeId=0,1,destructablecode,destructable\n_GetDestructableTypeId_Defaults=GetLastCreatedDestructable\n_GetDestructableTypeId_Category=TC_NOTHING\n\n\n// returns item\nGetLastCreatedItem=0,0,item\n_GetLastCreatedItem_Defaults=\n_GetLastCreatedItem_Category=TC_LAST\n\nGetLastRemovedItem=0,0,item\n_GetLastRemovedItem_Defaults=\n_GetLastRemovedItem_Category=TC_LAST\n\nRandomItemInRectSimpleBJ=1,0,item,rect\n_RandomItemInRectSimpleBJ_Defaults=_\n_RandomItemInRectSimpleBJ_Category=TC_NOTHING\n\nRandomItemInRectBJ=1,0,item,rect,boolexpr\n_RandomItemInRectBJ_Defaults=_,_\n_RandomItemInRectBJ_Category=TC_NOTHING\n\nGetEnumItem=1,0,item\n_GetEnumItem_Defaults=\n_GetEnumItem_Category=TC_NOTHING\n\nGetFilterItem=1,0,item\n_GetFilterItem_Defaults=\n_GetFilterItem_Category=TC_NOTHING\n\nUnitItemInSlotBJ=0,0,item,unit,integer\n_UnitItemInSlotBJ_Defaults=_,1\n_UnitItemInSlotBJ_Limits=_,_,1,6\n_UnitItemInSlotBJ_Category=TC_NOTHING\n\nGetItemOfTypeFromUnitBJ=0,0,item,unit,itemcode\n_GetItemOfTypeFromUnitBJ_Defaults=_,texp\n_GetItemOfTypeFromUnitBJ_Category=TC_NOTHING\n\nGetManipulatedItem=0,0,item\n_GetManipulatedItem_Defaults=\n_GetManipulatedItem_Category=TC_EVENTRESPONSE\n\nGetSoldItem=1,0,item\n_GetSoldItem_Defaults=\n_GetSoldItem_Category=TC_EVENTRESPONSE\n\nGetOrderTargetItem=0,0,item\n_GetOrderTargetItem_Defaults=\n_GetOrderTargetItem_Category=TC_EVENTRESPONSE\n\nGetSpellTargetItem=1,0,item\n_GetSpellTargetItem_Defaults=\n_GetSpellTargetItem_Category=TC_EVENTRESPONSE\n\n\n// returns itemtype\nGetItemType=1,1,itemtype,item\n_GetItemType_Defaults=GetLastCreatedItem\n_GetItemType_Category=TC_NOTHING\n\n\n// returns itemcode\nGetItemTypeId=0,1,itemcode,item\n_GetItemTypeId_Defaults=GetLastCreatedItem\n_GetItemTypeId_Category=TC_NOTHING\n\nChooseRandomItemBJ=0,1,itemcode,integer\n_ChooseRandomItemBJ_Defaults=1\n_ChooseRandomItemBJ_Limits=-1,10\n_ChooseRandomItemBJ_Category=TC_NOTHING\n\nChooseRandomItemExBJ=1,1,itemcode,integer,itemtype\n_ChooseRandomItemExBJ_Defaults=1,ItemTypeAny\n_ChooseRandomItemExBJ_Limits=-1,8,_,_\n_ChooseRandomItemExBJ_Category=TC_NOTHING\n\n\n// returns techcode\nGetResearched=0,1,techcode\n_GetResearched_Defaults=\n_GetResearched_Category=TC_EVENTRESPONSE\n\n\n// returns abilcode\nGetSpellAbilityId=1,0,abilcode\n_GetSpellAbilityId_Defaults=\n_GetSpellAbilityId_Category=TC_EVENTRESPONSE\n\n\n// returns heroskillcode\nGetLearnedSkillBJ=0,0,heroskillcode\n_GetLearnedSkillBJ_Defaults=\n_GetLearnedSkillBJ_Category=TC_EVENTRESPONSE\n\n\n// returns player\nGetEnumPlayer=0,0,player\n_GetEnumPlayer_Defaults=\n_GetEnumPlayer_Category=TC_NOTHING\n\nGetFilterPlayer=0,0,player\n_GetFilterPlayer_Defaults=\n_GetFilterPlayer_Category=TC_NOTHING\n\nGetOwningPlayer=0,1,player,unit\n_GetOwningPlayer_Defaults=GetTriggerUnit\n_GetOwningPlayer_Category=TC_NOTHING\n\nGetItemPlayer=0,1,player,item\n_GetItemPlayer_Defaults=GetLastCreatedItem\n_GetItemPlayer_Category=TC_NOTHING\n\nForcePickRandomPlayer=0,0,player,force\n_ForcePickRandomPlayer_Defaults=_\n_ForcePickRandomPlayer_Category=TC_NOTHING\n\nConvertedPlayer=0,1,player,integer\n_ConvertedPlayer_Defaults=1\n_ConvertedPlayer_Limits=1,28\n_ConvertedPlayer_Category=TC_CONVERSION\n\nGetChangingUnitPrevOwner=1,0,player\n_GetChangingUnitPrevOwner_Defaults=\n_GetChangingUnitPrevOwner_Category=TC_EVENTRESPONSE\n\nGetTriggerPlayer=0,0,player\n_GetTriggerPlayer_Defaults=\n_GetTriggerPlayer_Category=TC_EVENTRESPONSE\n\nLeaderboardGetIndexedPlayerBJ=1,0,player,integer,leaderboard\n_LeaderboardGetIndexedPlayerBJ_Defaults=1,GetLastCreatedLeaderboard\n_LeaderboardGetIndexedPlayerBJ_Limits=1,28\n_LeaderboardGetIndexedPlayerBJ_Category=TC_LEADERBOARD\n\n\n// returns group\nGetLastCreatedGroup=0,0,group\n_GetLastCreatedGroup_Defaults=\n_GetLastCreatedGroup_Category=TC_LAST\n\nGetRandomSubGroup=1,0,group,integer,group\n_GetRandomSubGroup_Defaults=4,GetUnitsInRectAll\n_GetRandomSubGroup_Category=TC_NOTHING\n\nGetUnitsInRectAll=0,0,group,rect\n_GetUnitsInRectAll_Defaults=GetPlayableMapRect\n_GetUnitsInRectAll_Category=TC_NOTHING\n\nGetUnitsInRectOfPlayer=0,0,group,rect,player\n_GetUnitsInRectOfPlayer_Defaults=GetPlayableMapRect,Player00\n_GetUnitsInRectOfPlayer_Category=TC_NOTHING\n\nGetUnitsInRectMatching=0,0,group,rect,boolexpr\n_GetUnitsInRectMatching_Defaults=GetPlayableMapRect,_\n_GetUnitsInRectMatching_Category=TC_NOTHING\n\nGetUnitsInRangeOfLocAll=0,0,group,real,location\n_GetUnitsInRangeOfLocAll_Defaults=512,GetRectCenter\n_GetUnitsInRangeOfLocAll_Limits=0,_,_,_\n_GetUnitsInRangeOfLocAll_Category=TC_NOTHING\n\nGetUnitsInRangeOfLocMatching=0,0,group,real,location,boolexpr\n_GetUnitsInRangeOfLocMatching_Defaults=512,GetRectCenter,_\n_GetUnitsInRangeOfLocMatching_Limits=0,_,_,_,_,_\n_GetUnitsInRangeOfLocMatching_Category=TC_NOTHING\n\nGetUnitsOfPlayerAll=0,0,group,player\n_GetUnitsOfPlayerAll_Defaults=Player00\n_GetUnitsOfPlayerAll_Category=TC_NOTHING\n\nGetUnitsOfPlayerAndTypeId=0,0,group,player,unitcode\n_GetUnitsOfPlayerAndTypeId_Defaults=Player00,hfoo\n_GetUnitsOfPlayerAndTypeId_Category=TC_NOTHING\n\nGetUnitsOfPlayerMatching=0,0,group,player,boolexpr\n_GetUnitsOfPlayerMatching_Defaults=Player00,_\n_GetUnitsOfPlayerMatching_Category=TC_NOTHING\n\nGetUnitsOfTypeIdAll=0,0,group,unitcode\n_GetUnitsOfTypeIdAll_Defaults=hfoo\n_GetUnitsOfTypeIdAll_Category=TC_NOTHING\n\nGetUnitsSelectedAll=0,0,group,player\n_GetUnitsSelectedAll_Defaults=Player00\n_GetUnitsSelectedAll_Category=TC_NOTHING\n\n\n// returns force\nGetPlayersAll=0,0,force\n_GetPlayersAll_Defaults=\n_GetPlayersAll_Category=TC_NOTHING\n\nGetPlayersByMapControl=0,0,force,mapcontrol\n_GetPlayersByMapControl_Defaults=MapControlComputer\n_GetPlayersByMapControl_Category=TC_NOTHING\n\nGetPlayersMatching=0,0,force,boolexpr\n_GetPlayersMatching_Defaults=_\n_GetPlayersMatching_Category=TC_NOTHING\n\nGetPlayersAllies=0,0,force,player\n_GetPlayersAllies_Defaults=Player00\n_GetPlayersAllies_Category=TC_NOTHING\n\nGetPlayersEnemies=0,0,force,player\n_GetPlayersEnemies_Defaults=Player00\n_GetPlayersEnemies_Category=TC_NOTHING\n\nGetForceOfPlayer=0,0,force,player\n_GetForceOfPlayer_Defaults=Player00\n_GetForceOfPlayer_Category=TC_NOTHING\n\n\n// returns race\nGetPlayerRace=0,1,race,player\n_GetPlayerRace_Defaults=Player00\n_GetPlayerRace_Category=TC_NOTHING\n\nGetUnitRace=0,1,race,unit\n_GetUnitRace_Defaults=GetTriggerUnit\n_GetUnitRace_Category=TC_NOTHING\n\n\n// returns camerasetup\nGetCurrentCameraSetup=0,0,camerasetup\n_GetCurrentCameraSetup_Defaults=\n_GetCurrentCameraSetup_Category=TC_NOTHING\n\n\n// returns fogmodifier\nGetLastCreatedFogModifier=0,0,fogmodifier\n_GetLastCreatedFogModifier_Defaults=\n_GetLastCreatedFogModifier_Category=TC_LAST\n\n\n// returns trigger\nGetTriggeringTrigger=0,0,trigger\n_GetTriggeringTrigger_Defaults=\n_GetTriggeringTrigger_Category=TC_NOTHING\n\n\n// returns gamedifficulty\nGetGameDifficulty=0,1,gamedifficulty\n_GetGameDifficulty_Defaults=\n_GetGameDifficulty_Category=TC_NOTHING\n\n\n// returns aidifficulty\nGetAIDifficulty=1,1,aidifficulty,player\n_GetAIDifficulty_Defaults=Player00\n_GetAIDifficulty_Category=TC_NOTHING\n\n\n// returns gamespeed\nGetGameSpeed=0,1,gamespeed\n_GetGameSpeed_Defaults=\n_GetGameSpeed_Category=TC_NOTHING\n\n\n// returns mapcontrol\nGetPlayerController=0,1,mapcontrol,player\n_GetPlayerController_Defaults=Player00\n_GetPlayerController_Category=TC_NOTHING\n\n\n// returns playercolor\nGetPlayerColor=0,1,playercolor,player\n_GetPlayerColor_Defaults=Player00\n_GetPlayerColor_Category=TC_NOTHING\n\n\n// returns playerslotstate\nGetPlayerSlotState=0,1,playerslotstate,player\n_GetPlayerSlotState_Defaults=Player00\n_GetPlayerSlotState_Category=TC_NOTHING\n\n\n// returns effect\nGetLastCreatedEffectBJ=0,0,effect\n_GetLastCreatedEffectBJ_Defaults=\n_GetLastCreatedEffectBJ_Category=TC_LAST\n\n\n// returns lightning\nGetLastCreatedLightningBJ=1,0,lightning\n_GetLastCreatedLightningBJ_Defaults=\n_GetLastCreatedLightningBJ_Category=TC_LAST\n\n\n// returns image\nGetLastCreatedImage=1,0,image\n_GetLastCreatedImage_Defaults=\n_GetLastCreatedImage_Category=TC_LAST\n\n\n// returns ubersplat\nGetLastCreatedUbersplat=1,0,ubersplat\n_GetLastCreatedUbersplat_Defaults=\n_GetLastCreatedUbersplat_Category=TC_LAST\n\n\n// returns weathereffect\nGetLastCreatedWeatherEffect=0,0,weathereffect\n_GetLastCreatedWeatherEffect_Defaults=\n_GetLastCreatedWeatherEffect_Category=TC_LAST\n\n\n// returns terraindeformation\nGetLastCreatedTerrainDeformation=1,0,terraindeformation\n_GetLastCreatedTerrainDeformation_Defaults=\n_GetLastCreatedTerrainDeformation_Category=TC_LAST\n\n\n// returns terraintype\nGetTerrainTypeBJ=1,1,terraintype,location\n_GetTerrainTypeBJ_Defaults=GetRectCenter\n_GetTerrainTypeBJ_Category=TC_ENVIRONMENT\n\n\n// returns sound\nGetLastPlayedSound=0,0,sound\n_GetLastPlayedSound_Defaults=\n_GetLastPlayedSound_Category=TC_LAST\n\n\n// returns musicfile\nGetLastPlayedMusic=0,0,musicfile\n_GetLastPlayedMusic_Defaults=\n_GetLastPlayedMusic_Category=TC_LAST\n\n\n// returns quest\nGetLastCreatedQuestBJ=0,0,quest\n_GetLastCreatedQuestBJ_Defaults=\n_GetLastCreatedQuestBJ_Category=TC_LAST\n\n\n// returns questitem\nGetLastCreatedQuestItemBJ=0,0,questitem\n_GetLastCreatedQuestItemBJ_Defaults=\n_GetLastCreatedQuestItemBJ_Category=TC_LAST\n\n\n// returns defeatcondition\nGetLastCreatedDefeatConditionBJ=0,0,defeatcondition\n_GetLastCreatedDefeatConditionBJ_Defaults=\n_GetLastCreatedDefeatConditionBJ_Category=TC_LAST\n\n\n// returns dialog\nGetClickedDialogBJ=0,0,dialog\n_GetClickedDialogBJ_Defaults=\n_GetClickedDialogBJ_Category=TC_EVENTRESPONSE\n\n\n// returns button\nGetLastCreatedButtonBJ=0,0,button\n_GetLastCreatedButtonBJ_Defaults=\n_GetLastCreatedButtonBJ_Category=TC_LAST\n\nGetClickedButtonBJ=0,0,button\n_GetClickedButtonBJ_Defaults=\n_GetClickedButtonBJ_Category=TC_EVENTRESPONSE\n\n\n// returns leaderboard\nGetLastCreatedLeaderboard=0,0,leaderboard\n_GetLastCreatedLeaderboard_Defaults=\n_GetLastCreatedLeaderboard_Category=TC_LAST\n\nPlayerGetLeaderboardBJ=0,0,leaderboard,player\n_PlayerGetLeaderboardBJ_Defaults=Player00\n_PlayerGetLeaderboardBJ_Category=TC_NOTHING\n\n\n// returns multiboard\nGetLastCreatedMultiboard=1,0,multiboard\n_GetLastCreatedMultiboard_Defaults=\n_GetLastCreatedMultiboard_Category=TC_LAST\n\n\n// returns timer\nGetLastCreatedTimerBJ=0,0,timer\n_GetLastCreatedTimerBJ_Defaults=\n_GetLastCreatedTimerBJ_Category=TC_LAST\n\nGetExpiredTimer=0,0,timer\n_GetExpiredTimer_Defaults=\n_GetExpiredTimer_Category=TC_EVENTRESPONSE\n\n\n// returns timerdialog\nGetLastCreatedTimerDialogBJ=0,0,timerdialog\n_GetLastCreatedTimerDialogBJ_Defaults=\n_GetLastCreatedTimerDialogBJ_Category=TC_LAST\n\n\n// returns gamecache\nGetLastCreatedGameCacheBJ=0,0,gamecache\n_GetLastCreatedGameCacheBJ_Defaults=\n_GetLastCreatedGameCacheBJ_Category=TC_LAST\n\n// returns hashtable\nGetLastCreatedHashtableBJ=0,0,hashtable\n_GetLastCreatedHashtableBJ_Defaults=\n_GetLastCreatedHashtableBJ_Category=TC_LAST\n\n\n// returns texttag\nGetLastCreatedTextTag=1,0,texttag\n_GetLastCreatedTextTag_Defaults=\n_GetLastCreatedTextTag_Category=TC_LAST\n\n\n\n//***************************************************************************\n[DefaultTriggerCategories]\n// Defines categories to be automatically added to new maps\nNumCategories=1\n\nCategory01=WESTRING_INITIALIZATION\n\n\n\n//***************************************************************************\n[DefaultTriggers]\n// Defines triggers to be automatically added to new maps\nNumTriggers=1\n\n// Melee Initialization\nTrigger01Name=WESTRING_MELEEINITIALIZATION\nTrigger01Comment=WESTRING_MELEEINITIALIZATION_COMMENT\nTrigger01Category=1\nTrigger01Events=1\nTrigger01Event01=MapInitializationEvent\nTrigger01Conditions=0\nTrigger01Actions=8\nTrigger01Action01=MeleeStartingVisibility\nTrigger01Action02=MeleeStartingHeroLimit\nTrigger01Action03=MeleeGrantHeroItems\nTrigger01Action04=MeleeStartingResources\nTrigger01Action05=MeleeClearExcessUnits\nTrigger01Action06=MeleeStartingUnits\nTrigger01Action07=MeleeStartingAI\nTrigger01Action08=MeleeInitVictoryDefeat\n"
  },
  {
    "path": "clients/weu/TriggerDataWEU.txt",
    "content": "[TriggerCategories]\nTC_ARITHMETIC=WESTRING_TRIGCAT_ARITHMETIC,ReplaceableTextures\\WorldEditUI\\Actions-AI,1\nTC_NOTHING=WESTRING_TRIGCAT_NOTHING,ReplaceableTextures\\WorldEditUI\\Actions-Nothing,1\nTC_COMMENT=WESTRING_TRIGCAT_COMMENT,ReplaceableTextures\\WorldEditUI\\Actions-Comment,1\nTC_CUSTOM=WESTRING_TRIGCAT_CUSTOM,ReplaceableTextures\\WorldEditUI\\Actions-Nothing,1\nTC_CONDITION=WESTRING_TRIGCAT_CONDITION,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_WAIT=WESTRING_TRIGCAT_WAIT,ReplaceableTextures\\WorldEditUI\\Actions-Wait,1\nTC_SETVARIABLE=WESTRING_TRIGCAT_SETVARIABLE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables,1\nTC_SKIPACTIONS=WESTRING_TRIGCAT_SKIPACTIONS,ReplaceableTextures\\WorldEditUI\\Actions-Nothing,1\nTC_LOGIC=WESTRING_TRIGCAT_LOGIC,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_FORLOOP=WESTRING_TRIGCAT_FORLOOP,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_LAST=WESTRING_TRIGCAT_LAST,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables,1\nTC_AI=WESTRING_TRIGCAT_AI,ReplaceableTextures\\WorldEditUI\\Actions-AI\nTC_ANIMATION=WESTRING_TRIGCAT_ANIMATION,ReplaceableTextures\\WorldEditUI\\Actions-Animation\nTC_CAMERA=WESTRING_TRIGCAT_CAMERA,ReplaceableTextures\\WorldEditUI\\Actions-Camera\nTC_CINEMATIC=WESTRING_TRIGCAT_CINEMATIC,ReplaceableTextures\\WorldEditUI\\Actions-Camera\nTC_CONVERSION=WESTRING_TRIGCAT_CONVERSION,ReplaceableTextures\\WorldEditUI\\Actions-AI\nTC_TIMER=WESTRING_TRIGCAT_TIMER,ReplaceableTextures\\WorldEditUI\\Events-Time\nTC_DESTRUCT=WESTRING_TRIGCAT_DESTRUCT,ReplaceableTextures\\WorldEditUI\\Actions-Destructibles\nTC_DIALOG=WESTRING_TRIGCAT_DIALOG,ReplaceableTextures\\WorldEditUI\\Actions-Dialog\nTC_ENVIRONMENT=WESTRING_TRIGCAT_ENVIRONMENT,ReplaceableTextures\\WorldEditUI\\Actions-Environment\nTC_EVENTRESPONSE=WESTRING_TRIGCAT_EVENTRESPONSE,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_TEXTTAG=WESTRING_TRIGCAT_TEXTTAG,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_GAME=WESTRING_TRIGCAT_GAME,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_GAMECACHE=WESTRING_TRIGCAT_GAMECACHE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables\nTC_HERO=WESTRING_TRIGCAT_HERO,ReplaceableTextures\\WorldEditUI\\Actions-Hero\nTC_IMAGE=WESTRING_TRIGCAT_IMAGE,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_ITEM=WESTRING_TRIGCAT_ITEM,ReplaceableTextures\\WorldEditUI\\Actions-Item\nTC_LEADERBOARD=WESTRING_TRIGCAT_LEADERBOARD,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_LOCATION=WESTRING_TRIGCAT_LOCATION,ReplaceableTextures\\WorldEditUI\\Actions-Region\nTC_LIGHTNING=WESTRING_TRIGCAT_LIGHTNING,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_MATH=WESTRING_TRIGCAT_MATH,ReplaceableTextures\\WorldEditUI\\Actions-Logical\nTC_MELEE=WESTRING_TRIGCAT_MELEE,ReplaceableTextures\\WorldEditUI\\Actions-Melee\nTC_MULTIBOARD=WESTRING_TRIGCAT_MULTIBOARD,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_NEUTRALBUILDING=WESTRING_TRIGCAT_NEUTRALBUILDING,ReplaceableTextures\\WorldEditUI\\Actions-Goldmine\nTC_PLAYER=WESTRING_TRIGCAT_PLAYER,ReplaceableTextures\\WorldEditUI\\Actions-Player\nTC_PLAYERGROUP=WESTRING_TRIGCAT_PLAYERGROUP,ReplaceableTextures\\WorldEditUI\\Actions-PlayerGroup\nTC_QUEST=WESTRING_TRIGCAT_QUEST,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_REGION=WESTRING_TRIGCAT_REGION,ReplaceableTextures\\WorldEditUI\\Actions-Region\nTC_RECTANGLE=WESTRING_TRIGCAT_RECTANGLE,ReplaceableTextures\\WorldEditUI\\Actions-Regions\nTC_UNITSEL=WESTRING_TRIGCAT_UNITSEL,ReplaceableTextures\\WorldEditUI\\Actions-UnitSelection\nTC_SOUND=WESTRING_TRIGCAT_SOUND,ReplaceableTextures\\WorldEditUI\\Actions-Sound\nTC_SPECIALEFFECT=WESTRING_TRIGCAT_SPECIALEFFECT,ReplaceableTextures\\WorldEditUI\\Actions-Animation\nTC_TIME=WESTRING_TRIGCAT_TIME,ReplaceableTextures\\WorldEditUI\\Events-Time\nTC_TRIGGER=WESTRING_TRIGCAT_TRIGGER,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_UBERSPLAT=WESTRING_TRIGCAT_UBERSPLAT,ReplaceableTextures\\WorldEditUI\\Actions-Nothing\nTC_TRACKABLE=WESTRING_TRIGCAT_TRACKABLE,ReplaceableTextures\\WorldEditUI\\Actions-Trackable\nTC_UNIT=WESTRING_TRIGCAT_UNIT,ReplaceableTextures\\WorldEditUI\\Actions-Unit\nTC_UNITGROUP=WESTRING_TRIGCAT_UNITGROUP,ReplaceableTextures\\WorldEditUI\\Actions-UnitGroup\nTC_VISIBILITY=WESTRING_TRIGCAT_VISIBILITY,ReplaceableTextures\\WorldEditUI\\Actions-Visibility\nTC_COMPATIBILITY=WESTRING_TRIGCAT_COMPATIBILITY,ReplaceableTextures\\WorldEditUI\\Actions-Compatibility\nTC_RETURNSUCCESS=WESTRING_TRIGCAT_RETURNSUCCESS,ReplaceableTextures\\WorldEditUI\\Actions-Success\nTC_AI_TOWN=WESTRING_TRIGCAT_AI_TOWN,none\nTC_AI_HERO=WESTRING_TRIGCAT_AI_HERO,none\nTC_AI_RESOURCES=WESTRING_TRIGCAT_AI_RESOURCES,none\nTC_AI_MISC=WESTRING_TRIGCAT_AI_MISC,none\nTC_AI_UNIT=WESTRING_TRIGCAT_AI_UNIT,none\nTC_AI_UPGRADE=WESTRING_TRIGCAT_AI_UPGRADE,none\nTC_AI_COMMAND=WESTRING_TRIGCAT_AI_COMMAND,none\n[TriggerTypes]\nabilcode=0,1,1,WESTRING_TRIGTYPE_abilcode,integer\nattacktype=0,1,1,WESTRING_TRIGTYPE_attacktype\nboolean=0,1,1,WESTRING_TRIGTYPE_boolean\nbuffcode=1,1,1,WESTRING_TRIGTYPE_buffcode,integer\ncamerasetup=0,1,0,WESTRING_TRIGTYPE_camerasetup\nweapontype=0,1,1,WESTRING_TRIGTYPE_weapontype\ndamagetype=0,1,1,WESTRING_TRIGTYPE_damagetype\ndestructable=0,1,1,WESTRING_TRIGTYPE_destructable\ndestructablecode=0,1,1,WESTRING_TRIGTYPE_destructablecode,integer\ndefeatcondition=0,1,0,WESTRING_TRIGTYPE_defeatcondition\ndialog=0,1,0,WESTRING_TRIGTYPE_dialog\nbutton=0,1,0,WESTRING_TRIGTYPE_button\neffecttype=0,1,1,WESTRING_TRIGTYPE_effecttype\ntexttag=1,1,0,WESTRING_TRIGTYPE_texttag\ngamecache=0,1,0,WESTRING_TRIGTYPE_gamecache\ngamespeed=0,1,1,WESTRING_TRIGTYPE_gamespeed\nimage=1,1,1,WESTRING_TRIGTYPE_image\nimagetype=0,1,1,WESTRING_TRIGTYPE_imagetype,integer\ninteger=0,1,1,WESTRING_TRIGTYPE_integer\nitem=0,1,1,WESTRING_TRIGTYPE_item\nitemtype=1,1,1,WESTRING_TRIGTYPE_itemtype\nitemcode=0,1,1,WESTRING_TRIGTYPE_itemcode,integer\nleaderboard=0,1,0,WESTRING_TRIGTYPE_leaderboard\nlightning=1,1,1,WESTRING_TRIGTYPE_lightning\nlightningtype=0,1,1,WESTRING_TRIGTYPE_lightningtype,string\nmultiboard=1,1,0,WESTRING_TRIGTYPE_multiboard\nmultiboarditem=1,1,1,WESTRING_TRIGTYPE_multiboarditem\nordercode=0,1,1,WESTRING_TRIGTYPE_ordercode,integer\nplayer=0,1,1,WESTRING_TRIGTYPE_player\nplayercolor=0,1,1,WESTRING_TRIGTYPE_playercolor\nforce=0,1,0,WESTRING_TRIGTYPE_force\nlocation=0,1,1,WESTRING_TRIGTYPE_location\npathingtype=0,1,1,WESTRING_TRIGTYPE_pathingtype\nquest=0,1,0,WESTRING_TRIGTYPE_quest\nquestitem=0,1,0,WESTRING_TRIGTYPE_questitem\nrace=0,1,1,WESTRING_TRIGTYPE_race\nreal=0,1,1,WESTRING_TRIGTYPE_real\nrect=0,1,1,WESTRING_TRIGTYPE_rect\nregion=1,1,1,WESTRING_TRIGTYPE_rectanglereg\nsound=0,1,0,WESTRING_TRIGTYPE_sound\nsoundtype=0,1,1,WESTRING_TRIGTYPE_soundtype\neffect=0,1,0,WESTRING_TRIGTYPE_effect\nstring=0,1,1,WESTRING_TRIGTYPE_string\ntechcode=0,1,1,WESTRING_TRIGTYPE_techcode,integer\nterraindeformation=1,1,0,WESTRING_TRIGTYPE_terraindeformation\nterrainshape=0,1,1,WESTRING_TRIGTYPE_terrainshape,integer\nterraintype=0,1,1,WESTRING_TRIGTYPE_terraintype,integer\ntimer=0,1,0,WESTRING_TRIGTYPE_timer\ntimerdialog=0,1,0,WESTRING_TRIGTYPE_timerdialog\ntrackable=0,1,0,WESTRING_TRIGTYPE_trackable\ntrigger=0,1,1,WESTRING_TRIGTYPE_trigger\nunit=0,1,1,WESTRING_TRIGTYPE_unit\ngroup=0,1,0,WESTRING_TRIGTYPE_group\nunitcode=0,1,1,WESTRING_TRIGTYPE_unitcode,integer\nfogmodifier=0,1,0,WESTRING_TRIGTYPE_fogmodifier\nweathereffect=0,1,0,WESTRING_TRIGTYPE_weathereffect\ncode=0,0,0,WESTRING_TRIGTYPE_code\nevent=0,1,0,WESTRING_TRIGTYPE_event\ntriggercondition=0,1,0,WESTRING_TRIGTYPE_triggercondition\ntriggeraction=0,1,0,WESTRING_TRIGTYPE_triggeraction\nubersplat=1,1,1,WESTRING_TRIGTYPE_ubersplat\nubersplattype=0,1,1,WESTRING_TRIGTYPE_ubersplattype,string\nboolexpr=0,1,1,WESTRING_TRIGTYPE_boolexpr\neventid=0,1,1,WESTRING_TRIGTYPE_eventid\ngamestate=0,0,0,WESTRING_TRIGTYPE_gamestate\nigamestate=0,0,0,WESTRING_TRIGTYPE_igamestate\nunittype=0,0,0,WESTRING_TRIGTYPE_unittype\nalliancetype=0,0,0,WESTRING_TRIGTYPE_alliancetype\nplayerstate=0,0,0,WESTRING_TRIGTYPE_playerstate\nplayerscore=1,0,0,WESTRING_TRIGTYPE_playerscore\nplayergameresult=0,0,0,WESTRING_TRIGTYPE_playergameresult\nunitstate=0,0,0,WESTRING_TRIGTYPE_unitstate\nplayerunitevent=0,0,0,WESTRING_TRIGTYPE_playerunitevent\nunitevent=0,0,0,WESTRING_TRIGTYPE_unitevent\nlimitop=0,0,0,WESTRING_TRIGTYPE_limitop\ngamedifficulty=0,0,1,WESTRING_TRIGTYPE_gamedifficulty\ngameevent=1,0,0,WESTRING_TRIGTYPE_gameevent\naidifficulty=0,0,1,WESTRING_TRIGTYPE_aidifficulty\nmapdensity=0,0,1,WESTRING_TRIGTYPE_mapdensity\nmapcontrol=0,0,1,WESTRING_TRIGTYPE_mapcontrol\nmapflag=0,0,0,WESTRING_TRIGTYPE_mapflag\nplayerslotstate=0,0,1,WESTRING_TRIGTYPE_playerslotstate\ncamerafield=0,0,0,WESTRING_TRIGTYPE_camerafield\nraritycontrol=0,0,0,WESTRING_TRIGTYPE_raritycontrol\nblendmode=0,0,0,WESTRING_TRIGTYPE_blendmode\nfogstate=0,0,0,WESTRING_TRIGTYPE_fogstate\nvolumegroup=0,0,0,WESTRING_TRIGTYPE_volumegroup\nkeyeventtype=1,0,0,WESTRING_TRIGTYPE_keyeventtype,integer\nkeyeventkey=1,0,0,WESTRING_TRIGTYPE_keyeventkey,integer\ncolorchangeoption=0,0,0,WESTRING_TRIGTYPE_colorchangeoption,boolean\nplayerchangecoloroption=0,0,0,WESTRING_TRIGTYPE_playerchangecoloroption,boolean\nchatmatchtype=0,0,0,WESTRING_TRIGTYPE_chatmatchtype,boolean\nunitfacingbone=0,0,0,WESTRING_TRIGTYPE_unitfacingbone,string\nincludeoption=0,0,0,WESTRING_TRIGTYPE_inclusionoption,boolean\ncameraapplyoption=0,0,0,WESTRING_TRIGTYPE_cameraapplyoption,boolean\ncameraorientationoption=0,0,0,WESTRING_TRIGTYPE_cameraorientationoption,boolean\ninvulnerableoption=0,0,0,WESTRING_TRIGTYPE_invulnerableoption,boolean\navailabilityoption=0,0,0,WESTRING_TRIGTYPE_availabilityoption,boolean\nshowhideoption=0,0,0,WESTRING_TRIGTYPE_showhideoption,boolean\nminimizeoption=1,0,0,WESTRING_TRIGTYPE_minimizeoption,boolean\nskymodelstring=0,0,0,WESTRING_TRIGTYPE_skymodelstring,string,Model\ncinefiltertexture=0,0,0,WESTRING_TRIGTYPE_cinefiltertexture,string,Image\nplayerresource=1,0,0,WESTRING_TRIGTYPE_playerresource,playerstate\npathingoption=0,0,0,WESTRING_TRIGTYPE_pathingoption,boolean\npawnableoption=1,0,0,WESTRING_TRIGTYPE_pawnableoption,boolean\ndropnodropoption=0,0,0,WESTRING_TRIGTYPE_dropnodropoption,boolean\ndroppableoption=0,0,0,WESTRING_TRIGTYPE_droppableoption,boolean\nbeforeafteroption=0,0,0,WESTRING_TRIGTYPE_beforeafteroption,boolean\nonoffoption=0,0,0,WESTRING_TRIGTYPE_onoffoption,boolean\nenabledisableoption=0,0,0,WESTRING_TRIGTYPE_enabledisableoption,boolean\nenableddisabledoption=0,0,0,WESTRING_TRIGTYPE_enableddisabledoption,boolean\nrescuableoption=0,0,0,WESTRING_TRIGTYPE_rescuableoption,boolean\nallowdontoption=0,0,0,WESTRING_TRIGTYPE_allowdontoption,boolean\nfadedontoption=0,0,0,WESTRING_TRIGTYPE_fadedontoption,boolean\nunitorderutarg=0,0,0,WESTRING_TRIGTYPE_unitorderutarg,string\nunitorderptarg=0,0,0,WESTRING_TRIGTYPE_unitorderptarg,string\nunitorderdtarg=0,0,0,WESTRING_TRIGTYPE_unitorderdtarg,string\nunitordernotarg=0,0,0,WESTRING_TRIGTYPE_unitordernotarg,string\nheroskillcode=0,1,1,WESTRING_TRIGTYPE_heroskillcode,integer\nweathereffectcode=0,0,0,WESTRING_TRIGTYPE_weathereffectcode,integer\nalliancesetting=0,0,0,WESTRING_TRIGTYPE_alliancesetting,integer\naddsettooption=0,0,0,WESTRING_TRIGTYPE_addsettooption,integer\nmodifymethod=1,0,0,WESTRING_TRIGTYPE_modifymethod,integer\nwaitdontoption=0,0,0,WESTRING_TRIGTYPE_waitdontoption,boolean\ncratertype=1,0,0,WESTRING_TRIGTYPE_cratertype,boolean\nrippletype=1,0,0,WESTRING_TRIGTYPE_rippletype,boolean\ncreateremoveoption=0,0,0,WESTRING_TRIGTYPE_createremoveoption,boolean\naddremoveoption=0,0,0,WESTRING_TRIGTYPE_addremoveoption,boolean\nquesttypeoption=0,0,0,WESTRING_TRIGTYPE_questtypeoption,integer\nquestmessagetype=0,0,0,WESTRING_TRIGTYPE_questmessagetype,integer\nherostat=1,0,0,WESTRING_TRIGTYPE_herostat,integer\ncompletionoption=0,0,0,WESTRING_TRIGTYPE_completionoption,boolean\nfailureoption=0,0,0,WESTRING_TRIGTYPE_failureoption,boolean\ndiscoveredoption=0,0,0,WESTRING_TRIGTYPE_discoveredoption,boolean\npauseresumeoption=0,0,0,WESTRING_TRIGTYPE_pauseresumeoption,boolean\nperiodicoption=0,0,0,WESTRING_TRIGTYPE_periodicoption,boolean\nleaderboardsortoption=0,0,0,WESTRING_TRIGTYPE_leaderboardsortoption,integer\nascendingoption=0,0,0,WESTRING_TRIGTYPE_ascendingoption,boolean\nsleepwakeoption=0,0,0,WESTRING_TRIGTYPE_sleepwakeoption,boolean\npauseunpauseoption=0,0,0,WESTRING_TRIGTYPE_pauseunpauseoption,boolean\nsharedontoption=0,0,0,WESTRING_TRIGTYPE_sharedontoption,boolean\nfadetypeoption=0,0,0,WESTRING_TRIGTYPE_fadetypeoption,boolean\nbufftype=0,0,0,WESTRING_TRIGTYPE_bufftype,integer\nbuffpolarity=1,0,0,WESTRING_TRIGTYPE_buffpolarity,integer\nbuffresist=1,0,0,WESTRING_TRIGTYPE_buffresist,integer\ncameraboundsadjusttype=0,0,0,WESTRING_TRIGTYPE_cameraboundsadjusttype,integer\navailableoption=0,0,0,WESTRING_TRIGTYPE_availableoption,boolean\nexplodedontoption=0,0,0,WESTRING_TRIGTYPE_explodedontoption,boolean\nsuspendresumeoption=0,0,0,WESTRING_TRIGTYPE_suspendresumeoption,boolean\nmissionindex=0,0,0,WESTRING_TRIGTYPE_missionindex,integer\ncampaignindex=0,0,0,WESTRING_TRIGTYPE_campaignindex,integer\ncinematicindex=0,0,0,WESTRING_TRIGTYPE_cinematicindex,integer\nmusictheme=0,0,0,WESTRING_TRIGTYPE_musictheme,string,Sound\nambientthemeday=0,0,0,WESTRING_TRIGTYPE_ambientthemeday,string\nambientthemenight=0,0,0,WESTRING_TRIGTYPE_ambientthemenight,string\nunitstatemethod=0,0,0,WESTRING_TRIGTYPE_unitstatemethod,string\ncheckingignoringoption=0,0,0,WESTRING_TRIGTYPE_checkingignoringoption,string\nplayerflag=0,0,0,WESTRING_TRIGTYPE_playerflag,playerstate\ngateoperation=0,0,0,WESTRING_TRIGTYPE_gateoperation,integer\nelevatorwallop=1,0,0,WESTRING_TRIGTYPE_elevatorwallop,boolean\nelevatorwalltype=1,0,0,WESTRING_TRIGTYPE_elevatorwalltype,integer\nuseskipoption=0,0,0,WESTRING_TRIGTYPE_useskipoption,boolean\nseldeseloption=0,0,0,WESTRING_TRIGTYPE_seldeseloption,boolean\ncachevaluetype=1,0,0,WESTRING_TRIGTYPE_cachevaluetype,integer\nfogstyle=0,0,0,WESTRING_TRIGTYPE_fogstyle,integer\ntimedlifebuffcode=1,0,0,WESTRING_TRIGTYPE_timedlifebuffcode,integer\naicaptaintype=1,0,0,WESTRING_TRIGTYPE_aicaptaintype,boolean\naicommandpop=1,0,0,WESTRING_TRIGTYPE_aicommandpop,boolean\nscriptcode=1,0,0,WESTRING_TRIGTYPE_scriptcode,string\nitemstatus=1,0,0,WESTRING_TRIGTYPE_itemstatus,integer\nitemcodestatus=1,0,0,WESTRING_TRIGTYPE_itemcodestatus,integer\nminimappingstyle=1,0,0,WESTRING_TRIGTYPE_minimappingstyle,integer\ncorpsetype=1,0,0,WESTRING_TRIGTYPE_corpsetype,integer\nstringcaseoption=1,0,0,WESTRING_TRIGTYPE_stringcaseoption,boolean\nunitorderitarg=0,0,0,WESTRING_TRIGTYPE_unitorderitarg,string\nunitorderinstant=0,0,0,WESTRING_TRIGTYPE_unitorderinstant,string\npermanentoption=0,0,0,WESTRING_TRIGTYPE_permanentoption,boolean\neffecttypebuff=0,0,0,WESTRING_TRIGTYPE_effecttypeoption,effecttype\ngameeventoption=0,0,0,WESTRING_TRIGTYPE_gameeventoption,gameevent\nplayereventoption=0,0,0,WESTRING_TRIGTYPE_playereventoption,playerevent\ncamfollowfield=1,0,0,WESTRING_TRIGTYPE_camfollowfield,integer\nbrightnesshex=1,0,0,WESTRING_TRIGTYPE_brightnesshex,string\ncolorhex=1,0,0,WESTRING_TRIGTYPE_colorhex,string\nracepreset=1,0,0,WESTRING_TRIGTYPE_racepreset,integer\nsfxtype=1,0,0,WESTRING_TRIGTYPE_sfxtype,integer\nburnstyle=1,0,0,WESTRING_TRIGTYPE_burnstyle,string\nunituiname=0,0,0,WESTRING_TRIGTYPE_unituiname,string\nlightningcode=1,0,0,WESTRING_TRIGTYPE_lightningcode,string\nmissilemdl=1,0,0,WESTRING_TRIGTYPE_missilemdl,string\nsaveloadop=1,0,0,WESTRING_TRIGTYPE_saveloadop,integer\nsaveignoreoption=1,0,0,WESTRING_TRIGTYPE_saveignoreoption,boolean\ncircledirection=1,0,0,WESTRING_TRIGTYPE_circledirection,integer\nincreasedecreaseoption=1,0,0,WESTRING_TRIGTYPE_increasedecreaseoption,boolean\nlargesmalloption=1,0,0,WESTRING_TRIGTYPE_largesmalloption,boolean\ndummyitem=1,0,0,WESTRING_TRIGTYPE_dummyitem,integer\nbuildableoption=1,0,0,WESTRING_TRIGTYPE_buildableoption,boolean\ndropoption=1,0,0,WESTRING_TRIGTYPE_dropoption,boolean\nenterleaveoption=1,0,0,WESTRING_TRIGTYPE_enterleaveoption,boolean\naibuildtype=1,0,0,WESTRING_TRIGTYPE_aibuildtype,integer\naicanceltype=1,0,0,WESTRING_TRIGTYPE_aicanceltype,integer\nairestricttype=1,0,0,WESTRING_TRIGTYPE_airestricttype,integer\naimode=1,0,0,WESTRING_TRIGTYPE_aimode,integer\nbasicabil=1,0,0,WESTRING_TRIGTYPE_basicabil,integer\nrpercentage=1,0,0,WESTRING_TRIGTYPE_rpercentage,integer\ngpercentage=1,0,0,WESTRING_TRIGTYPE_gpercentage,integer\nbpercentage=1,0,0,WESTRING_TRIGTYPE_bpercentage,integer\ncolorchannel=1,0,0,WESTRING_TRIGTYPE_colorchannel,string\nglowcolor=1,0,0,WESTRING_TRIGTYPE_glowcolor,string\naiscript=0,0,0,WESTRING_TRIGTYPE_aiscript,string,AIScript,1\nmodelfile=0,0,0,WESTRING_TRIGTYPE_modelfile,string,Model,1\nanyfile=0,0,0,WESTRING_TRIGTYPE_anyfile,string,Any,1\npreloadfile=0,0,0,WESTRING_TRIGTYPE_preloadfile,string,Preload,1\nimagefile=0,0,0,WESTRING_TRIGTYPE_imagefile,string,Image,1\nStringExt=0,0,0,WESTRING_TRIGTYPE_StringExt,string\nAnyGlobal=0,0,0,WESTRING_TRIGTYPE_AnyGlobal\nAnyType=0,0,0,WESTRING_TRIGTYPE_AnyType\nVarAsString_Real=0,0,0,WESTRING_TRIGTYPE_VarAsString_Real\nArithmeticOperator=0,0,0,WESTRING_TRIGTYPE_ArithmeticOperator\nComparisonOperator=0,0,0,WESTRING_TRIGTYPE_ComparisonOperator\nEqualNotEqualOperator=0,0,0,WESTRING_TRIGTYPE_EqualNotEqualOperator\nboolcall=0,0,0,WESTRING_TRIGTYPE_boolcall\neventcall=1,0,0,WESTRING_TRIGTYPE_eventcall\ndoodadcode=0,0,0,WESTRING_TRIGTYPE_doodadcode,integer\nmusicfile=0,0,0,WESTRING_TRIGTYPE_musicfile,string\nintegervar=1,0,0,WESTRING_TRIGTYPE_integer,integer\n[TriggerTypeDefaults]\nboolean=false,WESTRING_FALSE\ninteger=0\nreal=0\ngroup=CreateGroup(),WESTRING_TRIGDEFAULT_GROUP\nforce=CreateForce(),WESTRING_TRIGDEFAULT_FORCE\ntimer=CreateTimer(),WESTRING_TRIGDEFAULT_TIMER\ndialog=DialogCreate(),WESTRING_TRIGDEFAULT_DIALOG\nmultiboard=CreateMultiboard(),WESTRING_TRIGDEFAULT_MULTIBOARD\nregion=CreateRegion(),WESTRING_TRIGDEFAULT_REGION\ntrigger=CreateTrigger(),WESTRING_TRIGDEFAULT_TRIGGER\n[TriggerParams]\nOperatorAdd=0,ArithmeticOperator,\"+\",WESTRING_ARITHMETICOPERATOR_ADD\nOperatorSubtract=0,ArithmeticOperator,\"-\",WESTRING_ARITHMETICOPERATOR_SUBTRACT\nOperatorMultiply=0,ArithmeticOperator,\"*\",WESTRING_ARITHMETICOPERATOR_MULTIPLY\nOperatorDivide=0,ArithmeticOperator,\"/\",WESTRING_ARITHMETICOPERATOR_DIVIDE\nOperatorEqual=0,ComparisonOperator,\"==\",WESTRING_COMPARISONOPERATOR_EQUAL\nOperatorNotEqual=0,ComparisonOperator,\"!=\",WESTRING_COMPARISONOPERATOR_NOTEQUAL\nOperatorGreater=0,ComparisonOperator,\">\",WESTRING_COMPARISONOPERATOR_GREATER\nOperatorGreaterEq=0,ComparisonOperator,\">=\",WESTRING_COMPARISONOPERATOR_GREATEREQ\nOperatorLess=0,ComparisonOperator,\"<\",WESTRING_COMPARISONOPERATOR_LESS\nOperatorLessEq=0,ComparisonOperator,\"<=\",WESTRING_COMPARISONOPERATOR_LESSEQ\nOperatorEqualENE=0,EqualNotEqualOperator,\"==\",WESTRING_EQUALNOTEQUALOPERATOR_EQUAL\nOperatorNotEqualENE=0,EqualNotEqualOperator,\"!=\",WESTRING_EQUALNOTEQUALOPERATOR_NOTEQUAL\nRealQueueDelayQuest=0,real,bj_QUEUE_DELAY_QUEST,WESTRING_QUEUE_DELAY_QUEST\nRealQueueDelayHint=0,real,bj_QUEUE_DELAY_HINT,WESTRING_QUEUE_DELAY_HINT\nRealQueueDelaySecret=0,real,bj_QUEUE_DELAY_SECRET,WESTRING_QUEUE_DELAY_SECRET\nRealHandicapEasy=0,real,bj_HANDICAP_EASY,WESTRING_HANDICAP_EASY\nRealCellWidth=0,real,bj_CELLWIDTH,WESTRING_REAL_CELLWIDTH\nRealUnitFacing=0,real,bj_UNIT_FACING,WESTRING_REAL_UNITFACING\nRealCamDefDistance=0,real,bj_CAMERA_DEFAULT_DISTANCE,WESTRING_CAMDEFAULT_DISTANCE\nRealCamDefFarZ=0,real,bj_CAMERA_DEFAULT_FARZ,WESTRING_CAMDEFAULT_FARZ\nRealCamDefAoA=0,real,bj_CAMERA_DEFAULT_AOA,WESTRING_CAMDEFAULT_AOA\nRealCamDefFoV=0,real,bj_CAMERA_DEFAULT_FOV,WESTRING_CAMDEFAULT_FOV\nRealCamDefRoll=0,real,bj_CAMERA_DEFAULT_ROLL,WESTRING_CAMDEFAULT_ROLL\nRealCamDefRotation=0,real,bj_CAMERA_DEFAULT_ROTATION,WESTRING_CAMDEFAULT_ROTATION\nRealE=0,real,bj_E,WESTRING_REAL_E\nRealPi=0,real,bj_PI,WESTRING_REAL_PI\nRealGameStartedThreshold=0,real,bj_GAME_STARTED_THRESHOLD,WESTRING_REAL_GAMESTARTEDTHRESHOLD\nIntegerMaxInventory=0,integer,bj_MAX_INVENTORY,WESTRING_INTEGER_MAXINVENTORY\nIntegerMaxPlayers=0,integer,bj_MAX_PLAYERS,WESTRING_INTEGER_MAXPLAYERS\nIntegerMaxPlayerSlots=0,integer,bj_MAX_PLAYER_SLOTS,WESTRING_INTEGER_MAXPLAYERSLOTS\nLeaderboardNull=0,leaderboard,null,WESTRING_TRIGLEADERBOARD_NULL\nMultiboardNull=0,multiboard,null,WESTRING_TRIGMULTIBOARD_NULL\nRegionNull=0,region,null,WESTRING_TRIGREGION_NULL\nTriggerNull=0,trigger,null,WESTRING_TRIGTRIGGER_NULL\nTrackableNull=0,trackable,null,WESTRING_TRIGTRACKABLE_NULL\nEmptyString=1,string,\"``\",WESTRING_PRESET_EMPTYSTRING\nAttachPointOverhead=0,string,`overhead`,WESTRING_ATTACHPOINT_OVERHEAD\nAttachPointHead=0,string,`head`,WESTRING_ATTACHPOINT_HEAD\nAttachPointChest=0,string,`chest`,WESTRING_ATTACHPOINT_CHEST\nAttachPointOrigin=0,string,`origin`,WESTRING_ATTACHPOINT_ORIGIN\nAttachPointHand=0,string,`hand`,WESTRING_ATTACHPOINT_HAND\nAttachPointFoot=0,string,`foot`,WESTRING_ATTACHPOINT_FOOT\nAttachPointWeapon=0,string,`weapon`,WESTRING_ATTACHPOINT_WEAPON\nAttachPointSprite=0,string,`sprite`,WESTRING_ATTACHPOINT_SPRITE\nAttachPointMedium=0,string,`medium`,WESTRING_ATTACHPOINT_MEDIUM\nAttachPointLarge=0,string,`large`,WESTRING_ATTACHPOINT_LARGE\nAttHandRight=1,string,\"`hand right`\",WESTRING_ATTHANDRIGHT\nAttHandLeft=1,string,\"`hand left`\",WESTRING_ATTHANDLEFT\nAttFootRight=1,string,\"`foot right`\",WESTRING_ATTFOOTRIGHT\nAttFootLeft=1,string,\"`foot left`\",WESTRING_ATTFOOTLEFT\nAttFootRightMount=1,string,\"`foot right mount`\",WESTRING_ATTFOOTRIGHTMOUNT\nAttFootLeftMount=1,string,\"`foot left mount`\",WESTRING_ATTFOOTLEFTMOUNT\nAttFootRightMountRear=1,string,\"`foot right mount rear`\",WESTRING_ATTFOOTRIGHTMOUNTREAR\nAttFootLeftMountRear=1,string,\"`foot left mount rear`\",WESTRING_ATTFOOTLEFTMOUNTREAR\nAttSpriteFirst=1,string,\"`sprite first`\",WESTRING_ATTSPRITEFIRST\nAttSpriteSecond=1,string,\"`sprite second`\",WESTRING_ATTSPRITESECOND\nAttSpriteThird=1,string,\"`sprite third`\",WESTRING_ATTSPRITETHIRD\nAttSpriteFourth=1,string,\"`sprite fourth`\",WESTRING_ATTSPRITEFOURTH\nAttSpriteFifth=1,string,\"`sprite fifth`\",WESTRING_ATTSPRITEFIFTH\nAttSpriteSixth=1,string,\"`sprite sixth`\",WESTRING_ATTSPRITESIXTH\nAttSpriteRallypoint=1,string,\"`sprite rallypoint`\",WESTRING_ATTSPRITERALLYPOINT\nAttMediumFirst=1,string,\"`medium first`\",WESTRING_ATTMEDIUMFIRST\nAttMediumSecond=1,string,\"`medium second`\",WESTRING_ATTMEDIUMSECOND\nAttMediumThird=1,string,\"`medium third`\",WESTRING_ATTMEDIUMTHIRD\nAttMediumFourth=1,string,\"`medium fourth`\",WESTRING_ATTMEDIUMFOURTH\nAttMediumFifth=1,string,\"`medium fifth`\",WESTRING_ATTMEDIUMFIFTH\nAttMediumSixth=1,string,\"`medium sixth`\",WESTRING_ATTMEDIUMSIXTH\nAttMediumRallypoint=1,string,\"`medium rallypoint`\",WESTRING_ATTMEDIUMRALLYPOINT\nAttLargeFirst=1,string,\"`large first`\",WESTRING_ATTLARGEFIRST\nAttLargeSecond=1,string,\"`large second`\",WESTRING_ATTLARGESECOND\nAttLargeThird=1,string,\"`large third`\",WESTRING_ATTLARGETHIRD\nAttLargeFourth=1,string,\"`large fourth`\",WESTRING_ATTLARGEFOURTH\nAttLargeFifth=1,string,\"`large fifth`\",WESTRING_ATTLARGEFIFTH\nAttLargeSixth=1,string,\"`large sixth`\",WESTRING_ATTLARGESIXTH\nAttLargeRallypoint=1,string,\"`large rallypoint`\",WESTRING_ATTLARGERALLYPOINT\nAttachPointModifierLeft=0,string,` left`,WESTRING_ATTACHPOINTMODIFIER_LEFT\nAttachPointModifierRight=0,string,` right`,WESTRING_ATTACHPOINTMODIFIER_RIGHT\nAttachPointModifierMount=0,string,` mount`,WESTRING_ATTACHPOINTMODIFIER_MOUNT\nAttachPointModifierRear=0,string,` rear`,WESTRING_ATTACHPOINTMODIFIER_REAR\nAttachPointModifierFirst=0,string,` first`,WESTRING_ATTACHPOINTMODIFIER_FIRST\nAttachPointModifierSecond=0,string,` second`,WESTRING_ATTACHPOINTMODIFIER_SECOND\nAttachPointModifierThird=0,string,` third`,WESTRING_ATTACHPOINTMODIFIER_THIRD\nAttachPointModifierFourth=0,string,` fourth`,WESTRING_ATTACHPOINTMODIFIER_FOURTH\nAttachPointModifierFifth=0,string,` fifth`,WESTRING_ATTACHPOINTMODIFIER_FIFTH\nAttachPointModifierSixth=0,string,` sixth`,WESTRING_ATTACHPOINTMODIFIER_SIXTH\nAttachPointModifierRallypoint=0,string,` rallypoint`,WESTRING_ATTACHPOINTMODIFIER_RALLYPOINT\nPlayerStateGivesBounty=0,playerstate,PLAYER_STATE_GIVES_BOUNTY,WESTRING_PLAYER_STATE_GIVES_BOUNTY\nPlayerStateAlliedVictory=0,playerstate,PLAYER_STATE_ALLIED_VICTORY,WESTRING_PLAYER_STATE_ALLIED_VICTORY\nPlayerStateIsPlaced=0,playerstate,PLAYER_STATE_PLACED,WESTRING_PLAYER_STATE_PLACED\nPlayerStateObserverOnDeath=0,playerstate,PLAYER_STATE_OBSERVER_ON_DEATH,WESTRING_PLAYER_STATE_OBSERVER_ON_DEATH\nPlayerStateIsObserver=0,playerstate,PLAYER_STATE_OBSERVER,WESTRING_PLAYER_STATE_OBSERVER\nPlayerStateIsUnfollowable=0,playerstate,PLAYER_STATE_UNFOLLOWABLE,WESTRING_PLAYER_STATE_UNFOLLOWABLE\nPlayerStateCreepSleep=0,playerstate,PLAYER_STATE_NO_CREEP_SLEEP,WESTRING_PLAYER_STATE_NO_CREEP_SLEEP\nOrderCodePoisonArrows=0,ordercode,OrderId(\"poisonarrows\"),WESTRING_UNITORDERNOTARG_POISONARROWON\nOrderCodeUnPoisonArrows=0,ordercode,OrderId(\"unpoisonarrows\"),WESTRING_UNITORDERNOTARG_POISONARROWOFF\nOrderCodeClusterRockets=1,ordercode,OrderId(\"clusterrockets\"),WESTRING_UNITORDERPTARG_CLUSTERROCKETS\nOrderCodeSummonFactory=1,ordercode,OrderId(\"summonfactory\"),WESTRING_UNITORDERPTARG_SUMMONFACTORY\nOrderCodeRoboGoblin=1,ordercode,OrderId(\"robogoblin\"),WESTRING_UNITORDERNOTARG_ROBOGOBLIN\nOrderCodeUnRoboGoblin=1,ordercode,OrderId(\"unrobogoblin\"),WESTRING_UNITORDERNOTARG_UNROBOGOBLIN\nOrderCodeAcidBomb=1,ordercode,OrderId(\"acidbomb\"),WESTRING_UNITORDERUTARG_ACIDBOMB\nOrderCodeTransmute=1,ordercode,OrderId(\"transmute\"),WESTRING_UNITORDERUTARG_TRANSMUTE\nOrderCodeSoulBurn=1,ordercode,OrderId(\"soulburn\"),WESTRING_UNITORDERUTARG_SOULBURN\nOrderCodeHealingSpray=1,ordercode,OrderId(\"healingspray\"),WESTRING_UNITORDERPTARG_HEALINGSPRAY\nOrderCodeVolcano=1,ordercode,OrderId(\"volcano\"),WESTRING_UNITORDERPTARG_VOLCANO\nOrderCodeChemicalRage=1,ordercode,OrderId(\"chemicalrage\"),WESTRING_UNITORDERNOTARG_CHEMICALRAGE\nOrderCodeLavaMonster=1,ordercode,OrderId(\"lavamonster\"),WESTRING_UNITORDERNOTARG_LAVAMONSTER\nUnitOrderAcidBomb=1,unitorderutarg,`acidbomb`,WESTRING_UNITORDERUTARG_ACIDBOMB\nUnitOrderTransmute=1,unitorderutarg,`transmute`,WESTRING_UNITORDERUTARG_TRANSMUTE\nUnitOrderSoulBurn=1,unitorderutarg,`soulburn`,WESTRING_UNITORDERUTARG_SOULBURN\nUnitOrderPoisonArrow=0,unitorderutarg,`poisonarrowstarg`,WESTRING_UNITORDERUTARG_POISONARROW\nUnitOrderSummonFactory=1,unitorderptarg,`summonfactory`,WESTRING_UNITORDERPTARG_SUMMONFACTORY\nUnitOrderVolcano=1,unitorderptarg,`volcano`,WESTRING_UNITORDERPTARG_VOLCANO\nUnitOrderHealingSpray=1,unitorderptarg,`healingspray`,WESTRING_UNITORDERPTARG_HEALINGSPRAY\nUnitOrderClusterRockets=1,unitorderptarg,`clusterrockets`,WESTRING_UNITORDERPTARG_CLUSTERROCKETS\nUnitOrderChemicalRage=1,unitordernotarg,`chemicalrage`,WESTRING_UNITORDERNOTARG_CHEMICALRAGE\nUnitOrderRoboGoblin=1,unitordernotarg,`robogoblin`,WESTRING_UNITORDERNOTARG_ROBOGOBLIN\nUnitOrderUnRoboGoblin=1,unitordernotarg,`unrobogoblin`,WESTRING_UNITORDERNOTARG_UNROBOGOBLIN\nUnitOrderLavaMonster=1,unitordernotarg,`lavamonster`,WESTRING_UNITORDERNOTARG_LAVAMONSTER\nUnitOrderIncinerateArrowOn=1,unitordernotarg,`incineratearrowon`,WESTRING_UNITORDERNOTARG_INCINERATEARROWON\nUnitOrderIncinerateArrowOff=1,unitordernotarg,`incineratearrowoff`,WESTRING_UNITORDERNOTARG_INCINERATEARROWOFF\nHeroSkillAcidBomb=1,heroskillcode,'ANab',WESTRING_HEROSKILL_ACIDBOMB\nHeroSkillChemicalRage=1,heroskillcode,'ANcr',WESTRING_HEROSKILL_CHEMICALRAGE\nHeroSkillHealingSpray=1,heroskillcode,'ANhs',WESTRING_HEROSKILL_HEALINGSPRAY\nHeroSkillTransmute=1,heroskillcode,'ANtm',WESTRING_HEROSKILL_TRANSMUTE\nHeroSkillEngineeringUpgrade=1,heroskillcode,'ANeg',WESTRING_HEROSKILL_ENGINEERINGUPGRADE\nHeroSkillClusterRockets=1,heroskillcode,'ANcs',WESTRING_HEROSKILL_CLUSTERROCKETS\nHeroSkillSummonFactory=1,heroskillcode,'ANsy',WESTRING_HEROSKILL_SUMMONFACTORY\nHeroSkillRoboGoblin=1,heroskillcode,'ANrg',WESTRING_HEROSKILL_ROBOGOBLIN\nHeroSkillIncinerate=1,heroskillcode,'ANic',WESTRING_HEROSKILL_INCINERATE\nHeroSkillIncinerateArrow=1,heroskillcode,'ANia',WESTRING_HEROSKILL_INCINERATEARROW\nHeroSkillSoulBurn=1,heroskillcode,'ANso',WESTRING_HEROSKILL_SOULBURN\nHeroSkillLavaMonster=1,heroskillcode,'ANlm',WESTRING_HEROSKILL_LAVAMONSTER\nHeroSkillVolcano=1,heroskillcode,'ANvc',WESTRING_HEROSKILL_VOLCANO\nunknownAloc=0,abilcode,'Aloc',WESTRING_UNKNOWNABIL_ALOC\nunknownAatk=0,abilcode,'Aatk',WESTRING_UNKNOWNABIL_AATK\nunknownAmov=0,abilcode,'Amov',WESTRING_UNKNOWNABIL_AMOV\nunknownAalr=0,abilcode,'Aalr',WESTRING_UNKNOWNABIL_AALR\nunknownAfir=0,abilcode,'Afir',WESTRING_UNKNOWNABIL_AFIR\nunknownAfih=0,abilcode,'Afih',WESTRING_UNKNOWNABIL_AFIH\nunknownAfin=0,abilcode,'Afin',WESTRING_UNKNOWNABIL_AFIN\nunknownAfio=0,abilcode,'Afio',WESTRING_UNKNOWNABIL_AFIO\nunknownAfiu=0,abilcode,'Afiu',WESTRING_UNKNOWNABIL_AFIU\nunknownAher=0,abilcode,'Aher',WESTRING_UNKNOWNABIL_AHER\nunknownAsla=0,abilcode,'Asla',WESTRING_UNKNOWNABIL_ASLA\nunknownARal=0,abilcode,'ARal',WESTRING_UNKNOWNABIL_ARAL\nunknownApit=0,abilcode,'Apit',WESTRING_UNKNOWNABIL_APIT\nunknownArev=0,abilcode,'Arev',WESTRING_UNKNOWNABIL_AREV\nunknownAawa=0,abilcode,'Aawa',WESTRING_UNKNOWNABIL_AAWA\nunknownAGbu=0,abilcode,'AGbu',WESTRING_UNKNOWNABIL_AGBU\nunknownAHbu=0,abilcode,'AHbu',WESTRING_UNKNOWNABIL_AHBU\nunknownAObu=0,abilcode,'AObu',WESTRING_UNKNOWNABIL_AOBU\nunknownAEbu=0,abilcode,'AEbu',WESTRING_UNKNOWNABIL_AEBU\nunknownAUbu=0,abilcode,'AUbu',WESTRING_UNKNOWNABIL_AUBU\nunknownANbu=0,abilcode,'ANbu',WESTRING_UNKNOWNABIL_ANBU\nBooleanIsSinglePlayer=0,boolean,bj_isSinglePlayer,WESTRING_BOOLEAN_IS_SINGLEPLAYER\nScriptCodeWantDestroyGroup=0,scriptcode,set bj_wantDestroyGroup = true,WESTRING_SCRIPT_WANTDESTROY\nScriptCodeLoopStart=0,scriptcode,loop,WESTRING_SCRIPT_LOOP\nScriptCodeLoopEnd=0,scriptcode,endloop,WESTRING_SCRIPT_ENDLOOP\nGamestateDivineIntervention=1,gamestate,GAME_STATE_DIVINE_INTERVENTION,WESTRING_GAME_STATE_DIVINE_INTERVENTION\nGamestateDisconnected=1,gamestate,GAME_STATE_DISCONNECTED,WESTRING_GAME_STATE_DISCONNECTED\nGamestateTimeOfDay=1,gamestate,GAME_STATE_TIME_OF_DAY,WESTRING_GAME_STATE_TIME_OF_DAY\nIGamestateDivineIntervention=1,igamestate,GAME_STATE_DIVINE_INTERVENTION,WESTRING_GAME_STATE_DIVINE_INTERVENTION\nIGamestateDisconnected=1,igamestate,GAME_STATE_DISCONNECTED,WESTRING_GAME_STATE_DISCONNECTED\nEventIdGameEnterRegion=1,eventid,EVENT_GAME_ENTER_REGION,WESTRING_GAMEEVENTOPTION_ENTERREGION\nEventIdGameLeaveRegion=1,eventid,EVENT_GAME_LEAVE_REGION,WESTRING_GAMEEVENTOPTION_LEAVEREGION\nEventIdGameStateLimit=1,eventid,EVENT_GAME_STATE_LIMIT,WESTRING_GAMEEVENTOPTION_STATELIMIT\nEventIdGameVariableLimit=1,eventid,EVENT_GAME_VARIABLE_LIMIT,WESTRING_GAMEEVENTOPTION_VARLIMIT\nEventIdGameUnitStateLimit=1,eventid,EVENT_UNIT_STATE_LIMIT,WESTRING_EVENTID_UNIT_STATE_LIMIT\nEventIdPlayerStateLimit=1,eventid,EVENT_PLAYER_STATE_LIMIT,WESTRING_EVENTID_EVENT_PLAYER_STATE_LIMIT\nEventIdGameVictory=1,eventid,EVENT_GAME_VICTORY,WESTRING_EVENTID_GAME_VICTORY\nEventIdGameEndLevel=1,eventid,EVENT_GAME_END_LEVEL,WESTRING_EVENTID_EVENT_GAME_END_LEVEL\nEventIdGameTimerExpired=1,eventid,EVENT_GAME_TIMER_EXPIRED,WESTRING_EVENTID_EVENT_GAME_TIMER_EXPIRED\nEventIdGameShowSkills=1,eventid,EVENT_GAME_SHOW_SKILL,WESTRING_EVENTID_EVENT_GAME_SHOW_SKILL\nEventIdGameBuildSubmenu=1,eventid,EVENT_GAME_BUILD_SUBMENU,WESTRING_EVENTID_EVENT_GAME_BUILD_SUBMENU\nEventIdPlayerAllianceChanged=1,eventid,EVENT_PLAYER_ALLIANCE_CHANGED,WESTRING_EVENTID_EVENT_PLAYER_ALLIANCE_CHANGED\nEventIdPlayerDefeat=1,eventid,EVENT_PLAYER_DEFEAT,WESTRING_EVENTID_EVENT_PLAYER_DEFEAT\nEventIdPlayerVictory=1,eventid,EVENT_PLAYER_VICTORY,WESTRING_EVENTID_EVENT_PLAYER_VICTORY\nEventIdPlayerLeave=1,eventid,EVENT_PLAYER_LEAVE,WESTRING_EVENTID_EVENT_PLAYER_LEAVE\nEventIdPlayerChat=1,eventid,EVENT_PLAYER_CHAT,WESTRING_EVENTID_EVENT_PLAYER_CHAT\nEventIdPlayerEndCinematic=1,eventid,EVENT_PLAYER_END_CINEMATIC,WESTRING_EVENTID_EVENT_PLAYER_END_CINEMATIC\nEventIdPlayerWidgetDeath=1,eventid,EVENT_WIDGET_DEATH,WESTRING_EVENTID_EVENT_WIDGET_DEATH\nEventIdPlayerDialogButtonClick=1,eventid,EVENT_DIALOG_BUTTON_CLICK,WESTRING_EVENTID_EVENT_DIALOG_BUTTON_CLICK\nEventIdPlayerDialogClick=1,eventid,EVENT_DIALOG_CLICK,WESTRING_EVENTID_EVENT_DIALOG_CLICK\nEventIdPlayerUnitEventDeath=1,eventid,EVENT_PLAYER_UNIT_DEATH,WESTRING_PUEVENT_DEATH\nEventIdPlayerUnitEventDecay=1,eventid,EVENT_PLAYER_UNIT_DECAY,WESTRING_PUEVENT_DECAY\nEventIdPlayerUnitEventHero_Level=1,eventid,EVENT_PLAYER_HERO_LEVEL,WESTRING_PUEVENT_HEROLEVEL\nEventIdPlayerUnitEventHero_Skill=1,eventid,EVENT_PLAYER_HERO_SKILL,WESTRING_PUEVENT_HEROSKILL\nEventIdPlayerUnitEventHero_Revivable=1,eventid,EVENT_PLAYER_HERO_REVIVABLE,WESTRING_PUEVENT_HEROREVIVABLE\nEventIdPlayerUnitEventHeroUseItem=1,eventid,EVENT_PLAYER_UNIT_USE_ITEM,WESTRING_PUEVENT_HEROUSEITEM\nEventIdPlayerUnitEventHeroPickUpItem=1,eventid,EVENT_PLAYER_UNIT_PICKUP_ITEM,WESTRING_PUEVENT_HEROPICKUPITEM\nEventIdPlayerUnitEventHeroDropItem=1,eventid,EVENT_PLAYER_UNIT_DROP_ITEM,WESTRING_PUEVENT_HERODROPITEM\nEventIdPlayerUnitEventAttacked=1,eventid,EVENT_PLAYER_UNIT_ATTACKED,WESTRING_PUEVENT_ATTACKED\nEventIdPlayerUnitEventRescued=1,eventid,EVENT_PLAYER_UNIT_RESCUED,WESTRING_PUEVENT_RESCUED\nEventIdPlayerUnitEventSummoned=1,eventid,EVENT_PLAYER_UNIT_SUMMON,WESTRING_PUEVENT_SUMMONED\nEventIdPlayerUnitEventLoaded=1,eventid,EVENT_PLAYER_UNIT_LOADED,WESTRING_PUEVENT_LOADED\nEventIdPlayerUnitEventTrain_Start=1,eventid,EVENT_PLAYER_UNIT_TRAIN_START,WESTRING_PUEVENT_TRAINSTART\nEventIdPlayerUnitEventTrain_Cancel=1,eventid,EVENT_PLAYER_UNIT_TRAIN_CANCEL,WESTRING_PUEVENT_TRAINCANCEL\nEventIdPlayerUnitEventTrain_Finish=1,eventid,EVENT_PLAYER_UNIT_TRAIN_FINISH,WESTRING_PUEVENT_TRAINFINISH\nEventIdPlayerUnitEventConstruct_Start=1,eventid,EVENT_PLAYER_UNIT_CONSTRUCT_START,WESTRING_PUEVENT_CONSTRUCTSTART\nEventIdPlayerUnitEventConstruct_Cancel=1,eventid,EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL,WESTRING_PUEVENT_CONSTRUCTCANCEL\nEventIdPlayerUnitEventConstruct_Finish=1,eventid,EVENT_PLAYER_UNIT_CONSTRUCT_FINISH,WESTRING_PUEVENT_CONSTRUCTFINISH\nEventIdPlayerUnitEventReviveStart=1,eventid,EVENT_PLAYER_HERO_REVIVE_START,WESTRING_PUEVENT_REVIVESTART\nEventIdPlayerUnitEventReviveCancel=1,eventid,EVENT_PLAYER_HERO_REVIVE_CANCEL,WESTRING_PUEVENT_REVIVECANCEL\nEventIdPlayerUnitEventReviveFinish=1,eventid,EVENT_PLAYER_HERO_REVIVE_FINISH,WESTRING_PUEVENT_REVIVEFINISH\nEventIdPlayerUnitEventUpgrade_Start=1,eventid,EVENT_PLAYER_UNIT_UPGRADE_START,WESTRING_PUEVENT_UPGRADESTART\nEventIdPlayerUnitEventUpgrade_Cancel=1,eventid,EVENT_PLAYER_UNIT_UPGRADE_CANCEL,WESTRING_PUEVENT_UPGRADECANCEL\nEventIdPlayerUnitEventUpgrade_Finish=1,eventid,EVENT_PLAYER_UNIT_UPGRADE_FINISH,WESTRING_PUEVENT_UPGRADEFINISH\nEventIdPlayerUnitEventResearch_Start=1,eventid,EVENT_PLAYER_UNIT_RESEARCH_START,WESTRING_PUEVENT_RESEARCHSTART\nEventIdPlayerUnitEventResearch_Cancel=1,eventid,EVENT_PLAYER_UNIT_RESEARCH_CANCEL,WESTRING_PUEVENT_RESEARCHCANCEL\nEventIdPlayerUnitEventResearch_Finish=1,eventid,EVENT_PLAYER_UNIT_RESEARCH_FINISH,WESTRING_PUEVENT_RESEARCHFINISH\nEventIdPlayerUnitEventIssued_Unit_Order=1,eventid,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER,WESTRING_PUEVENT_ISSUEDUNITORDER\nEventIdPlayerUnitEventIssued_Point_Order=1,eventid,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,WESTRING_PUEVENT_ISSUEDPOINTORDER\nEventIdPlayerUnitEventIssued_Order=1,eventid,EVENT_PLAYER_UNIT_ISSUED_ORDER,WESTRING_PUEVENT_ISSUEDORDER\nEventIdUnitEventSummon=1,eventid,EVENT_UNIT_SUMMON,WESTRING_UEVENT_SUMMON\nEventIdUnitEventDeath=1,eventid,EVENT_UNIT_DEATH,WESTRING_UEVENT_DEATH\nEventIdUnitEventDecay=1,eventid,EVENT_UNIT_DECAY,WESTRING_UEVENT_DECAY\nEventIdUnitEventDamaged=1,eventid,EVENT_UNIT_DAMAGED,WESTRING_UEVENT_DAMAGED\nEventIdUnitEventHeroLevel=1,eventid,EVENT_UNIT_HERO_LEVEL,WESTRING_UEVENT_HEROLEVEL\nEventIdUnitEventHeroSkill=1,eventid,EVENT_UNIT_HERO_SKILL,WESTRING_UEVENT_HEROSKILL\nEventIdUnitEventHeroRevivable=1,eventid,EVENT_UNIT_HERO_REVIVABLE,WESTRING_UEVENT_HEROREVIVABLE\nEventIdUnitEventHeroUseItem=1,eventid,EVENT_UNIT_USE_ITEM,WESTRING_UEVENT_HEROUSEITEM\nEventIdUnitEventHeroPickUpItem=1,eventid,EVENT_UNIT_PICKUP_ITEM,WESTRING_UEVENT_HEROPICKUPITEM\nEventIdUnitEventHeroDropItem=1,eventid,EVENT_UNIT_DROP_ITEM,WESTRING_UEVENT_HERODROPITEM\nEventIdUnitEventAttacked=1,eventid,EVENT_UNIT_ATTACKED,WESTRING_UEVENT_ATTACKED\nEventIdUnitEventRescued=1,eventid,EVENT_UNIT_RESCUED,WESTRING_UEVENT_RESCUED\nEventIdUnitEventSelected=1,eventid,EVENT_UNIT_SELECTED,WESTRING_UEVENT_SELECTED\nEventIdUnitEventDeselected=1,eventid,EVENT_UNIT_DESELECTED,WESTRING_UEVENT_DESELECTED\nEventIdUnitEventLoaded=1,eventid,EVENT_UNIT_LOADED,WESTRING_UEVENT_LOADED\nEventIdUnitEventAcquiredTarget=1,eventid,EVENT_UNIT_ACQUIRED_TARGET,WESTRING_UEVENT_ACQUIREDTARGET\nEventIdUnitEventTargetInRange=1,eventid,EVENT_UNIT_TARGET_IN_RANGE,WESTRING_UEVENT_TARGETINRANGE\nEventIdUnitEventTrainStart=1,eventid,EVENT_UNIT_TRAIN_START,WESTRING_UEVENT_TRAINSTART\nEventIdUnitEventTrainCancel=1,eventid,EVENT_UNIT_TRAIN_CANCEL,WESTRING_UEVENT_TRAINCANCEL\nEventIdUnitEventTrainFinish=1,eventid,EVENT_UNIT_TRAIN_FINISH,WESTRING_UEVENT_TRAINFINISH\nEventIdUnitEventReviveStart=1,eventid,EVENT_UNIT_HERO_REVIVE_START,WESTRING_UEVENT_REVIVESTART\nEventIdUnitEventReviveCancel=1,eventid,EVENT_UNIT_HERO_REVIVE_CANCEL,WESTRING_UEVENT_REVIVECANCEL\nEventIdUnitEventReviveFinish=1,eventid,EVENT_UNIT_HERO_REVIVE_FINISH,WESTRING_UEVENT_REVIVEFINISH\nEventIdUnitEventUpgradeStart=1,eventid,EVENT_UNIT_UPGRADE_START,WESTRING_UEVENT_UPGRADESTART\nEventIdUnitEventUpgradeCancel=1,eventid,EVENT_UNIT_UPGRADE_CANCEL,WESTRING_UEVENT_UPGRADECANCEL\nEventIdUnitEventUpgradeFinish=1,eventid,EVENT_UNIT_UPGRADE_FINISH,WESTRING_UEVENT_UPGRADEFINISH\nEventIdUnitEventResearchStart=1,eventid,EVENT_UNIT_RESEARCH_START,WESTRING_UEVENT_RESEARCHSTART\nEventIdUnitEventResearchCancel=1,eventid,EVENT_UNIT_RESEARCH_CANCEL,WESTRING_UEVENT_RESEARCHCANCEL\nEventIdUnitEventResearchFinish=1,eventid,EVENT_UNIT_RESEARCH_FINISH,WESTRING_UEVENT_RESEARCHFINISH\nEventIdUnitEventIssueUnitOrder=1,eventid,EVENT_UNIT_ISSUED_TARGET_ORDER,WESTRING_UEVENT_ISSUEUNITORDER\nEventIdUnitEventIssuePointOrder=1,eventid,EVENT_UNIT_ISSUED_POINT_ORDER,WESTRING_UEVENT_ISSUEPOINTORDER\nEventIdEventIdUnitEventIssueOrder=1,eventid,EVENT_UNIT_ISSUED_ORDER,WESTRING_UEVENT_ISSUEORDER\nEventIdGameLoaded=1,eventid,EVENT_GAME_LOADED,WESTRING_EVENTIDGAMELOADED\nEventIdGameSaved=1,eventid,EVENT_GAME_SAVE,WESTRING_EVENTIDGAMESAVED\nEventIdLeftDown=1,eventid,EVENT_PLAYER_ARROW_LEFT_DOWN,WESTRING_EVENTIDLEFTDOWN\nEventIdRightDown=1,eventid,EVENT_PLAYER_ARROW_RIGHT_DOWN,WESTRING_EVENTIDRIGHTDOWN\nEventIdUpDown=1,eventid,EVENT_PLAYER_ARROW_UP_DOWN,WESTRING_EVENTIDUPDOWN\nEventIdDownDown=1,eventid,EVENT_PLAYER_ARROW_DOWN_DOWN,WESTRING_EVENTIDDOWNDOWN\nEventIdLeftUp=1,eventid,EVENT_PLAYER_ARROW_LEFT_UP,WESTRING_EVENTIDLEFTUP\nEventIdRightUp=1,eventid,EVENT_PLAYER_ARROW_RIGHT_UP,WESTRING_EVENTIDRIGHTUP\nEventIdUpUp=1,eventid,EVENT_PLAYER_ARROW_UP_UP,WESTRING_EVENTIDUPUP\nEventIdDownUp=1,eventid,EVENT_PLAYER_ARROW_DOWN_UP,WESTRING_EVENTIDDOWNUP\nEventIdPlayerUnitEventUnitSell=1,eventid,EVENT_PLAYER_UNIT_SELL,WESTRING_EVENTIDPLAYERUNITEVENTUNITSELL\nEventIdPlayerUnitEventChangeOwner=1,eventid,EVENT_PLAYER_UNIT_CHANGE_OWNER,WESTRING_EVENTIDPLAYERUNITEVENTCHANGEOWNER\nEventIdPlayerUnitEventItemSell=1,eventid,EVENT_PLAYER_UNIT_SELL_ITEM,WESTRING_EVENTIDPLAYERUNITEVENTITEMSELL\nEventIdPlayerUnitEventSpellChannel=1,eventid,EVENT_PLAYER_UNIT_SPELL_CHANNEL,WESTRING_EVENTIDPLAYERUNITEVENTSPELLCHANNEL\nEventIdPlayerUnitEventSpellCast=1,eventid,EVENT_PLAYER_UNIT_SPELL_CAST,WESTRING_EVENTIDPLAYERUNITEVENTSPELLCAST\nEventIdPlayerUnitEvent=1,eventid,EVENT_PLAYER_UNIT_SPELL_EFFECT,WESTRING_EVENTIDPLAYERUNITEVENT\nEventIdPlayerUnitEvent=1,eventid,EVENT_PLAYER_UNIT_SPELL_FINISH,WESTRING_EVENTIDPLAYERUNITEVENT\nEventIdPlayerUnitEvent=1,eventid,EVENT_PLAYER_UNIT_SPELL_ENDCAST,WESTRING_EVENTIDPLAYERUNITEVENT\nEventIdUnitEventUnitSell=1,eventid,EVENT_UNIT_SELL,WESTRING_EVENTIDUNITEVENTUNITSELL\nEventIdUnitEventChangeOwner=1,eventid,EVENT_UNIT_CHANGE_OWNER,WESTRING_EVENTIDUNITEVENTCHANGEOWNER\nEventIdUnitEventItemSell=1,eventid,EVENT_UNIT_SELL_ITEM,WESTRING_EVENTIDUNITEVENTITEMSELL\nEventIdUnitEventSpellChannel=1,eventid,EVENT_UNIT_SPELL_CHANNEL,WESTRING_EVENTIDUNITEVENTSPELLCHANNEL\nEventIdUnitEventSpellCast=1,eventid,EVENT_UNIT_SPELL_CAST,WESTRING_EVENTIDUNITEVENTSPELLCAST\nEventIdUnitEvent=1,eventid,EVENT_UNIT_SPELL_EFFECT,WESTRING_EVENTIDUNITEVENT\nEventIdUnitEvent=1,eventid,EVENT_UNIT_SPELL_FINISH,WESTRING_EVENTIDUNITEVENT\nEventIdUnitEvent=1,eventid,EVENT_UNIT_SPELL_ENDCAST,WESTRING_EVENTIDUNITEVENT\nEventIdTrackableHit=1,eventid,EVENT_GAME_TRACKABLE_HIT,WESTRING_GAMEEVENTOPTION_TRACKABLEHIT\nEventIdTrackableTrack=1,eventid,EVENT_GAME_TRACKABLE_TRACK,WESTRING_GAMEEVENTOPTION_TRACKABLETRACK\nUnitUINamearchmage=0,unituiname,`archmage`,WESTRING_UNITUINAMEARCHMAGE\nUnitUINamebloodmage=0,unituiname,`bloodmage`,WESTRING_UNITUINAMEBLOODMAGE\nUnitUINamemountainking=0,unituiname,`mountainking`,WESTRING_UNITUINAMEMOUNTAINKING\nUnitUINamepaladin=0,unituiname,`paladin`,WESTRING_UNITUINAMEPALADIN\nUnitUINamehumantransportship=0,unituiname,`humantransportship`,WESTRING_UNITUINAMEHUMANTRANSPORTSHIP\nUnitUINamehumanbattleship=0,unituiname,`humanbattleship`,WESTRING_UNITUINAMEHUMANBATTLESHIP\nUnitUINamehumandestroyer=0,unituiname,`humandestroyer`,WESTRING_UNITUINAMEHUMANDESTROYER\nUnitUINamedragonhawk=0,unituiname,`dragonhawk`,WESTRING_UNITUINAMEDRAGONHAWK\nUnitUINamefootman=0,unituiname,`footman`,WESTRING_UNITUINAMEFOOTMAN\nUnitUINamegryphonrider=0,unituiname,`gryphonrider`,WESTRING_UNITUINAMEGRYPHONRIDER\nUnitUINameflyingmachine=0,unituiname,`flyingmachine`,WESTRING_UNITUINAMEFLYINGMACHINE\nUnitUINameknight=0,unituiname,`knight`,WESTRING_UNITUINAMEKNIGHT\nUnitUINamemilitia=0,unituiname,`militia`,WESTRING_UNITUINAMEMILITIA\nUnitUINamepriest=0,unituiname,`priest`,WESTRING_UNITUINAMEPRIEST\nUnitUINamemortarteam=0,unituiname,`mortarteam`,WESTRING_UNITUINAMEMORTARTEAM\nUnitUINamesiegeengine=0,unituiname,`siegeengine`,WESTRING_UNITUINAMESIEGEENGINE\nUnitUINamepeasant=0,unituiname,`peasant`,WESTRING_UNITUINAMEPEASANT\nUnitUINamephoenix=0,unituiname,`phoenix`,WESTRING_UNITUINAMEPHOENIX\nUnitUINamephoenixegg=0,unituiname,`phoenixegg`,WESTRING_UNITUINAMEPHOENIXEGG\nUnitUINamerifleman=0,unituiname,`rifleman`,WESTRING_UNITUINAMERIFLEMAN\nUnitUINamerocketengine=0,unituiname,`rocketengine`,WESTRING_UNITUINAMEROCKETENGINE\nUnitUINamesorceress=0,unituiname,`sorceress`,WESTRING_UNITUINAMESORCERESS\nUnitUINamespellbreaker=0,unituiname,`spellbreaker`,WESTRING_UNITUINAMESPELLBREAKER\nUnitUINamewaterelemental1=0,unituiname,`waterelemental1`,WESTRING_UNITUINAMEWATERELEMENTAL1\nUnitUINamewaterelemental2=0,unituiname,`waterelemental2`,WESTRING_UNITUINAMEWATERELEMENTAL2\nUnitUINamewaterelemental3=0,unituiname,`waterelemental3`,WESTRING_UNITUINAMEWATERELEMENTAL3\nUnitUINamealtarofkings=0,unituiname,`altarofkings`,WESTRING_UNITUINAMEALTAROFKINGS\nUnitUINameworkshop=0,unituiname,`workshop`,WESTRING_UNITUINAMEWORKSHOP\nUnitUINamearcanesanctum=0,unituiname,`arcanesanctum`,WESTRING_UNITUINAMEARCANESANCTUM\nUnitUINamehumanarcanetower=0,unituiname,`humanarcanetower`,WESTRING_UNITUINAMEHUMANARCANETOWER\nUnitUINamehumanbarracks=0,unituiname,`humanbarracks`,WESTRING_UNITUINAMEHUMANBARRACKS\nUnitUINameblacksmith=0,unituiname,`blacksmith`,WESTRING_UNITUINAMEBLACKSMITH\nUnitUINamecastle=0,unituiname,`castle`,WESTRING_UNITUINAMECASTLE\nUnitUINamecannontower=0,unituiname,`cannontower`,WESTRING_UNITUINAMECANNONTOWER\nUnitUINamegryphonaviary=0,unituiname,`gryphonaviary`,WESTRING_UNITUINAMEGRYPHONAVIARY\nUnitUINameguardtower=0,unituiname,`guardtower`,WESTRING_UNITUINAMEGUARDTOWER\nUnitUINamefarm=0,unituiname,`farm`,WESTRING_UNITUINAMEFARM\nUnitUINamekeep=0,unituiname,`keep`,WESTRING_UNITUINAMEKEEP\nUnitUINamehumanlumbermill=0,unituiname,`humanlumbermill`,WESTRING_UNITUINAMEHUMANLUMBERMILL\nUnitUINamehumanshipyard=0,unituiname,`humanshipyard`,WESTRING_UNITUINAMEHUMANSHIPYARD\nUnitUINametownhall=0,unituiname,`townhall`,WESTRING_UNITUINAMETOWNHALL\nUnitUINamearcanevault=0,unituiname,`arcanevault`,WESTRING_UNITUINAMEARCANEVAULT\nUnitUINamescouttower=0,unituiname,`scouttower`,WESTRING_UNITUINAMESCOUTTOWER\nUnitUINameblademaster=0,unituiname,`blademaster`,WESTRING_UNITUINAMEBLADEMASTER\nUnitUINamefarseer=0,unituiname,`farseer`,WESTRING_UNITUINAMEFARSEER\nUnitUINameshadowhunter=0,unituiname,`shadowhunter`,WESTRING_UNITUINAMESHADOWHUNTER\nUnitUINametaurenchieftain=0,unituiname,`taurenchieftain`,WESTRING_UNITUINAMETAURENCHIEFTAIN\nUnitUINamewatcherward=0,unituiname,`watcherward`,WESTRING_UNITUINAMEWATCHERWARD\nUnitUINameorcishtransportship=0,unituiname,`orcishtransportship`,WESTRING_UNITUINAMEORCISHTRANSPORTSHIP\nUnitUINamedemolisher=0,unituiname,`demolisher`,WESTRING_UNITUINAMEDEMOLISHER\nUnitUINameorcishdestroyer=0,unituiname,`orcishdestroyer`,WESTRING_UNITUINAMEORCISHDESTROYER\nUnitUINamewitchdoctor=0,unituiname,`witchdoctor`,WESTRING_UNITUINAMEWITCHDOCTOR\nUnitUINamesentryward=0,unituiname,`sentryward`,WESTRING_UNITUINAMESENTRYWARD\nUnitUINamegrunt=0,unituiname,`grunt`,WESTRING_UNITUINAMEGRUNT\nUnitUINameheadhunter=0,unituiname,`headhunter`,WESTRING_UNITUINAMEHEADHUNTER\nUnitUINamehealingward=0,unituiname,`healingward`,WESTRING_UNITUINAMEHEALINGWARD\nUnitUINamekotobeast=0,unituiname,`kotobeast`,WESTRING_UNITUINAMEKOTOBEAST\nUnitUINamepeon=0,unituiname,`peon`,WESTRING_UNITUINAMEPEON\nUnitUINamewolfrider=0,unituiname,`wolfrider`,WESTRING_UNITUINAMEWOLFRIDER\nUnitUINameshaman=0,unituiname,`shaman`,WESTRING_UNITUINAMESHAMAN\nUnitUINameserpentward1=0,unituiname,`serpentward1`,WESTRING_UNITUINAMESERPENTWARD1\nUnitUINameserpentward2=0,unituiname,`serpentward2`,WESTRING_UNITUINAMESERPENTWARD2\nUnitUINameserpentward3=0,unituiname,`serpentward3`,WESTRING_UNITUINAMESERPENTWARD3\nUnitUINameserpentward4=0,unituiname,`serpentward4`,WESTRING_UNITUINAMESERPENTWARD4\nUnitUINamespiritwalkermorph=0,unituiname,`spiritwalkermorph`,WESTRING_UNITUINAMESPIRITWALKERMORPH\nUnitUINamespiritwalker=0,unituiname,`spiritwalker`,WESTRING_UNITUINAMESPIRITWALKER\nUnitUINamespiritwolf1=0,unituiname,`spiritwolf1`,WESTRING_UNITUINAMESPIRITWOLF1\nUnitUINamespiritwolf2=0,unituiname,`spiritwolf2`,WESTRING_UNITUINAMESPIRITWOLF2\nUnitUINamespiritwolf3=0,unituiname,`spiritwolf3`,WESTRING_UNITUINAMESPIRITWOLF3\nUnitUINametauren=0,unituiname,`tauren`,WESTRING_UNITUINAMETAUREN\nUnitUINameberserker=0,unituiname,`berserker`,WESTRING_UNITUINAMEBERSERKER\nUnitUINametrollbatrider=0,unituiname,`trollbatrider`,WESTRING_UNITUINAMETROLLBATRIDER\nUnitUINamestasistraptotem=0,unituiname,`stasistraptotem`,WESTRING_UNITUINAMESTASISTRAPTOTEM\nUnitUINamewindrider=0,unituiname,`windrider`,WESTRING_UNITUINAMEWINDRIDER\nUnitUINamealtarofstorms=0,unituiname,`altarofstorms`,WESTRING_UNITUINAMEALTAROFSTORMS\nUnitUINameorcbarracks=0,unituiname,`orcbarracks`,WESTRING_UNITUINAMEORCBARRACKS\nUnitUINamebeastiary=0,unituiname,`beastiary`,WESTRING_UNITUINAMEBEASTIARY\nUnitUINamewarmill=0,unituiname,`warmill`,WESTRING_UNITUINAMEWARMILL\nUnitUINamefortress=0,unituiname,`fortress`,WESTRING_UNITUINAMEFORTRESS\nUnitUINamegreathall=0,unituiname,`greathall`,WESTRING_UNITUINAMEGREATHALL\nUnitUINameorcshipyard=0,unituiname,`orcshipyard`,WESTRING_UNITUINAMEORCSHIPYARD\nUnitUINamespiritlodge=0,unituiname,`spiritlodge`,WESTRING_UNITUINAMESPIRITLODGE\nUnitUINamestronghold=0,unituiname,`stronghold`,WESTRING_UNITUINAMESTRONGHOLD\nUnitUINametrollburrow=0,unituiname,`trollburrow`,WESTRING_UNITUINAMETROLLBURROW\nUnitUINametaurentotem=0,unituiname,`taurentotem`,WESTRING_UNITUINAMETAURENTOTEM\nUnitUINamevoodoolounge=0,unituiname,`voodoolounge`,WESTRING_UNITUINAMEVOODOOLOUNGE\nUnitUINamewatchtower=0,unituiname,`watchtower`,WESTRING_UNITUINAMEWATCHTOWER\nUnitUINamedemonhunter=0,unituiname,`demonhunter`,WESTRING_UNITUINAMEDEMONHUNTER\nUnitUINamedemonhuntermorphed=0,unituiname,`demonhuntermorphed`,WESTRING_UNITUINAMEDEMONHUNTERMORPHED\nUnitUINamekeeperofthegrove=0,unituiname,`keeperofthegrove`,WESTRING_UNITUINAMEKEEPEROFTHEGROVE\nUnitUINamepriestessofthemoon=0,unituiname,`priestessofthemoon`,WESTRING_UNITUINAMEPRIESTESSOFTHEMOON\nUnitUINamewarden=0,unituiname,`warden`,WESTRING_UNITUINAMEWARDEN\nUnitUINamearcher=0,unituiname,`archer`,WESTRING_UNITUINAMEARCHER\nUnitUINameglaivethrower=0,unituiname,`glaivethrower`,WESTRING_UNITUINAMEGLAIVETHROWER\nUnitUINamenightelfbattleship=0,unituiname,`nightelfbattleship`,WESTRING_UNITUINAMENIGHTELFBATTLESHIP\nUnitUINamechimaera=0,unituiname,`chimaera`,WESTRING_UNITUINAMECHIMAERA\nUnitUINamedruidoftheclawmorphed=0,unituiname,`druidoftheclawmorphed`,WESTRING_UNITUINAMEDRUIDOFTHECLAWMORPHED\nUnitUINamenightelfdestroyer=0,unituiname,`nightelfdestroyer`,WESTRING_UNITUINAMENIGHTELFDESTROYER\nUnitUINamedruidoftheclaw=0,unituiname,`druidoftheclaw`,WESTRING_UNITUINAMEDRUIDOFTHECLAW\nUnitUINamedruidofthetalon=0,unituiname,`druidofthetalon`,WESTRING_UNITUINAMEDRUIDOFTHETALON\nUnitUINamedryad=0,unituiname,`dryad`,WESTRING_UNITUINAMEDRYAD\nUnitUINamedruidofthetalonmorphed=0,unituiname,`druidofthetalonmorphed`,WESTRING_UNITUINAMEDRUIDOFTHETALONMORPHED\nUnitUINamefaeriedragon=0,unituiname,`faeriedragon`,WESTRING_UNITUINAMEFAERIEDRAGON\nUnitUINameforceofnature=0,unituiname,`forceofnature`,WESTRING_UNITUINAMEFORCEOFNATURE\nUnitUINamehippogryph=0,unituiname,`hippogryph`,WESTRING_UNITUINAMEHIPPOGRYPH\nUnitUINameriddenhippogryph=0,unituiname,`riddenhippogryph`,WESTRING_UNITUINAMERIDDENHIPPOGRYPH\nUnitUINamemountaingiant=0,unituiname,`mountaingiant`,WESTRING_UNITUINAMEMOUNTAINGIANT\nUnitUINamehuntress=0,unituiname,`huntress`,WESTRING_UNITUINAMEHUNTRESS\nUnitUINamespiritofvengeance=0,unituiname,`spiritofvengeance`,WESTRING_UNITUINAMESPIRITOFVENGEANCE\nUnitUINamevengeance=0,unituiname,`vengeance`,WESTRING_UNITUINAMEVENGEANCE\nUnitUINamewisp=0,unituiname,`wisp`,WESTRING_UNITUINAMEWISP\nUnitUINameancientoflore=0,unituiname,`ancientoflore`,WESTRING_UNITUINAMEANCIENTOFLORE\nUnitUINameancientofwar=0,unituiname,`ancientofwar`,WESTRING_UNITUINAMEANCIENTOFWAR\nUnitUINameancientofwind=0,unituiname,`ancientofwind`,WESTRING_UNITUINAMEANCIENTOFWIND\nUnitUINamealtarofelders=0,unituiname,`altarofelders`,WESTRING_UNITUINAMEALTAROFELDERS\nUnitUINameancientofwonders=0,unituiname,`ancientofwonders`,WESTRING_UNITUINAMEANCIENTOFWONDERS\nUnitUINamehuntershall=0,unituiname,`huntershall`,WESTRING_UNITUINAMEHUNTERSHALL\nUnitUINamechimaeraroost=0,unituiname,`chimaeraroost`,WESTRING_UNITUINAMECHIMAERAROOST\nUnitUINameentangledgoldmine=0,unituiname,`entangledgoldmine`,WESTRING_UNITUINAMEENTANGLEDGOLDMINE\nUnitUINamemoonwell=0,unituiname,`moonwell`,WESTRING_UNITUINAMEMOONWELL\nUnitUINamenightelfshipyard=0,unituiname,`nightelfshipyard`,WESTRING_UNITUINAMENIGHTELFSHIPYARD\nUnitUINametreeofages=0,unituiname,`treeofages`,WESTRING_UNITUINAMETREEOFAGES\nUnitUINametreeofeternity=0,unituiname,`treeofeternity`,WESTRING_UNITUINAMETREEOFETERNITY\nUnitUINametreeoflife=0,unituiname,`treeoflife`,WESTRING_UNITUINAMETREEOFLIFE\nUnitUINameancientprotector=0,unituiname,`ancientprotector`,WESTRING_UNITUINAMEANCIENTPROTECTOR\nUnitUINamecryptlord=0,unituiname,`cryptlord`,WESTRING_UNITUINAMECRYPTLORD\nUnitUINamedeathknight=0,unituiname,`deathknight`,WESTRING_UNITUINAMEDEATHKNIGHT\nUnitUINamedreadlord=0,unituiname,`dreadlord`,WESTRING_UNITUINAMEDREADLORD\nUnitUINamelich=0,unituiname,`lich`,WESTRING_UNITUINAMELICH\nUnitUINameabomination=0,unituiname,`abomination`,WESTRING_UNITUINAMEABOMINATION\nUnitUINameacolyte=0,unituiname,`acolyte`,WESTRING_UNITUINAMEACOLYTE\nUnitUINamebanshee=0,unituiname,`banshee`,WESTRING_UNITUINAMEBANSHEE\nUnitUINameobsidiandestroyer=0,unituiname,`obsidiandestroyer`,WESTRING_UNITUINAMEOBSIDIANDESTROYER\nUnitUINamecryptfiendmorph=0,unituiname,`cryptfiendmorph`,WESTRING_UNITUINAMECRYPTFIENDMORPH\nUnitUINamecryptfiend=0,unituiname,`cryptfiend`,WESTRING_UNITUINAMECRYPTFIEND\nUnitUINamecarrionscarab1=0,unituiname,`carrionscarab1`,WESTRING_UNITUINAMECARRIONSCARAB1\nUnitUINamecarrionscarab2=0,unituiname,`carrionscarab2`,WESTRING_UNITUINAMECARRIONSCARAB2\nUnitUINamecarrionscarab3=0,unituiname,`carrionscarab3`,WESTRING_UNITUINAMECARRIONSCARAB3\nUnitUINamecarrionscarabburrowed2=0,unituiname,`carrionscarabburrowed2`,WESTRING_UNITUINAMECARRIONSCARABBURROWED2\nUnitUINamecarrionscarabburrowed3=0,unituiname,`carrionscarabburrowed3`,WESTRING_UNITUINAMECARRIONSCARABBURROWED3\nUnitUINamefrostwyrm=0,unituiname,`frostwyrm`,WESTRING_UNITUINAMEFROSTWYRM\nUnitUINamegargoyle=0,unituiname,`gargoyle`,WESTRING_UNITUINAMEGARGOYLE\nUnitUINameghoul=0,unituiname,`ghoul`,WESTRING_UNITUINAMEGHOUL\nUnitUINamegargoylemorphed=0,unituiname,`gargoylemorphed`,WESTRING_UNITUINAMEGARGOYLEMORPHED\nUnitUINamelocust=0,unituiname,`locust`,WESTRING_UNITUINAMELOCUST\nUnitUINamemeatwagon=0,unituiname,`meatwagon`,WESTRING_UNITUINAMEMEATWAGON\nUnitUINamenecromancer=0,unituiname,`necromancer`,WESTRING_UNITUINAMENECROMANCER\nUnitUINameobsidianstatue=0,unituiname,`obsidianstatue`,WESTRING_UNITUINAMEOBSIDIANSTATUE\nUnitUINameplagueward=0,unituiname,`plagueward`,WESTRING_UNITUINAMEPLAGUEWARD\nUnitUINameshade=0,unituiname,`shade`,WESTRING_UNITUINAMESHADE\nUnitUINameskeletonwarrior=0,unituiname,`skeletonwarrior`,WESTRING_UNITUINAMESKELETONWARRIOR\nUnitUINameskeletalmage=0,unituiname,`skeletalmage`,WESTRING_UNITUINAMESKELETALMAGE\nUnitUINameundeadbattleship=0,unituiname,`undeadbattleship`,WESTRING_UNITUINAMEUNDEADBATTLESHIP\nUnitUINamealtarofdarkness=0,unituiname,`altarofdarkness`,WESTRING_UNITUINAMEALTAROFDARKNESS\nUnitUINameboneyard=0,unituiname,`boneyard`,WESTRING_UNITUINAMEBONEYARD\nUnitUINameundeadgoldmine2=0,unituiname,`undeadgoldmine2`,WESTRING_UNITUINAMEUNDEADGOLDMINE2\nUnitUINamegraveyard=0,unituiname,`graveyard`,WESTRING_UNITUINAMEGRAVEYARD\nUnitUINamenecropolis1=0,unituiname,`necropolis1`,WESTRING_UNITUINAMENECROPOLIS1\nUnitUINamenecropolis2=0,unituiname,`necropolis2`,WESTRING_UNITUINAMENECROPOLIS2\nUnitUINamenecropolis=0,unituiname,`necropolis`,WESTRING_UNITUINAMENECROPOLIS\nUnitUINamesacrificialpit=0,unituiname,`sacrificialpit`,WESTRING_UNITUINAMESACRIFICIALPIT\nUnitUINamecrypt=0,unituiname,`crypt`,WESTRING_UNITUINAMECRYPT\nUnitUINameundeadshipyard=0,unituiname,`undeadshipyard`,WESTRING_UNITUINAMEUNDEADSHIPYARD\nUnitUINameslaughterhouse=0,unituiname,`slaughterhouse`,WESTRING_UNITUINAMESLAUGHTERHOUSE\nUnitUINametempleofthedamned=0,unituiname,`templeofthedamned`,WESTRING_UNITUINAMETEMPLEOFTHEDAMNED\nUnitUINametombofrelics=0,unituiname,`tombofrelics`,WESTRING_UNITUINAMETOMBOFRELICS\nUnitUINameziggurat1=0,unituiname,`ziggurat1`,WESTRING_UNITUINAMEZIGGURAT1\nUnitUINamefrosttower=0,unituiname,`frosttower`,WESTRING_UNITUINAMEFROSTTOWER\nUnitUINameziggurat=0,unituiname,`ziggurat`,WESTRING_UNITUINAMEZIGGURAT\nUnitUINamedarkranger=0,unituiname,`darkranger`,WESTRING_UNITUINAMEDARKRANGER\nUnitUINamebeastmaster=0,unituiname,`beastmaster`,WESTRING_UNITUINAMEBEASTMASTER\nUnitUINameseawitch=0,unituiname,`seawitch`,WESTRING_UNITUINAMESEAWITCH\nUnitUINamepandarenbrewmaster=0,unituiname,`pandarenbrewmaster`,WESTRING_UNITUINAMEPANDARENBREWMASTER\nUnitUINamepitlord=0,unituiname,`pitlord`,WESTRING_UNITUINAMEPITLORD\nUnitUINamedarkminion1=0,unituiname,`darkminion1`,WESTRING_UNITUINAMEDARKMINION1\nUnitUINamedarkminion2=0,unituiname,`darkminion2`,WESTRING_UNITUINAMEDARKMINION2\nUnitUINamedarkminion3=0,unituiname,`darkminion3`,WESTRING_UNITUINAMEDARKMINION3\nUnitUINamegrizzlybear1=0,unituiname,`grizzlybear1`,WESTRING_UNITUINAMEGRIZZLYBEAR1\nUnitUINamegrizzlybear2=0,unituiname,`grizzlybear2`,WESTRING_UNITUINAMEGRIZZLYBEAR2\nUnitUINamegrizzlybear3=0,unituiname,`grizzlybear3`,WESTRING_UNITUINAMEGRIZZLYBEAR3\nUnitUINamemisha1=0,unituiname,`misha1`,WESTRING_UNITUINAMEMISHA1\nUnitUINamemisha2=0,unituiname,`misha2`,WESTRING_UNITUINAMEMISHA2\nUnitUINamemisha3=0,unituiname,`misha3`,WESTRING_UNITUINAMEMISHA3\nUnitUINamemisha4=0,unituiname,`misha4`,WESTRING_UNITUINAMEMISHA4\nUnitUINamepanda1=0,unituiname,`panda1`,WESTRING_UNITUINAMEPANDA1\nUnitUINamepanda2=0,unituiname,`panda2`,WESTRING_UNITUINAMEPANDA2\nUnitUINamepanda3=0,unituiname,`panda3`,WESTRING_UNITUINAMEPANDA3\nUnitUINamepanda4=0,unituiname,`panda4`,WESTRING_UNITUINAMEPANDA4\nUnitUINamepanda5=0,unituiname,`panda5`,WESTRING_UNITUINAMEPANDA5\nUnitUINamepanda6=0,unituiname,`panda6`,WESTRING_UNITUINAMEPANDA6\nUnitUINamequillbeast1=0,unituiname,`quillbeast1`,WESTRING_UNITUINAMEQUILLBEAST1\nUnitUINamequillbeast2=0,unituiname,`quillbeast2`,WESTRING_UNITUINAMEQUILLBEAST2\nUnitUINamequillbeast3=0,unituiname,`quillbeast3`,WESTRING_UNITUINAMEQUILLBEAST3\nUnitUINamequillbeast4=0,unituiname,`quillbeast4`,WESTRING_UNITUINAMEQUILLBEAST4\nUnitUINamewareagle1=0,unituiname,`wareagle1`,WESTRING_UNITUINAMEWAREAGLE1\nUnitUINamewareagle2=0,unituiname,`wareagle2`,WESTRING_UNITUINAMEWAREAGLE2\nUnitUINamewareagle3=0,unituiname,`wareagle3`,WESTRING_UNITUINAMEWAREAGLE3\nUnitUINameazuredrake=0,unituiname,`azuredrake`,WESTRING_UNITUINAMEAZUREDRAKE\nUnitUINameazuredragon=0,unituiname,`azuredragon`,WESTRING_UNITUINAMEAZUREDRAGON\nUnitUINameazuredragonwhelp=0,unituiname,`azuredragonwhelp`,WESTRING_UNITUINAMEAZUREDRAGONWHELP\nUnitUINameancienthydra=0,unituiname,`ancienthydra`,WESTRING_UNITUINAMEANCIENTHYDRA\nUnitUINamebarbedarachnathid=0,unituiname,`barbedarachnathid`,WESTRING_UNITUINAMEBARBEDARACHNATHID\nUnitUINamebarbedarachnathidmerc=0,unituiname,`barbedarachnathidmerc`,WESTRING_UNITUINAMEBARBEDARACHNATHIDMERC\nUnitUINamecrystalarachnathid=0,unituiname,`crystalarachnathid`,WESTRING_UNITUINAMECRYSTALARACHNATHID\nUnitUINameearthborerarachnathid=0,unituiname,`earthborerarachnathid`,WESTRING_UNITUINAMEEARTHBORERARACHNATHID\nUnitUINameoverlordarachnathid=0,unituiname,`overlordarachnathid`,WESTRING_UNITUINAMEOVERLORDARACHNATHID\nUnitUINamewarriorarachnathid=0,unituiname,`warriorarachnathid`,WESTRING_UNITUINAMEWARRIORARACHNATHID\nUnitUINamebattlegolem=0,unituiname,`battlegolem`,WESTRING_UNITUINAMEBATTLEGOLEM\nUnitUINameassassin=0,unituiname,`assassin`,WESTRING_UNITUINAMEASSASSIN\nUnitUINamedoomguard=0,unituiname,`doomguard`,WESTRING_UNITUINAMEDOOMGUARD\nUnitUINamedoomguardsummoned=0,unituiname,`doomguardsummoned`,WESTRING_UNITUINAMEDOOMGUARDSUMMONED\nUnitUINamebandit=0,unituiname,`bandit`,WESTRING_UNITUINAMEBANDIT\nUnitUINamebluedragonspawnapprentice=0,unituiname,`bluedragonspawnapprentice`,WESTRING_UNITUINAMEBLUEDRAGONSPAWNAPPRENTICE\nUnitUINameblackdrake=0,unituiname,`blackdrake`,WESTRING_UNITUINAMEBLACKDRAKE\nUnitUINamebluedragonspawnmeddler=0,unituiname,`bluedragonspawnmeddler`,WESTRING_UNITUINAMEBLUEDRAGONSPAWNMEDDLER\nUnitUINamebluedragonspawnoverseer=0,unituiname,`bluedragonspawnoverseer`,WESTRING_UNITUINAMEBLUEDRAGONSPAWNOVERSEER\nUnitUINameblackdragonwhelp=0,unituiname,`blackdragonwhelp`,WESTRING_UNITUINAMEBLACKDRAGONWHELP\nUnitUINamebluedragonspawnsorceror=0,unituiname,`bluedragonspawnsorceror`,WESTRING_UNITUINAMEBLUEDRAGONSPAWNSORCEROR\nUnitUINamebluedragonspawnwarrior=0,unituiname,`bluedragonspawnwarrior`,WESTRING_UNITUINAMEBLUEDRAGONSPAWNWARRIOR\nUnitUINamebanditlord=0,unituiname,`banditlord`,WESTRING_UNITUINAMEBANDITLORD\nUnitUINamebarbedarachnathidburrowed=0,unituiname,`barbedarachnathidburrowed`,WESTRING_UNITUINAMEBARBEDARACHNATHIDBURROWED\nUnitUINametransportship=0,unituiname,`transportship`,WESTRING_UNITUINAMETRANSPORTSHIP\nUnitUINamebrigand=0,unituiname,`brigand`,WESTRING_UNITUINAMEBRIGAND\nUnitUINameblackdragon=0,unituiname,`blackdragon`,WESTRING_UNITUINAMEBLACKDRAGON\nUnitUINamebronzedragon=0,unituiname,`bronzedragon`,WESTRING_UNITUINAMEBRONZEDRAGON\nUnitUINamebronzedrake=0,unituiname,`bronzedrake`,WESTRING_UNITUINAMEBRONZEDRAKE\nUnitUINamebronzedragonwhelp=0,unituiname,`bronzedragonwhelp`,WESTRING_UNITUINAMEBRONZEDRAGONWHELP\nUnitUINamecentaurarcher=0,unituiname,`centaurarcher`,WESTRING_UNITUINAMECENTAURARCHER\nUnitUINamecentauroutrunner=0,unituiname,`centauroutrunner`,WESTRING_UNITUINAMECENTAUROUTRUNNER\nUnitUINamecentaurdrudge=0,unituiname,`centaurdrudge`,WESTRING_UNITUINAMECENTAURDRUDGE\nUnitUINamewateryminioncliffrunner=0,unituiname,`wateryminioncliffrunner`,WESTRING_UNITUINAMEWATERYMINIONCLIFFRUNNER\nUnitUINamecentaurimpaler=0,unituiname,`centaurimpaler`,WESTRING_UNITUINAMECENTAURIMPALER\nUnitUINamecentaursorceror=0,unituiname,`centaursorceror`,WESTRING_UNITUINAMECENTAURSORCEROR\nUnitUINamecentaurkhan=0,unituiname,`centaurkhan`,WESTRING_UNITUINAMECENTAURKHAN\nUnitUINamesuccubus=0,unituiname,`succubus`,WESTRING_UNITUINAMESUCCUBUS\nUnitUINamemaidenofpain=0,unituiname,`maidenofpain`,WESTRING_UNITUINAMEMAIDENOFPAIN\nUnitUINamequeenofsuffering=0,unituiname,`queenofsuffering`,WESTRING_UNITUINAMEQUEENOFSUFFERING\nUnitUINameviletemptress=0,unituiname,`viletemptress`,WESTRING_UNITUINAMEVILETEMPTRESS\nUnitUINameviletormentor=0,unituiname,`viletormentor`,WESTRING_UNITUINAMEVILETORMENTOR\nUnitUINamerevenantofthedepths=0,unituiname,`revenantofthedepths`,WESTRING_UNITUINAMEREVENANTOFTHEDEPTHS\nUnitUINamedarktrollberserker=0,unituiname,`darktrollberserker`,WESTRING_UNITUINAMEDARKTROLLBERSERKER\nUnitUINamedarktrollhighpriest=0,unituiname,`darktrollhighpriest`,WESTRING_UNITUINAMEDARKTROLLHIGHPRIEST\nUnitUINamedarktrollshadowpriest=0,unituiname,`darktrollshadowpriest`,WESTRING_UNITUINAMEDARKTROLLSHADOWPRIEST\nUnitUINamedarktroll=0,unituiname,`darktroll`,WESTRING_UNITUINAMEDARKTROLL\nUnitUINamedarktrolltrapper=0,unituiname,`darktrolltrapper`,WESTRING_UNITUINAMEDARKTROLLTRAPPER\nUnitUINamedarktrollwarlord=0,unituiname,`darktrollwarlord`,WESTRING_UNITUINAMEDARKTROLLWARLORD\nUnitUINameelderhydra=0,unituiname,`elderhydra`,WESTRING_UNITUINAMEELDERHYDRA\nUnitUINamebereserkelemental=0,unituiname,`bereserkelemental`,WESTRING_UNITUINAMEBERESERKELEMENTAL\nUnitUINameenragedelemental=0,unituiname,`enragedelemental`,WESTRING_UNITUINAMEENRAGEDELEMENTAL\nUnitUINamecorruptedent=0,unituiname,`corruptedent`,WESTRING_UNITUINAMECORRUPTEDENT\nUnitUINameenforcer=0,unituiname,`enforcer`,WESTRING_UNITUINAMEENFORCER\nUnitUINamepoisonent=0,unituiname,`poisonent`,WESTRING_UNITUINAMEPOISONENT\nUnitUINameplagueent=0,unituiname,`plagueent`,WESTRING_UNITUINAMEPLAGUEENT\nUnitUINameeredardiabolist=0,unituiname,`eredardiabolist`,WESTRING_UNITUINAMEEREDARDIABOLIST\nUnitUINameeredarsorceror=0,unituiname,`eredarsorceror`,WESTRING_UNITUINAMEEREDARSORCEROR\nUnitUINameeredarwarlock=0,unituiname,`eredarwarlock`,WESTRING_UNITUINAMEEREDARWARLOCK\nUnitUINamefelstalker=0,unituiname,`felstalker`,WESTRING_UNITUINAMEFELSTALKER\nUnitUINamebloodfiend=0,unituiname,`bloodfiend`,WESTRING_UNITUINAMEBLOODFIEND\nUnitUINameforgottenone=0,unituiname,`forgottenone`,WESTRING_UNITUINAMEFORGOTTENONE\nUnitUINametentacle=0,unituiname,`tentacle`,WESTRING_UNITUINAMETENTACLE\nUnitUINamefelguard=0,unituiname,`felguard`,WESTRING_UNITUINAMEFELGUARD\nUnitUINamefacelessonedeathbringer=0,unituiname,`facelessonedeathbringer`,WESTRING_UNITUINAMEFACELESSONEDEATHBRINGER\nUnitUINamefacelessonetrickster=0,unituiname,`facelessonetrickster`,WESTRING_UNITUINAMEFACELESSONETRICKSTER\nUnitUINamefacelessoneterror=0,unituiname,`facelessoneterror`,WESTRING_UNITUINAMEFACELESSONETERROR\nUnitUINameoverlord=0,unituiname,`overlord`,WESTRING_UNITUINAMEOVERLORD\nUnitUINamepolarfurbolgchampion=0,unituiname,`polarfurbolgchampion`,WESTRING_UNITUINAMEPOLARFURBOLGCHAMPION\nUnitUINamepolarfurbolgeldershaman=0,unituiname,`polarfurbolgeldershaman`,WESTRING_UNITUINAMEPOLARFURBOLGELDERSHAMAN\nUnitUINamepolarfurbolg=0,unituiname,`polarfurbolg`,WESTRING_UNITUINAMEPOLARFURBOLG\nUnitUINamepolarfurbolgshaman=0,unituiname,`polarfurbolgshaman`,WESTRING_UNITUINAMEPOLARFURBOLGSHAMAN\nUnitUINamepolarfurbolgtracker=0,unituiname,`polarfurbolgtracker`,WESTRING_UNITUINAMEPOLARFURBOLGTRACKER\nUnitUINamepolarfurbolgursawarrior=0,unituiname,`polarfurbolgursawarrior`,WESTRING_UNITUINAMEPOLARFURBOLGURSAWARRIOR\nUnitUINamefurbolgancient=0,unituiname,`furbolgancient`,WESTRING_UNITUINAMEFURBOLGANCIENT\nUnitUINamefurbolgtracker=0,unituiname,`furbolgtracker`,WESTRING_UNITUINAMEFURBOLGTRACKER\nUnitUINamefurbolgeldershaman=0,unituiname,`furbolgeldershaman`,WESTRING_UNITUINAMEFURBOLGELDERSHAMAN\nUnitUINamefurbolgchampion=0,unituiname,`furbolgchampion`,WESTRING_UNITUINAMEFURBOLGCHAMPION\nUnitUINamefurbolg=0,unituiname,`furbolg`,WESTRING_UNITUINAMEFURBOLG\nUnitUINamefurbolgpanda=0,unituiname,`furbolgpanda`,WESTRING_UNITUINAMEFURBOLGPANDA\nUnitUINamefurbolgshaman=0,unituiname,`furbolgshaman`,WESTRING_UNITUINAMEFURBOLGSHAMAN\nUnitUINameforesttrollhighpriest=0,unituiname,`foresttrollhighpriest`,WESTRING_UNITUINAMEFORESTTROLLHIGHPRIEST\nUnitUINameforesttrollshadowpriest=0,unituiname,`foresttrollshadowpriest`,WESTRING_UNITUINAMEFORESTTROLLSHADOWPRIEST\nUnitUINameforesttrollberserker=0,unituiname,`foresttrollberserker`,WESTRING_UNITUINAMEFORESTTROLLBERSERKER\nUnitUINameforesttrollking=0,unituiname,`foresttrollking`,WESTRING_UNITUINAMEFORESTTROLLKING\nUnitUINameforesttroll=0,unituiname,`foresttroll`,WESTRING_UNITUINAMEFORESTTROLL\nUnitUINameforesttrolltrapper=0,unituiname,`foresttrolltrapper`,WESTRING_UNITUINAMEFORESTTROLLTRAPPER\nUnitUINamegreendrake=0,unituiname,`greendrake`,WESTRING_UNITUINAMEGREENDRAKE\nUnitUINamegranitegolem=0,unituiname,`granitegolem`,WESTRING_UNITUINAMEGRANITEGOLEM\nUnitUINameghost=0,unituiname,`ghost`,WESTRING_UNITUINAMEGHOST\nUnitUINamewraith=0,unituiname,`wraith`,WESTRING_UNITUINAMEWRAITH\nUnitUINamegoblinshredder=0,unituiname,`goblinshredder`,WESTRING_UNITUINAMEGOBLINSHREDDER\nUnitUINamegoblinlandmine=0,unituiname,`goblinlandmine`,WESTRING_UNITUINAMEGOBLINLANDMINE\nUnitUINamegnollpoacher=0,unituiname,`gnollpoacher`,WESTRING_UNITUINAMEGNOLLPOACHER\nUnitUINamegnollbrute=0,unituiname,`gnollbrute`,WESTRING_UNITUINAMEGNOLLBRUTE\nUnitUINamegnoll1=0,unituiname,`gnoll1`,WESTRING_UNITUINAMEGNOLL1\nUnitUINamegnollassassin=0,unituiname,`gnollassassin`,WESTRING_UNITUINAMEGNOLLASSASSIN\nUnitUINamegnollking=0,unituiname,`gnollking`,WESTRING_UNITUINAMEGNOLLKING\nUnitUINamegnoll3=0,unituiname,`gnoll3`,WESTRING_UNITUINAMEGNOLL3\nUnitUINamegreendragon=0,unituiname,`greendragon`,WESTRING_UNITUINAMEGREENDRAGON\nUnitUINamemudgolem=0,unituiname,`mudgolem`,WESTRING_UNITUINAMEMUDGOLEM\nUnitUINamegreendragonwhelp=0,unituiname,`greendragonwhelp`,WESTRING_UNITUINAMEGREENDRAGONWHELP\nUnitUINamegoblinsapper=0,unituiname,`goblinsapper`,WESTRING_UNITUINAMEGOBLINSAPPER\nUnitUINamerockgolem=0,unituiname,`rockgolem`,WESTRING_UNITUINAMEROCKGOLEM\nUnitUINameharpyscout=0,unituiname,`harpyscout`,WESTRING_UNITUINAMEHARPYSCOUT\nUnitUINamedeceiver=0,unituiname,`deceiver`,WESTRING_UNITUINAMEDECEIVER\nUnitUINamefallenpriest=0,unituiname,`fallenpriest`,WESTRING_UNITUINAMEFALLENPRIEST\nUnitUINameheretic=0,unituiname,`heretic`,WESTRING_UNITUINAMEHERETIC\nUnitUINameharpyhag=0,unituiname,`harpyhag`,WESTRING_UNITUINAMEHARPYHAG\nUnitUINameharpyqueen=0,unituiname,`harpyqueen`,WESTRING_UNITUINAMEHARPYQUEEN\nUnitUINameharpyrogue=0,unituiname,`harpyrogue`,WESTRING_UNITUINAMEHARPYROGUE\nUnitUINameharpywitch=0,unituiname,`harpywitch`,WESTRING_UNITUINAMEHARPYWITCH\nUnitUINamecampaignturtle=0,unituiname,`campaignturtle`,WESTRING_UNITUINAMECAMPAIGNTURTLE\nUnitUINamehydra=0,unituiname,`hydra`,WESTRING_UNITUINAMEHYDRA\nUnitUINamehydrahatchling=0,unituiname,`hydrahatchling`,WESTRING_UNITUINAMEHYDRAHATCHLING\nUnitUINameinfernaljuggernaut=0,unituiname,`infernaljuggernaut`,WESTRING_UNITUINAMEINFERNALJUGGERNAUT\nUnitUINameinfernalcontraption=0,unituiname,`infernalcontraption`,WESTRING_UNITUINAMEINFERNALCONTRAPTION\nUnitUINameinfernal=0,unituiname,`infernal`,WESTRING_UNITUINAMEINFERNAL\nUnitUINameinfernalmachine=0,unituiname,`infernalmachine`,WESTRING_UNITUINAMEINFERNALMACHINE\nUnitUINameicetrollhighpriest=0,unituiname,`icetrollhighpriest`,WESTRING_UNITUINAMEICETROLLHIGHPRIEST\nUnitUINameicetrollshadowpriest=0,unituiname,`icetrollshadowpriest`,WESTRING_UNITUINAMEICETROLLSHADOWPRIEST\nUnitUINameicetroll=0,unituiname,`icetroll`,WESTRING_UNITUINAMEICETROLL\nUnitUINameicetrollberserker=0,unituiname,`icetrollberserker`,WESTRING_UNITUINAMEICETROLLBERSERKER\nUnitUINameicetrolltrapper=0,unituiname,`icetrolltrapper`,WESTRING_UNITUINAMEICETROLLTRAPPER\nUnitUINameicetrollwarlord=0,unituiname,`icetrollwarlord`,WESTRING_UNITUINAMEICETROLLWARLORD\nUnitUINameenrangedjunglestalker=0,unituiname,`enrangedjunglestalker`,WESTRING_UNITUINAMEENRANGEDJUNGLESTALKER\nUnitUINameelderjunglestalker=0,unituiname,`elderjunglestalker`,WESTRING_UNITUINAMEELDERJUNGLESTALKER\nUnitUINamejunglestalker=0,unituiname,`junglestalker`,WESTRING_UNITUINAMEJUNGLESTALKER\nUnitUINamekobold=0,unituiname,`kobold`,WESTRING_UNITUINAMEKOBOLD\nUnitUINamekoboldgeomancer=0,unituiname,`koboldgeomancer`,WESTRING_UNITUINAMEKOBOLDGEOMANCER\nUnitUINamekoboldtaskmaster=0,unituiname,`koboldtaskmaster`,WESTRING_UNITUINAMEKOBOLDTASKMASTER\nUnitUINamekobolttunneler=0,unituiname,`kobolttunneler`,WESTRING_UNITUINAMEKOBOLTTUNNELER\nUnitUINamelobstrokkdeepseer=0,unituiname,`lobstrokkdeepseer`,WESTRING_UNITUINAMELOBSTROKKDEEPSEER\nUnitUINamelobstrokktidallord=0,unituiname,`lobstrokktidallord`,WESTRING_UNITUINAMELOBSTROKKTIDALLORD\nUnitUINamelobstrokkpooldweller=0,unituiname,`lobstrokkpooldweller`,WESTRING_UNITUINAMELOBSTROKKPOOLDWELLER\nUnitUINamelobstrokkprawn=0,unituiname,`lobstrokkprawn`,WESTRING_UNITUINAMELOBSTROKKPRAWN\nUnitUINamelobstrokkprawnsummoned=0,unituiname,`lobstrokkprawnsummoned`,WESTRING_UNITUINAMELOBSTROKKPRAWNSUMMONED\nUnitUINamedeeplordrevenant=0,unituiname,`deeplordrevenant`,WESTRING_UNITUINAMEDEEPLORDREVENANT\nUnitUINamelobstrokksnapper=0,unituiname,`lobstrokksnapper`,WESTRING_UNITUINAMELOBSTROKKSNAPPER\nUnitUINamelobstrokktidecaller=0,unituiname,`lobstrokktidecaller`,WESTRING_UNITUINAMELOBSTROKKTIDECALLER\nUnitUINamelightninglizard=0,unituiname,`lightninglizard`,WESTRING_UNITUINAMELIGHTNINGLIZARD\nUnitUINamemonsterlure=0,unituiname,`monsterlure`,WESTRING_UNITUINAMEMONSTERLURE\nUnitUINamemammoth=0,unituiname,`mammoth`,WESTRING_UNITUINAMEMAMMOTH\nUnitUINamemurgulbloodgill=0,unituiname,`murgulbloodgill`,WESTRING_UNITUINAMEMURGULBLOODGILL\nUnitUINamemurgulcliffrunner=0,unituiname,`murgulcliffrunner`,WESTRING_UNITUINAMEMURGULCLIFFRUNNER\nUnitUINamediremammoth=0,unituiname,`diremammoth`,WESTRING_UNITUINAMEDIREMAMMOTH\nUnitUINamemurlocflesheater=0,unituiname,`murlocflesheater`,WESTRING_UNITUINAMEMURLOCFLESHEATER\nUnitUINamemagnataurdestroyer=0,unituiname,`magnataurdestroyer`,WESTRING_UNITUINAMEMAGNATAURDESTROYER\nUnitUINamemagnataurreaver=0,unituiname,`magnataurreaver`,WESTRING_UNITUINAMEMAGNATAURREAVER\nUnitUINamemagnataurwarrior=0,unituiname,`magnataurwarrior`,WESTRING_UNITUINAMEMAGNATAURWARRIOR\nUnitUINameicetuskmammoth=0,unituiname,`icetuskmammoth`,WESTRING_UNITUINAMEICETUSKMAMMOTH\nUnitUINamemurlocmutant=0,unituiname,`murlocmutant`,WESTRING_UNITUINAMEMURLOCMUTANT\nUnitUINamemurlocplaguebearer=0,unituiname,`murlocplaguebearer`,WESTRING_UNITUINAMEMURLOCPLAGUEBEARER\nUnitUINamemurloctiderunner=0,unituiname,`murloctiderunner`,WESTRING_UNITUINAMEMURLOCTIDERUNNER\nUnitUINamemurlocnightcrawler=0,unituiname,`murlocnightcrawler`,WESTRING_UNITUINAMEMURLOCNIGHTCRAWLER\nUnitUINamemurlochuntsman=0,unituiname,`murlochuntsman`,WESTRING_UNITUINAMEMURLOCHUNTSMAN\nUnitUINamemurgulreaver=0,unituiname,`murgulreaver`,WESTRING_UNITUINAMEMURGULREAVER\nUnitUINamemurgulshadowcaster=0,unituiname,`murgulshadowcaster`,WESTRING_UNITUINAMEMURGULSHADOWCASTER\nUnitUINamemurgulsnarecaster=0,unituiname,`murgulsnarecaster`,WESTRING_UNITUINAMEMURGULSNARECASTER\nUnitUINamemurgultidewarrior=0,unituiname,`murgultidewarrior`,WESTRING_UNITUINAMEMURGULTIDEWARRIOR\nUnitUINamenagamyrmidon=0,unituiname,`nagamyrmidon`,WESTRING_UNITUINAMENAGAMYRMIDON\nUnitUINamenagamyrmidonmorph=0,unituiname,`nagamyrmidonmorph`,WESTRING_UNITUINAMENAGAMYRMIDONMORPH\nUnitUINamenetherdrake=0,unituiname,`netherdrake`,WESTRING_UNITUINAMENETHERDRAKE\nUnitUINamenetherdragon=0,unituiname,`netherdragon`,WESTRING_UNITUINAMENETHERDRAGON\nUnitUINamenetherdragonhatchling=0,unituiname,`netherdragonhatchling`,WESTRING_UNITUINAMENETHERDRAGONHATCHLING\nUnitUINamenagamurgul=0,unituiname,`nagamurgul`,WESTRING_UNITUINAMENAGAMURGUL\nUnitUINamenagaroyalguard=0,unituiname,`nagaroyalguard`,WESTRING_UNITUINAMENAGAROYALGUARD\nUnitUINamenagaroyalguardmorph=0,unituiname,`nagaroyalguardmorph`,WESTRING_UNITUINAMENAGAROYALGUARDMORPH\nUnitUINamesummoner=0,unituiname,`summoner`,WESTRING_UNITUINAMESUMMONER\nUnitUINamesiren=0,unituiname,`siren`,WESTRING_UNITUINAMESIREN\nUnitUINamenerubianwarrior=0,unituiname,`nerubianwarrior`,WESTRING_UNITUINAMENERUBIANWARRIOR\nUnitUINamenerubianwebspinner=0,unituiname,`nerubianwebspinner`,WESTRING_UNITUINAMENERUBIANWEBSPINNER\nUnitUINamenerubianqueen=0,unituiname,`nerubianqueen`,WESTRING_UNITUINAMENERUBIANQUEEN\nUnitUINamenerubianseer=0,unituiname,`nerubianseer`,WESTRING_UNITUINAMENERUBIANSEER\nUnitUINamenerubianspiderlord=0,unituiname,`nerubianspiderlord`,WESTRING_UNITUINAMENERUBIANSPIDERLORD\nUnitUINamestonemaulwarchief=0,unituiname,`stonemaulwarchief`,WESTRING_UNITUINAMESTONEMAULWARCHIEF\nUnitUINameogrelord=0,unituiname,`ogrelord`,WESTRING_UNITUINAMEOGRELORD\nUnitUINameogre2=0,unituiname,`ogre2`,WESTRING_UNITUINAMEOGRE2\nUnitUINamestonemaulmagi=0,unituiname,`stonemaulmagi`,WESTRING_UNITUINAMESTONEMAULMAGI\nUnitUINamestonemaulogre=0,unituiname,`stonemaulogre`,WESTRING_UNITUINAMESTONEMAULOGRE\nUnitUINameogre1=0,unituiname,`ogre1`,WESTRING_UNITUINAMEOGRE1\nUnitUINameogremagi=0,unituiname,`ogremagi`,WESTRING_UNITUINAMEOGREMAGI\nUnitUINameowlbear=0,unituiname,`owlbear`,WESTRING_UNITUINAMEOWLBEAR\nUnitUINameenragedowlbear=0,unituiname,`enragedowlbear`,WESTRING_UNITUINAMEENRAGEDOWLBEAR\nUnitUINameberserkowlbear=0,unituiname,`berserkowlbear`,WESTRING_UNITUINAMEBERSERKOWLBEAR\nUnitUINamepurplefelstalker=0,unituiname,`purplefelstalker`,WESTRING_UNITUINAMEPURPLEFELSTALKER\nUnitUINamefelravager=0,unituiname,`felravager`,WESTRING_UNITUINAMEFELRAVAGER\nUnitUINamepolarbear=0,unituiname,`polarbear`,WESTRING_UNITUINAMEPOLARBEAR\nUnitUINamegiantpolarbear=0,unituiname,`giantpolarbear`,WESTRING_UNITUINAMEGIANTPOLARBEAR\nUnitUINamequillboarhunter=0,unituiname,`quillboarhunter`,WESTRING_UNITUINAMEQUILLBOARHUNTER\nUnitUINamereddragonwhelp=0,unituiname,`reddragonwhelp`,WESTRING_UNITUINAMEREDDRAGONWHELP\nUnitUINamereddrake=0,unituiname,`reddrake`,WESTRING_UNITUINAMEREDDRAKE\nUnitUINamereefelemental=0,unituiname,`reefelemental`,WESTRING_UNITUINAMEREEFELEMENTAL\nUnitUINamerogue=0,unituiname,`rogue`,WESTRING_UNITUINAMEROGUE\nUnitUINamedeathrevenant=0,unituiname,`deathrevenant`,WESTRING_UNITUINAMEDEATHREVENANT\nUnitUINamefirerevenant=0,unituiname,`firerevenant`,WESTRING_UNITUINAMEFIREREVENANT\nUnitUINameicerevenant=0,unituiname,`icerevenant`,WESTRING_UNITUINAMEICEREVENANT\nUnitUINamelightningrevenant=0,unituiname,`lightningrevenant`,WESTRING_UNITUINAMELIGHTNINGREVENANT\nUnitUINamefrostrevenant=0,unituiname,`frostrevenant`,WESTRING_UNITUINAMEFROSTREVENANT\nUnitUINamereddragon=0,unituiname,`reddragon`,WESTRING_UNITUINAMEREDDRAGON\nUnitUINamerazormanebrute=0,unituiname,`razormanebrute`,WESTRING_UNITUINAMERAZORMANEBRUTE\nUnitUINamerazormanechieftain=0,unituiname,`razormanechieftain`,WESTRING_UNITUINAMERAZORMANECHIEFTAIN\nUnitUINamerazormanemedicineman=0,unituiname,`razormanemedicineman`,WESTRING_UNITUINAMERAZORMANEMEDICINEMAN\nUnitUINamerazormanescout=0,unituiname,`razormanescout`,WESTRING_UNITUINAMERAZORMANESCOUT\nUnitUINamequillboar=0,unituiname,`quillboar`,WESTRING_UNITUINAMEQUILLBOAR\nUnitUINamesatyrtrickster=0,unituiname,`satyrtrickster`,WESTRING_UNITUINAMESATYRTRICKSTER\nUnitUINamebroodmother=0,unituiname,`broodmother`,WESTRING_UNITUINAMEBROODMOTHER\nUnitUINamesnapdragonmorph=0,unituiname,`snapdragonmorph`,WESTRING_UNITUINAMESNAPDRAGONMORPH\nUnitUINamespidercrab2=0,unituiname,`spidercrab2`,WESTRING_UNITUINAMESPIDERCRAB2\nUnitUINamespidercrab3=0,unituiname,`spidercrab3`,WESTRING_UNITUINAMESPIDERCRAB3\nUnitUINamespidercrab=0,unituiname,`spidercrab`,WESTRING_UNITUINAMESPIDERCRAB\nUnitUINameseaelemental=0,unituiname,`seaelemental`,WESTRING_UNITUINAMESEAELEMENTAL\nUnitUINameseagiantbehemoth=0,unituiname,`seagiantbehemoth`,WESTRING_UNITUINAMESEAGIANTBEHEMOTH\nUnitUINamesiegegolem=0,unituiname,`siegegolem`,WESTRING_UNITUINAMESIEGEGOLEM\nUnitUINameseagianthunter=0,unituiname,`seagianthunter`,WESTRING_UNITUINAMESEAGIANTHUNTER\nUnitUINameseagiant=0,unituiname,`seagiant`,WESTRING_UNITUINAMESEAGIANT\nUnitUINamegiantspider=0,unituiname,`giantspider`,WESTRING_UNITUINAMEGIANTSPIDER\nUnitUINameskeletalarcher=0,unituiname,`skeletalarcher`,WESTRING_UNITUINAMESKELETALARCHER\nUnitUINameskeleton=0,unituiname,`skeleton`,WESTRING_UNITUINAMESKELETON\nUnitUINameburningarcher=0,unituiname,`burningarcher`,WESTRING_UNITUINAMEBURNINGARCHER\nUnitUINamegiantskeleton=0,unituiname,`giantskeleton`,WESTRING_UNITUINAMEGIANTSKELETON\nUnitUINameskeletalmarksman=0,unituiname,`skeletalmarksman`,WESTRING_UNITUINAMESKELETALMARKSMAN\nUnitUINameskeletalorc=0,unituiname,`skeletalorc`,WESTRING_UNITUINAMESKELETALORC\nUnitUINamesludgeflinger=0,unituiname,`sludgeflinger`,WESTRING_UNITUINAMESLUDGEFLINGER\nUnitUINamesalamanderhatchling=0,unituiname,`salamanderhatchling`,WESTRING_UNITUINAMESALAMANDERHATCHLING\nUnitUINamesalamanderlord=0,unituiname,`salamanderlord`,WESTRING_UNITUINAMESALAMANDERLORD\nUnitUINamesludgeminion=0,unituiname,`sludgeminion`,WESTRING_UNITUINAMESLUDGEMINION\nUnitUINamesludgemonstrosity=0,unituiname,`sludgemonstrosity`,WESTRING_UNITUINAMESLUDGEMONSTROSITY\nUnitUINamesalamander=0,unituiname,`salamander`,WESTRING_UNITUINAMESALAMANDER\nUnitUINamesalamandervizier=0,unituiname,`salamandervizier`,WESTRING_UNITUINAMESALAMANDERVIZIER\nUnitUINamesnapdragon=0,unituiname,`snapdragon`,WESTRING_UNITUINAMESNAPDRAGON\nUnitUINamewateryminionsnarecaster=0,unituiname,`wateryminionsnarecaster`,WESTRING_UNITUINAMEWATERYMINIONSNARECASTER\nUnitUINameskeletalorcchampion=0,unituiname,`skeletalorcchampion`,WESTRING_UNITUINAMESKELETALORCCHAMPION\nUnitUINameskeletalorcgrunt=0,unituiname,`skeletalorcgrunt`,WESTRING_UNITUINAMESKELETALORCGRUNT\nUnitUINamespiderblack=0,unituiname,`spiderblack`,WESTRING_UNITUINAMESPIDERBLACK\nUnitUINamespiderling=0,unituiname,`spiderling`,WESTRING_UNITUINAMESPIDERLING\nUnitUINameforestspider=0,unituiname,`forestspider`,WESTRING_UNITUINAMEFORESTSPIDER\nUnitUINamespiritpig=0,unituiname,`spiritpig`,WESTRING_UNITUINAMESPIRITPIG\nUnitUINamespider=0,unituiname,`spider`,WESTRING_UNITUINAMESPIDER\nUnitUINameancientsasquatch=0,unituiname,`ancientsasquatch`,WESTRING_UNITUINAMEANCIENTSASQUATCH\nUnitUINameeldersasquatch=0,unituiname,`eldersasquatch`,WESTRING_UNITUINAMEELDERSASQUATCH\nUnitUINamesasquatchoracle=0,unituiname,`sasquatchoracle`,WESTRING_UNITUINAMESASQUATCHORACLE\nUnitUINamesasquatch=0,unituiname,`sasquatch`,WESTRING_UNITUINAMESASQUATCH\nUnitUINamestormreaverapprentice=0,unituiname,`stormreaverapprentice`,WESTRING_UNITUINAMESTORMREAVERAPPRENTICE\nUnitUINamestormreaverhermit=0,unituiname,`stormreaverhermit`,WESTRING_UNITUINAMESTORMREAVERHERMIT\nUnitUINamestormreavernecrolyte=0,unituiname,`stormreavernecrolyte`,WESTRING_UNITUINAMESTORMREAVERNECROLYTE\nUnitUINamerevenantoftheseas=0,unituiname,`revenantoftheseas`,WESTRING_UNITUINAMEREVENANTOFTHESEAS\nUnitUINamestormreaverwarlock=0,unituiname,`stormreaverwarlock`,WESTRING_UNITUINAMESTORMREAVERWARLOCK\nUnitUINamespittingspider=0,unituiname,`spittingspider`,WESTRING_UNITUINAMESPITTINGSPIDER\nUnitUINamesatyrhellcaller=0,unituiname,`satyrhellcaller`,WESTRING_UNITUINAMESATYRHELLCALLER\nUnitUINamesatyrsoulstealer=0,unituiname,`satyrsoulstealer`,WESTRING_UNITUINAMESATYRSOULSTEALER\nUnitUINamesatyrshadowdancer=0,unituiname,`satyrshadowdancer`,WESTRING_UNITUINAMESATYRSHADOWDANCER\nUnitUINamestormwyrm=0,unituiname,`stormwyrm`,WESTRING_UNITUINAMESTORMWYRM\nUnitUINamesatyr=0,unituiname,`satyr`,WESTRING_UNITUINAMESATYR\nUnitUINamethunderlizard=0,unituiname,`thunderlizard`,WESTRING_UNITUINAMETHUNDERLIZARD\nUnitUINametuskarrspearman=0,unituiname,`tuskarrspearman`,WESTRING_UNITUINAMETUSKARRSPEARMAN\nUnitUINametuskarrchieftain=0,unituiname,`tuskarrchieftain`,WESTRING_UNITUINAMETUSKARRCHIEFTAIN\nUnitUINametuskarrfighter=0,unituiname,`tuskarrfighter`,WESTRING_UNITUINAMETUSKARRFIGHTER\nUnitUINametuskarrhealer=0,unituiname,`tuskarrhealer`,WESTRING_UNITUINAMETUSKARRHEALER\nUnitUINametuskarrsorceror=0,unituiname,`tuskarrsorceror`,WESTRING_UNITUINAMETUSKARRSORCEROR\nUnitUINametuskarrtrapper=0,unituiname,`tuskarrtrapper`,WESTRING_UNITUINAMETUSKARRTRAPPER\nUnitUINametuskarrwarrior=0,unituiname,`tuskarrwarrior`,WESTRING_UNITUINAMETUSKARRWARRIOR\nUnitUINametornado=0,unituiname,`tornado`,WESTRING_UNITUINAMETORNADO\nUnitUINamedragonturtle=0,unituiname,`dragonturtle`,WESTRING_UNITUINAMEDRAGONTURTLE\nUnitUINamegargantuanseaturtle=0,unituiname,`gargantuanseaturtle`,WESTRING_UNITUINAMEGARGANTUANSEATURTLE\nUnitUINameseaturtlehatchling=0,unituiname,`seaturtlehatchling`,WESTRING_UNITUINAMESEATURTLEHATCHLING\nUnitUINameseaturtle=0,unituiname,`seaturtle`,WESTRING_UNITUINAMESEATURTLE\nUnitUINamegiantseaturtle=0,unituiname,`giantseaturtle`,WESTRING_UNITUINAMEGIANTSEATURTLE\nUnitUINamerevenantofthetides=0,unituiname,`revenantofthetides`,WESTRING_UNITUINAMEREVENANTOFTHETIDES\nUnitUINamewateryminiontidewarrior=0,unituiname,`wateryminiontidewarrior`,WESTRING_UNITUINAMEWATERYMINIONTIDEWARRIOR\nUnitUINameunbrokendarkhunter=0,unituiname,`unbrokendarkhunter`,WESTRING_UNITUINAMEUNBROKENDARKHUNTER\nUnitUINameunbrokenrager=0,unituiname,`unbrokenrager`,WESTRING_UNITUINAMEUNBROKENRAGER\nUnitUINameunbrokendarkweaver=0,unituiname,`unbrokendarkweaver`,WESTRING_UNITUINAMEUNBROKENDARKWEAVER\nUnitUINameeldervoidwalker=0,unituiname,`eldervoidwalker`,WESTRING_UNITUINAMEELDERVOIDWALKER\nUnitUINamegreatervoidwalker=0,unituiname,`greatervoidwalker`,WESTRING_UNITUINAMEGREATERVOIDWALKER\nUnitUINamelesservoidwalker=0,unituiname,`lesservoidwalker`,WESTRING_UNITUINAMELESSERVOIDWALKER\nUnitUINamevoidwalker=0,unituiname,`voidwalker`,WESTRING_UNITUINAMEVOIDWALKER\nUnitUINamewendigo1=0,unituiname,`wendigo1`,WESTRING_UNITUINAMEWENDIGO1\nUnitUINamenagacoutl=0,unituiname,`nagacoutl`,WESTRING_UNITUINAMENAGACOUTL\nUnitUINameapprenticewizard=0,unituiname,`apprenticewizard`,WESTRING_UNITUINAMEAPPRENTICEWIZARD\nUnitUINamedirewolf=0,unituiname,`direwolf`,WESTRING_UNITUINAMEDIREWOLF\nUnitUINamegiantwolf=0,unituiname,`giantwolf`,WESTRING_UNITUINAMEGIANTWOLF\nUnitUINametimberwolf=0,unituiname,`timberwolf`,WESTRING_UNITUINAMETIMBERWOLF\nUnitUINameancientwendigo=0,unituiname,`ancientwendigo`,WESTRING_UNITUINAMEANCIENTWENDIGO\nUnitUINameelderwendigo=0,unituiname,`elderwendigo`,WESTRING_UNITUINAMEELDERWENDIGO\nUnitUINamewendigoshaman=0,unituiname,`wendigoshaman`,WESTRING_UNITUINAMEWENDIGOSHAMAN\nUnitUINamewargolem=0,unituiname,`wargolem`,WESTRING_UNITUINAMEWARGOLEM\nUnitUINamewindserpent=0,unituiname,`windserpent`,WESTRING_UNITUINAMEWINDSERPENT\nUnitUINamewhitedirewolf=0,unituiname,`whitedirewolf`,WESTRING_UNITUINAMEWHITEDIREWOLF\nUnitUINamewhitewolf=0,unituiname,`whitewolf`,WESTRING_UNITUINAMEWHITEWOLF\nUnitUINamegiantwhitewolf=0,unituiname,`giantwhitewolf`,WESTRING_UNITUINAMEGIANTWHITEWOLF\nUnitUINamedarkwizard=0,unituiname,`darkwizard`,WESTRING_UNITUINAMEDARKWIZARD\nUnitUINamerenegadewizard=0,unituiname,`renegadewizard`,WESTRING_UNITUINAMERENEGADEWIZARD\nUnitUINameroguewizard=0,unituiname,`roguewizard`,WESTRING_UNITUINAMEROGUEWIZARD\nUnitUINamegoblinzeppelin=0,unituiname,`goblinzeppelin`,WESTRING_UNITUINAMEGOBLINZEPPELIN\nUnitUINamezombie=0,unituiname,`zombie`,WESTRING_UNITUINAMEZOMBIE\nUnitUINamechaplain=0,unituiname,`chaplain`,WESTRING_UNITUINAMECHAPLAIN\nUnitUINamehydromancer=0,unituiname,`hydromancer`,WESTRING_UNITUINAMEHYDROMANCER\nUnitUINamealbatross=0,unituiname,`albatross`,WESTRING_UNITUINAMEALBATROSS\nUnitUINamecrab=0,unituiname,`crab`,WESTRING_UNITUINAMECRAB\nUnitUINamedeer=0,unituiname,`deer`,WESTRING_UNITUINAMEDEER\nUnitUINamedog=0,unituiname,`dog`,WESTRING_UNITUINAMEDOG\nUnitUINameduneworm=0,unituiname,`duneworm`,WESTRING_UNITUINAMEDUNEWORM\nUnitUINamefelboar=0,unituiname,`felboar`,WESTRING_UNITUINAMEFELBOAR\nUnitUINamehermitcrab=0,unituiname,`hermitcrab`,WESTRING_UNITUINAMEHERMITCRAB\nUnitUINameowl2=0,unituiname,`owl2`,WESTRING_UNITUINAMEOWL2\nUnitUINameowl3=0,unituiname,`owl3`,WESTRING_UNITUINAMEOWL3\nUnitUINameowl=0,unituiname,`owl`,WESTRING_UNITUINAMEOWL\nUnitUINamepig=0,unituiname,`pig`,WESTRING_UNITUINAMEPIG\nUnitUINamepenguin=0,unituiname,`penguin`,WESTRING_UNITUINAMEPENGUIN\nUnitUINamewaterpenguin=0,unituiname,`waterpenguin`,WESTRING_UNITUINAMEWATERPENGUIN\nUnitUINamerat=0,unituiname,`rat`,WESTRING_UNITUINAMERAT\nUnitUINameseal=0,unituiname,`seal`,WESTRING_UNITUINAMESEAL\nUnitUINameamphibioussheep=0,unituiname,`amphibioussheep`,WESTRING_UNITUINAMEAMPHIBIOUSSHEEP\nUnitUINamesheep=0,unituiname,`sheep`,WESTRING_UNITUINAMESHEEP\nUnitUINameflyingsheep=0,unituiname,`flyingsheep`,WESTRING_UNITUINAMEFLYINGSHEEP\nUnitUINamewatersheep=0,unituiname,`watersheep`,WESTRING_UNITUINAMEWATERSHEEP\nUnitUINameskink=0,unituiname,`skink`,WESTRING_UNITUINAMESKINK\nUnitUINamesnowyowl=0,unituiname,`snowyowl`,WESTRING_UNITUINAMESNOWYOWL\nUnitUINamevillagerman=0,unituiname,`villagerman`,WESTRING_UNITUINAMEVILLAGERMAN\nUnitUINamevillagerkid2=0,unituiname,`villagerkid2`,WESTRING_UNITUINAMEVILLAGERKID2\nUnitUINamevillagerman2=0,unituiname,`villagerman2`,WESTRING_UNITUINAMEVILLAGERMAN2\nUnitUINamevillagerkid=0,unituiname,`villagerkid`,WESTRING_UNITUINAMEVILLAGERKID\nUnitUINamevillagerwoman=0,unituiname,`villagerwoman`,WESTRING_UNITUINAMEVILLAGERWOMAN\nUnitUINamevulture=0,unituiname,`vulture`,WESTRING_UNITUINAMEVULTURE\nUnitUINamecitybuildingSmall 0=0,unituiname,`citybuildingSmall 0`,WESTRING_UNITUINAMECITYBUILDINGSMALL 0\nUnitUINamecitybuildingSmall 1=0,unituiname,`citybuildingSmall 1`,WESTRING_UNITUINAMECITYBUILDINGSMALL 1\nUnitUINamecitybuildingSmall 2=0,unituiname,`citybuildingSmall 2`,WESTRING_UNITUINAMECITYBUILDINGSMALL 2\nUnitUINamecitybuildingSmall 3=0,unituiname,`citybuildingSmall 3`,WESTRING_UNITUINAMECITYBUILDINGSMALL 3\nUnitUINamecitybuildingSmall 4=0,unituiname,`citybuildingSmall 4`,WESTRING_UNITUINAMECITYBUILDINGSMALL 4\nUnitUINamecitybuildingSmall 5=0,unituiname,`citybuildingSmall 5`,WESTRING_UNITUINAMECITYBUILDINGSMALL 5\nUnitUINamecitybuildingSmall 6=0,unituiname,`citybuildingSmall 6`,WESTRING_UNITUINAMECITYBUILDINGSMALL 6\nUnitUINamecitybuildingSmall 7=0,unituiname,`citybuildingSmall 7`,WESTRING_UNITUINAMECITYBUILDINGSMALL 7\nUnitUINamecitybuildingSmall 8=0,unituiname,`citybuildingSmall 8`,WESTRING_UNITUINAMECITYBUILDINGSMALL 8\nUnitUINamecitybuildingSmall 9=0,unituiname,`citybuildingSmall 9`,WESTRING_UNITUINAMECITYBUILDINGSMALL 9\nUnitUINamecitybuildingSmall a=0,unituiname,`citybuildingSmall a`,WESTRING_UNITUINAMECITYBUILDINGSMALL A\nUnitUINamecitybuildingSmall b=0,unituiname,`citybuildingSmall b`,WESTRING_UNITUINAMECITYBUILDINGSMALL B\nUnitUINameCityBuildingLarge 0=0,unituiname,`CityBuildingLarge 0`,WESTRING_UNITUINAMECITYBUILDINGLARGE 0\nUnitUINameCityBuildingLarge 1=0,unituiname,`CityBuildingLarge 1`,WESTRING_UNITUINAMECITYBUILDINGLARGE 1\nUnitUINameCityBuildingLarge 2=0,unituiname,`CityBuildingLarge 2`,WESTRING_UNITUINAMECITYBUILDINGLARGE 2\nUnitUINameCityBuildingLarge 3=0,unituiname,`CityBuildingLarge 3`,WESTRING_UNITUINAMECITYBUILDINGLARGE 3\nUnitUINamecentaurtent=0,unituiname,`centaurtent`,WESTRING_UNITUINAMECENTAURTENT\nUnitUINamecircleofpower=0,unituiname,`circleofpower`,WESTRING_UNITUINAMECIRCLEOFPOWER\nUnitUINamecircleofpowermedium=0,unituiname,`circleofpowermedium`,WESTRING_UNITUINAMECIRCLEOFPOWERMEDIUM\nUnitUINamecircleofpowerlarge=0,unituiname,`circleofpowerlarge`,WESTRING_UNITUINAMECIRCLEOFPOWERLARGE\nUnitUINamecentaurtent1=0,unituiname,`centaurtent1`,WESTRING_UNITUINAMECENTAURTENT1\nUnitUINamecentaurtent2=0,unituiname,`centaurtent2`,WESTRING_UNITUINAMECENTAURTENT2\nUnitUINamechieftainhut=0,unituiname,`chieftainhut`,WESTRING_UNITUINAMECHIEFTAINHUT\nUnitUINamedraneihut0=0,unituiname,`draneihut0`,WESTRING_UNITUINAMEDRANEIHUT0\nUnitUINamedraneihut1=0,unituiname,`draneihut1`,WESTRING_UNITUINAMEDRANEIHUT1\nUnitUINamedraeneihaven=0,unituiname,`draeneihaven`,WESTRING_UNITUINAMEDRAENEIHAVEN\nUnitUINamedraeneiwarriorshall=0,unituiname,`draeneiwarriorshall`,WESTRING_UNITUINAMEDRAENEIWARRIORSHALL\nUnitUINamedraeneiseerden=0,unituiname,`draeneiseerden`,WESTRING_UNITUINAMEDRAENEISEERDEN\nUnitUINamegreendragonroost=0,unituiname,`greendragonroost`,WESTRING_UNITUINAMEGREENDRAGONROOST\nUnitUINameblackdragonroost=0,unituiname,`blackdragonroost`,WESTRING_UNITUINAMEBLACKDRAGONROOST\nUnitUINameoutlanddragonroost=0,unituiname,`outlanddragonroost`,WESTRING_UNITUINAMEOUTLANDDRAGONROOST\nUnitUINamereddragonroost=0,unituiname,`reddragonroost`,WESTRING_UNITUINAMEREDDRAGONROOST\nUnitUINamebluedragonroost=0,unituiname,`bluedragonroost`,WESTRING_UNITUINAMEBLUEDRAGONROOST\nUnitUINamebronzedragonroost=0,unituiname,`bronzedragonroost`,WESTRING_UNITUINAMEBRONZEDRAGONROOST\nUnitUINameforesttrollhut0=0,unituiname,`foresttrollhut0`,WESTRING_UNITUINAMEFORESTTROLLHUT0\nUnitUINameforesttrollhut1=0,unituiname,`foresttrollhut1`,WESTRING_UNITUINAMEFORESTTROLLHUT1\nUnitUINamefountainofhealth=0,unituiname,`fountainofhealth`,WESTRING_UNITUINAMEFOUNTAINOFHEALTH\nUnitUINamefurbolghut1=0,unituiname,`furbolghut1`,WESTRING_UNITUINAMEFURBOLGHUT1\nUnitUINamefurbolghut2=0,unituiname,`furbolghut2`,WESTRING_UNITUINAMEFURBOLGHUT2\nUnitUINamegoblinammodump=0,unituiname,`goblinammodump`,WESTRING_UNITUINAMEGOBLINAMMODUMP\nUnitUINamegoblinmerchant=0,unituiname,`goblinmerchant`,WESTRING_UNITUINAMEGOBLINMERCHANT\nUnitUINamegnollhut=0,unituiname,`gnollhut`,WESTRING_UNITUINAMEGNOLLHUT\nUnitUINamegranaryinfected=0,unituiname,`granaryinfected`,WESTRING_UNITUINAMEGRANARYINFECTED\nUnitUINamegoldmine=0,unituiname,`goldmine`,WESTRING_UNITUINAMEGOLDMINE\nUnitUINamegnollhut2=0,unituiname,`gnollhut2`,WESTRING_UNITUINAMEGNOLLHUT2\nUnitUINamegrainwarehouse=0,unituiname,`grainwarehouse`,WESTRING_UNITUINAMEGRAINWAREHOUSE\nUnitUINameharpynest=0,unituiname,`harpynest`,WESTRING_UNITUINAMEHARPYNEST\nUnitUINamemercenarycampl=0,unituiname,`mercenarycampl`,WESTRING_UNITUINAMEMERCENARYCAMPL\nUnitUINamemurgulhut0=0,unituiname,`murgulhut0`,WESTRING_UNITUINAMEMURGULHUT0\nUnitUINamemurgulhut1=0,unituiname,`murgulhut1`,WESTRING_UNITUINAMEMURGULHUT1\nUnitUINamemurlochut0=0,unituiname,`murlochut0`,WESTRING_UNITUINAMEMURLOCHUT0\nUnitUINamemurlochut1=0,unituiname,`murlochut1`,WESTRING_UNITUINAMEMURLOCHUT1\nUnitUINamefountainofmana=0,unituiname,`fountainofmana`,WESTRING_UNITUINAMEFOUNTAINOFMANA\nUnitUINamemercenarycampv=0,unituiname,`mercenarycampv`,WESTRING_UNITUINAMEMERCENARYCAMPV\nUnitUINamemercenarycampf=0,unituiname,`mercenarycampf`,WESTRING_UNITUINAMEMERCENARYCAMPF\nUnitUINamemercenarycampw=0,unituiname,`mercenarycampw`,WESTRING_UNITUINAMEMERCENARYCAMPW\nUnitUINamemercenarycampb=0,unituiname,`mercenarycampb`,WESTRING_UNITUINAMEMERCENARYCAMPB\nUnitUINamemercenarycampa=0,unituiname,`mercenarycampa`,WESTRING_UNITUINAMEMERCENARYCAMPA\nUnitUINamemercenarycampc=0,unituiname,`mercenarycampc`,WESTRING_UNITUINAMEMERCENARYCAMPC\nUnitUINamemercenarycampn=0,unituiname,`mercenarycampn`,WESTRING_UNITUINAMEMERCENARYCAMPN\nUnitUINamemercenarycampy=0,unituiname,`mercenarycampy`,WESTRING_UNITUINAMEMERCENARYCAMPY\nUnitUINamemercenarycampx=0,unituiname,`mercenarycampx`,WESTRING_UNITUINAMEMERCENARYCAMPX\nUnitUINamemercenarycampd=0,unituiname,`mercenarycampd`,WESTRING_UNITUINAMEMERCENARYCAMPD\nUnitUINamemercenarycampg=0,unituiname,`mercenarycampg`,WESTRING_UNITUINAMEMERCENARYCAMPG\nUnitUINamemercenarycampz=0,unituiname,`mercenarycampz`,WESTRING_UNITUINAMEMERCENARYCAMPZ\nUnitUINamemercenarycampi=0,unituiname,`mercenarycampi`,WESTRING_UNITUINAMEMERCENARYCAMPI\nUnitUINamemercenarycampo=0,unituiname,`mercenarycampo`,WESTRING_UNITUINAMEMERCENARYCAMPO\nUnitUINamemercenarycampk=0,unituiname,`mercenarycampk`,WESTRING_UNITUINAMEMERCENARYCAMPK\nUnitUINamemarketplace=0,unituiname,`marketplace`,WESTRING_UNITUINAMEMARKETPLACE\nUnitUINamenerubianziggurat=0,unituiname,`nerubianziggurat`,WESTRING_UNITUINAMENERUBIANZIGGURAT\nUnitUINamegoblinshipyard=0,unituiname,`goblinshipyard`,WESTRING_UNITUINAMEGOBLINSHIPYARD\nUnitUINamecantina=0,unituiname,`cantina`,WESTRING_UNITUINAMECANTINA\nUnitUINametent=0,unituiname,`tent`,WESTRING_UNITUINAMETENT\nUnitUINameicetrollhut0=0,unituiname,`icetrollhut0`,WESTRING_UNITUINAMEICETROLLHUT0\nUnitUINameicetrollhut1=0,unituiname,`icetrollhut1`,WESTRING_UNITUINAMEICETROLLHUT1\nUnitUINametent2=0,unituiname,`tent2`,WESTRING_UNITUINAMETENT2\nUnitUINametaurentent=0,unituiname,`taurentent`,WESTRING_UNITUINAMETAURENTENT\nUnitUINametaurentent2=0,unituiname,`taurentent2`,WESTRING_UNITUINAMETAURENTENT2\nUnitUINamewaygate=0,unituiname,`waygate`,WESTRING_UNITUINAMEWAYGATE\nUnitUINamecenarius=0,unituiname,`cenarius`,WESTRING_UNITUINAMECENARIUS\nUnitUINameevilillidan=0,unituiname,`evilillidan`,WESTRING_UNITUINAMEEVILILLIDAN\nUnitUINameevilillidandemonform=0,unituiname,`evilillidandemonform`,WESTRING_UNITUINAMEEVILILLIDANDEMONFORM\nUnitUINamefurion=0,unituiname,`furion`,WESTRING_UNITUINAMEFURION\nUnitUINameillidandemonform=0,unituiname,`illidandemonform`,WESTRING_UNITUINAMEILLIDANDEMONFORM\nUnitUINameillidan=0,unituiname,`illidan`,WESTRING_UNITUINAMEILLIDAN\nUnitUINameillidanmorphed=0,unituiname,`illidanmorphed`,WESTRING_UNITUINAMEILLIDANMORPHED\nUnitUINamekeeperofthegroveghost=0,unituiname,`keeperofthegroveghost`,WESTRING_UNITUINAMEKEEPEROFTHEGROVEGHOST\nUnitUINamemalfurion=0,unituiname,`malfurion`,WESTRING_UNITUINAMEMALFURION\nUnitUINamemalfurionnostag=0,unituiname,`malfurionnostag`,WESTRING_UNITUINAMEMALFURIONNOSTAG\nUnitUINametyrande=0,unituiname,`tyrande`,WESTRING_UNITUINAMETYRANDE\nUnitUINamemaiev=0,unituiname,`maiev`,WESTRING_UNITUINAMEMAIEV\nUnitUINameantonidus=0,unituiname,`antonidus`,WESTRING_UNITUINAMEANTONIDUS\nUnitUINameadmiralproudmoore=0,unituiname,`admiralproudmoore`,WESTRING_UNITUINAMEADMIRALPROUDMOORE\nUnitUINamearthaswithfrostmourne=0,unituiname,`arthaswithfrostmourne`,WESTRING_UNITUINAMEARTHASWITHFROSTMOURNE\nUnitUINamearthas=0,unituiname,`arthas`,WESTRING_UNITUINAMEARTHAS\nUnitUINamedagren=0,unituiname,`dagren`,WESTRING_UNITUINAMEDAGREN\nUnitUINamehalahk=0,unituiname,`halahk`,WESTRING_UNITUINAMEHALAHK\nUnitUINamejaina=0,unituiname,`jaina`,WESTRING_UNITUINAMEJAINA\nUnitUINamekael=0,unituiname,`kael`,WESTRING_UNITUINAMEKAEL\nUnitUINamelordgarithos=0,unituiname,`lordgarithos`,WESTRING_UNITUINAMELORDGARITHOS\nUnitUINamemuradinbronzebeard=0,unituiname,`muradinbronzebeard`,WESTRING_UNITUINAMEMURADINBRONZEBEARD\nUnitUINamemargoth=0,unituiname,`margoth`,WESTRING_UNITUINAMEMARGOTH\nUnitUINamepaladinboss1=0,unituiname,`paladinboss1`,WESTRING_UNITUINAMEPALADINBOSS1\nUnitUINamepaladinboss2=0,unituiname,`paladinboss2`,WESTRING_UNITUINAMEPALADINBOSS2\nUnitUINameuther=0,unituiname,`uther`,WESTRING_UNITUINAMEUTHER\nUnitUINameladyvashj=0,unituiname,`ladyvashj`,WESTRING_UNITUINAMELADYVASHJ\nUnitUINamesylvanuswindrunner=0,unituiname,`sylvanuswindrunner`,WESTRING_UNITUINAMESYLVANUSWINDRUNNER\nUnitUINameblackrockblademaster=0,unituiname,`blackrockblademaster`,WESTRING_UNITUINAMEBLACKROCKBLADEMASTER\nUnitUINamekiljaeden=0,unituiname,`kiljaeden`,WESTRING_UNITUINAMEKILJAEDEN\nUnitUINamekiljaedencinematic=0,unituiname,`kiljaedencinematic`,WESTRING_UNITUINAMEKILJAEDENCINEMATIC\nUnitUINamemagtheridon=0,unituiname,`magtheridon`,WESTRING_UNITUINAMEMAGTHERIDON\nUnitUINamemannoroth=0,unituiname,`mannoroth`,WESTRING_UNITUINAMEMANNOROTH\nUnitUINameoldpitlord=0,unituiname,`oldpitlord`,WESTRING_UNITUINAMEOLDPITLORD\nUnitUINamesinjostormstout=0,unituiname,`sinjostormstout`,WESTRING_UNITUINAMESINJOSTORMSTOUT\nUnitUINamecairnebloodhoof=0,unituiname,`cairnebloodhoof`,WESTRING_UNITUINAMECAIRNEBLOODHOOF\nUnitUINamecairnebloodhoofexp=0,unituiname,`cairnebloodhoofexp`,WESTRING_UNITUINAMECAIRNEBLOODHOOFEXP\nUnitUINamedrekthar=0,unituiname,`drekthar`,WESTRING_UNITUINAMEDREKTHAR\nUnitUINameguldan=0,unituiname,`guldan`,WESTRING_UNITUINAMEGULDAN\nUnitUINamegromhellscream=0,unituiname,`gromhellscream`,WESTRING_UNITUINAMEGROMHELLSCREAM\nUnitUINamepossessedgromhellscream=0,unituiname,`possessedgromhellscream`,WESTRING_UNITUINAMEPOSSESSEDGROMHELLSCREAM\nUnitUINamerexxar=0,unituiname,`rexxar`,WESTRING_UNITUINAMEREXXAR\nUnitUINamerokhan=0,unituiname,`rokhan`,WESTRING_UNITUINAMEROKHAN\nUnitUINamesamuro=0,unituiname,`samuro`,WESTRING_UNITUINAMESAMURO\nUnitUINamecairnebloodhoofcinematic=0,unituiname,`cairnebloodhoofcinematic`,WESTRING_UNITUINAMECAIRNEBLOODHOOFCINEMATIC\nUnitUINamethrall=0,unituiname,`thrall`,WESTRING_UNITUINAMETHRALL\nUnitUINameanubarak=0,unituiname,`anubarak`,WESTRING_UNITUINAMEANUBARAK\nUnitUINamebalnazzar=0,unituiname,`balnazzar`,WESTRING_UNITUINAMEBALNAZZAR\nUnitUINamekelthuzadlichcinematic=0,unituiname,`kelthuzadlichcinematic`,WESTRING_UNITUINAMEKELTHUZADLICHCINEMATIC\nUnitUINamedetheroc=0,unituiname,`detheroc`,WESTRING_UNITUINAMEDETHEROC\nUnitUINameevilarthas=0,unituiname,`evilarthas`,WESTRING_UNITUINAMEEVILARTHAS\nUnitUINamekelthuzadlich=0,unituiname,`kelthuzadlich`,WESTRING_UNITUINAMEKELTHUZADLICH\nUnitUINamemalganis=0,unituiname,`malganis`,WESTRING_UNITUINAMEMALGANIS\nUnitUINameevilsylvanas=0,unituiname,`evilsylvanas`,WESTRING_UNITUINAMEEVILSYLVANAS\nUnitUINametichondrius=0,unituiname,`tichondrius`,WESTRING_UNITUINAMETICHONDRIUS\nUnitUINamevarimathras=0,unituiname,`varimathras`,WESTRING_UNITUINAMEVARIMATHRAS\nUnitUINamevengyr=0,unituiname,`vengyr`,WESTRING_UNITUINAMEVENGYR\nUnitUINamearchimonde=0,unituiname,`archimonde`,WESTRING_UNITUINAMEARCHIMONDE\nUnitUINameghostlyarchmage=0,unituiname,`ghostlyarchmage`,WESTRING_UNITUINAMEGHOSTLYARCHMAGE\nUnitUINameillidanwagon=0,unituiname,`illidanwagon`,WESTRING_UNITUINAMEILLIDANWAGON\nUnitUINamenightelfrunner=0,unituiname,`nightelfrunner`,WESTRING_UNITUINAMENIGHTELFRUNNER\nUnitUINamenaisha=0,unituiname,`naisha`,WESTRING_UNITUINAMENAISHA\nUnitUINameshandris=0,unituiname,`shandris`,WESTRING_UNITUINAMESHANDRIS\nUnitUINamenightelftransportship=0,unituiname,`nightelftransportship`,WESTRING_UNITUINAMENIGHTELFTRANSPORTSHIP\nUnitUINamebloodelfwagon=0,unituiname,`bloodelfwagon`,WESTRING_UNITUINAMEBLOODELFWAGON\nUnitUINamethecaptain=0,unituiname,`thecaptain`,WESTRING_UNITUINAMETHECAPTAIN\nUnitUINameriderlesshorse=0,unituiname,`riderlesshorse`,WESTRING_UNITUINAMERIDERLESSHORSE\nUnitUINamehighelvenswordsman=0,unituiname,`highelvenswordsman`,WESTRING_UNITUINAMEHIGHELVENSWORDSMAN\nUnitUINamepackhorse=0,unituiname,`packhorse`,WESTRING_UNITUINAMEPACKHORSE\nUnitUINameakama=0,unituiname,`akama`,WESTRING_UNITUINAMEAKAMA\nUnitUINamespiritbeast=0,unituiname,`spiritbeast`,WESTRING_UNITUINAMESPIRITBEAST\nUnitUINamespiritbeast2=0,unituiname,`spiritbeast2`,WESTRING_UNITUINAMESPIRITBEAST2\nUnitUINamespiritbeast3=0,unituiname,`spiritbeast3`,WESTRING_UNITUINAMESPIRITBEAST3\nUnitUINamedemolisherdraenei=0,unituiname,`demolisherdraenei`,WESTRING_UNITUINAMEDEMOLISHERDRAENEI\nUnitUINamebloodelfengineer=0,unituiname,`bloodelfengineer`,WESTRING_UNITUINAMEBLOODELFENGINEER\nUnitUINamebloodelflieutenant=0,unituiname,`bloodelflieutenant`,WESTRING_UNITUINAMEBLOODELFLIEUTENANT\nUnitUINamebattleship=0,unituiname,`battleship`,WESTRING_UNITUINAMEBATTLESHIP\nUnitUINamechaosgrunt=0,unituiname,`chaosgrunt`,WESTRING_UNITUINAMECHAOSGRUNT\nUnitUINamechaoswolfrider=0,unituiname,`chaoswolfrider`,WESTRING_UNITUINAMECHAOSWOLFRIDER\nUnitUINamechaoswarlock=0,unituiname,`chaoswarlock`,WESTRING_UNITUINAMECHAOSWARLOCK\nUnitUINamechaoskotobeast=0,unituiname,`chaoskotobeast`,WESTRING_UNITUINAMECHAOSKOTOBEAST\nUnitUINamechaospeon=0,unituiname,`chaospeon`,WESTRING_UNITUINAMECHAOSPEON\nUnitUINamedalaranmutant=0,unituiname,`dalaranmutant`,WESTRING_UNITUINAMEDALARANMUTANT\nUnitUINamedraeneidarkslayer=0,unituiname,`draeneidarkslayer`,WESTRING_UNITUINAMEDRAENEIDARKSLAYER\nUnitUINamedraeneivindicator=0,unituiname,`draeneivindicator`,WESTRING_UNITUINAMEDRAENEIVINDICATOR\nUnitUINamedraeneistalker=0,unituiname,`draeneistalker`,WESTRING_UNITUINAMEDRAENEISTALKER\nUnitUINamedraeneiguardian=0,unituiname,`draeneiguardian`,WESTRING_UNITUINAMEDRAENEIGUARDIAN\nUnitUINamedraeneiharbinger=0,unituiname,`draeneiharbinger`,WESTRING_UNITUINAMEDRAENEIHARBINGER\nUnitUINamedalaranreject=0,unituiname,`dalaranreject`,WESTRING_UNITUINAMEDALARANREJECT\nUnitUINamedraeneidisciple=0,unituiname,`draeneidisciple`,WESTRING_UNITUINAMEDRAENEIDISCIPLE\nUnitUINamedraeneiprotector=0,unituiname,`draeneiprotector`,WESTRING_UNITUINAMEDRAENEIPROTECTOR\nUnitUINamedraeneiseer=0,unituiname,`draeneiseer`,WESTRING_UNITUINAMEDRAENEISEER\nUnitUINamedraeneiwatcher=0,unituiname,`draeneiwatcher`,WESTRING_UNITUINAMEDRAENEIWATCHER\nUnitUINamedraeneilaborer=0,unituiname,`draeneilaborer`,WESTRING_UNITUINAMEDRAENEILABORER\nUnitUINamedraeneisalamander=0,unituiname,`draeneisalamander`,WESTRING_UNITUINAMEDRAENEISALAMANDER\nUnitUINameengineergazlowe=0,unituiname,`engineergazlowe`,WESTRING_UNITUINAMEENGINEERGAZLOWE\nUnitUINameemissary=0,unituiname,`emissary`,WESTRING_UNITUINAMEEMISSARY\nUnitUINamefleshgolem=0,unituiname,`fleshgolem`,WESTRING_UNITUINAMEFLESHGOLEM\nUnitUINamegoblinblaster=0,unituiname,`goblinblaster`,WESTRING_UNITUINAMEGOBLINBLASTER\nUnitUINamehighelvenarcher=0,unituiname,`highelvenarcher`,WESTRING_UNITUINAMEHIGHELVENARCHER\nUnitUINamehighelvenfemale=0,unituiname,`highelvenfemale`,WESTRING_UNITUINAMEHIGHELVENFEMALE\nUnitUINamehighelvenmale=0,unituiname,`highelvenmale`,WESTRING_UNITUINAMEHIGHELVENMALE\nUnitUINamebloodelfworker=0,unituiname,`bloodelfworker`,WESTRING_UNITUINAMEBLOODELFWORKER\nUnitUINamejailorkassan=0,unituiname,`jailorkassan`,WESTRING_UNITUINAMEJAILORKASSAN\nUnitUINamemedivhmorphed=0,unituiname,`medivhmorphed`,WESTRING_UNITUINAMEMEDIVHMORPHED\nUnitUINamemedivh=0,unituiname,`medivh`,WESTRING_UNITUINAMEMEDIVH\nUnitUINamemurgulslave=0,unituiname,`murgulslave`,WESTRING_UNITUINAMEMURGULSLAVE\nUnitUINamemisha=0,unituiname,`misha`,WESTRING_UNITUINAMEMISHA\nUnitUINamesearinox=0,unituiname,`searinox`,WESTRING_UNITUINAMESEARINOX\nUnitUINamesupportcolumn=0,unituiname,`supportcolumn`,WESTRING_UNITUINAMESUPPORTCOLUMN\nUnitUINamenightelfassassin=0,unituiname,`nightelfassassin`,WESTRING_UNITUINAMENIGHTELFASSASSIN\nUnitUINametharifas=0,unituiname,`tharifas`,WESTRING_UNITUINAMETHARIFAS\nUnitUINamewar2warlock=0,unituiname,`war2warlock`,WESTRING_UNITUINAMEWAR2WARLOCK\nUnitUINamewatcher=0,unituiname,`watcher`,WESTRING_UNITUINAMEWATCHER\nUnitUINamedrakthul=0,unituiname,`drakthul`,WESTRING_UNITUINAMEDRAKTHUL\nUnitUINamegarthok=0,unituiname,`garthok`,WESTRING_UNITUINAMEGARTHOK\nUnitUINamejuggernaut=0,unituiname,`juggernaut`,WESTRING_UNITUINAMEJUGGERNAUT\nUnitUINamemathog=0,unituiname,`mathog`,WESTRING_UNITUINAMEMATHOG\nUnitUINamenazgrel=0,unituiname,`nazgrel`,WESTRING_UNITUINAMENAZGREL\nUnitUINamekotobeastnorider=0,unituiname,`kotobeastnorider`,WESTRING_UNITUINAMEKOTOBEASTNORIDER\nUnitUINamespiritwyvern=0,unituiname,`spiritwyvern`,WESTRING_UNITUINAMESPIRITWYVERN\nUnitUINamevoljin=0,unituiname,`voljin`,WESTRING_UNITUINAMEVOLJIN\nUnitUINamechaoswarlord=0,unituiname,`chaoswarlord`,WESTRING_UNITUINAMECHAOSWARLORD\nUnitUINameriderlesswyvern=0,unituiname,`riderlesswyvern`,WESTRING_UNITUINAMERIDERLESSWYVERN\nUnitUINameabominationcinematic=0,unituiname,`abominationcinematic`,WESTRING_UNITUINAMEABOMINATIONCINEMATIC\nUnitUINameairbarge=0,unituiname,`airbarge`,WESTRING_UNITUINAMEAIRBARGE\nUnitUINameazurelordfrostwyrm=0,unituiname,`azurelordfrostwyrm`,WESTRING_UNITUINAMEAZURELORDFROSTWYRM\nUnitUINameazureloredragon=0,unituiname,`azureloredragon`,WESTRING_UNITUINAMEAZURELOREDRAGON\nUnitUINameundeadtransportship=0,unituiname,`undeadtransportship`,WESTRING_UNITUINAMEUNDEADTRANSPORTSHIP\nUnitUINameundeaddestroyer=0,unituiname,`undeaddestroyer`,WESTRING_UNITUINAMEUNDEADDESTROYER\nUnitUINamekelthuzadghost=0,unituiname,`kelthuzadghost`,WESTRING_UNITUINAMEKELTHUZADGHOST\nUnitUINamekelthuzadnecro=0,unituiname,`kelthuzadnecro`,WESTRING_UNITUINAMEKELTHUZADNECRO\nUnitUINamesylvanusbanshee=0,unituiname,`sylvanusbanshee`,WESTRING_UNITUINAMESYLVANUSBANSHEE\nUnitUINameshimmeringportal=0,unituiname,`shimmeringportal`,WESTRING_UNITUINAMESHIMMERINGPORTAL\nUnitUINamearcaneobservatory=0,unituiname,`arcaneobservatory`,WESTRING_UNITUINAMEARCANEOBSERVATORY\nUnitUINamebloodfountain=0,unituiname,`bloodfountain`,WESTRING_UNITUINAMEBLOODFOUNTAIN\nUnitUINamebookofsummoning=0,unituiname,`bookofsummoning`,WESTRING_UNITUINAMEBOOKOFSUMMONING\nUnitUINamebouldertower=0,unituiname,`bouldertower`,WESTRING_UNITUINAMEBOULDERTOWER\nUnitUINamebouldertowerupgrade=0,unituiname,`bouldertowerupgrade`,WESTRING_UNITUINAMEBOULDERTOWERUPGRADE\nUnitUINamebarrowden=0,unituiname,`barrowden`,WESTRING_UNITUINAMEBARROWDEN\nUnitUINamecorruptedancientprotector=0,unituiname,`corruptedancientprotector`,WESTRING_UNITUINAMECORRUPTEDANCIENTPROTECTOR\nUnitUINamecorruptedancientofwar=0,unituiname,`corruptedancientofwar`,WESTRING_UNITUINAMECORRUPTEDANCIENTOFWAR\nUnitUINamecorruptedmoonwell=0,unituiname,`corruptedmoonwell`,WESTRING_UNITUINAMECORRUPTEDMOONWELL\nUnitUINamecorruptedtreeofages=0,unituiname,`corruptedtreeofages`,WESTRING_UNITUINAMECORRUPTEDTREEOFAGES\nUnitUINamecorruptedtreeofeternity=0,unituiname,`corruptedtreeofeternity`,WESTRING_UNITUINAMECORRUPTEDTREEOFETERNITY\nUnitUINamecorruptedtreeoflife=0,unituiname,`corruptedtreeoflife`,WESTRING_UNITUINAMECORRUPTEDTREEOFLIFE\nUnitUINamedefiledfountainoflife=0,unituiname,`defiledfountainoflife`,WESTRING_UNITUINAMEDEFILEDFOUNTAINOFLIFE\nUnitUINamedalaranguardtower=0,unituiname,`dalaranguardtower`,WESTRING_UNITUINAMEDALARANGUARDTOWER\nUnitUINamedarkportalse=0,unituiname,`darkportalse`,WESTRING_UNITUINAMEDARKPORTALSE\nUnitUINamedarkportalsw=0,unituiname,`darkportalsw`,WESTRING_UNITUINAMEDARKPORTALSW\nUnitUINamedemongate=0,unituiname,`demongate`,WESTRING_UNITUINAMEDEMONGATE\nUnitUINamedragonbuilding=0,unituiname,`dragonbuilding`,WESTRING_UNITUINAMEDRAGONBUILDING\nUnitUINamecoldtower=0,unituiname,`coldtower`,WESTRING_UNITUINAMECOLDTOWER\nUnitUINamecoldtowerupgrade=0,unituiname,`coldtowerupgrade`,WESTRING_UNITUINAMECOLDTOWERUPGRADE\nUnitUINameelvenfarm0=0,unituiname,`elvenfarm0`,WESTRING_UNITUINAMEELVENFARM0\nUnitUINameelvenfarm1=0,unituiname,`elvenfarm1`,WESTRING_UNITUINAMEELVENFARM1\nUnitUINameelvenfarm2=0,unituiname,`elvenfarm2`,WESTRING_UNITUINAMEELVENFARM2\nUnitUINameelvenfarm3=0,unituiname,`elvenfarm3`,WESTRING_UNITUINAMEELVENFARM3\nUnitUINameelvenfarm4=0,unituiname,`elvenfarm4`,WESTRING_UNITUINAMEELVENFARM4\nUnitUINameelvenfarm5=0,unituiname,`elvenfarm5`,WESTRING_UNITUINAMEELVENFARM5\nUnitUINameelvenfarm6=0,unituiname,`elvenfarm6`,WESTRING_UNITUINAMEELVENFARM6\nUnitUINameelvenfarm7=0,unituiname,`elvenfarm7`,WESTRING_UNITUINAMEELVENFARM7\nUnitUINameelvenfarm=0,unituiname,`elvenfarm`,WESTRING_UNITUINAMEELVENFARM\nUnitUINameearthfurytower=0,unituiname,`earthfurytower`,WESTRING_UNITUINAMEEARTHFURYTOWER\nUnitUINameskyfurytower=0,unituiname,`skyfurytower`,WESTRING_UNITUINAMESKYFURYTOWER\nUnitUINameelvenguardtower=0,unituiname,`elvenguardtower`,WESTRING_UNITUINAMEELVENGUARDTOWER\nUnitUINameenergytower=0,unituiname,`energytower`,WESTRING_UNITUINAMEENERGYTOWER\nUnitUINameenergytowerupgrade=0,unituiname,`energytowerupgrade`,WESTRING_UNITUINAMEENERGYTOWERUPGRADE\nUnitUINamepurplefountain=0,unituiname,`purplefountain`,WESTRING_UNITUINAMEPURPLEFOUNTAIN\nUnitUINamefrostmourne=0,unituiname,`frostmourne`,WESTRING_UNITUINAMEFROSTMOURNE\nUnitUINamefruitstand=0,unituiname,`fruitstand`,WESTRING_UNITUINAMEFRUITSTAND\nUnitUINameflametower=0,unituiname,`flametower`,WESTRING_UNITUINAMEFLAMETOWER\nUnitUINameflametowerupgrade=0,unituiname,`flametowerupgrade`,WESTRING_UNITUINAMEFLAMETOWERUPGRADE\nUnitUINameelvenfishingvillage0=0,unituiname,`elvenfishingvillage0`,WESTRING_UNITUINAMEELVENFISHINGVILLAGE0\nUnitUINameelvenfishingvillage1=0,unituiname,`elvenfishingvillage1`,WESTRING_UNITUINAMEELVENFISHINGVILLAGE1\nUnitUINameelvenfishingvillage2=0,unituiname,`elvenfishingvillage2`,WESTRING_UNITUINAMEELVENFISHINGVILLAGE2\nUnitUINameelvenfishingvillage3=0,unituiname,`elvenfishingvillage3`,WESTRING_UNITUINAMEELVENFISHINGVILLAGE3\nUnitUINameelvenfishingvillage4=0,unituiname,`elvenfishingvillage4`,WESTRING_UNITUINAMEELVENFISHINGVILLAGE4\nUnitUINamegemstoneobelisk=0,unituiname,`gemstoneobelisk`,WESTRING_UNITUINAMEGEMSTONEOBELISK\nUnitUINamehornofcenarius=0,unituiname,`hornofcenarius`,WESTRING_UNITUINAMEHORNOFCENARIUS\nUnitUINamehighelfbarracks=0,unituiname,`highelfbarracks`,WESTRING_UNITUINAMEHIGHELFBARRACKS\nUnitUINameicecrownobelisk=0,unituiname,`icecrownobelisk`,WESTRING_UNITUINAMEICECROWNOBELISK\nUnitUINametreasurebox=0,unituiname,`treasurebox`,WESTRING_UNITUINAMETREASUREBOX\nUnitUINamemagicvault=0,unituiname,`magicvault`,WESTRING_UNITUINAMEMAGICVAULT\nUnitUINamealtarofthedepths=0,unituiname,`altarofthedepths`,WESTRING_UNITUINAMEALTAROFTHEDEPTHS\nUnitUINamecoralbed=0,unituiname,`coralbed`,WESTRING_UNITUINAMECORALBED\nUnitUINameshrineofazshara=0,unituiname,`shrineofazshara`,WESTRING_UNITUINAMESHRINEOFAZSHARA\nUnitUINamespawninggrounds=0,unituiname,`spawninggrounds`,WESTRING_UNITUINAMESPAWNINGGROUNDS\nUnitUINametidalguardian=0,unituiname,`tidalguardian`,WESTRING_UNITUINAMETIDALGUARDIAN\nUnitUINametempleoftides=0,unituiname,`templeoftides`,WESTRING_UNITUINAMETEMPLEOFTIDES\nUnitUINamepigfarm=0,unituiname,`pigfarm`,WESTRING_UNITUINAMEPIGFARM\nUnitUINamepowergenerator=0,unituiname,`powergenerator`,WESTRING_UNITUINAMEPOWERGENERATOR\nUnitUINameshrine=0,unituiname,`shrine`,WESTRING_UNITUINAMESHRINE\nUnitUINamedeathtower=0,unituiname,`deathtower`,WESTRING_UNITUINAMEDEATHTOWER\nUnitUINamedeathtowerupgrade=0,unituiname,`deathtowerupgrade`,WESTRING_UNITUINAMEDEATHTOWERUPGRADE\nUnitUINameruinedelvenfishingvillage0=0,unituiname,`ruinedelvenfishingvillage0`,WESTRING_UNITUINAMERUINEDELVENFISHINGVILLAGE0\nUnitUINameruinedelvenfishingvillage1=0,unituiname,`ruinedelvenfishingvillage1`,WESTRING_UNITUINAMERUINEDELVENFISHINGVILLAGE1\nUnitUINameruinedelvenfishingvillage2=0,unituiname,`ruinedelvenfishingvillage2`,WESTRING_UNITUINAMERUINEDELVENFISHINGVILLAGE2\nUnitUINamewyverncage1=0,unituiname,`wyverncage1`,WESTRING_UNITUINAMEWYVERNCAGE1\nUnitUINamewyverncage2=0,unituiname,`wyverncage2`,WESTRING_UNITUINAMEWYVERNCAGE2\nUnitUINamechaosorcburrow=0,unituiname,`chaosorcburrow`,WESTRING_UNITUINAMECHAOSORCBURROW\nUnitUINamezoneindicator=0,unituiname,`zoneindicator`,WESTRING_UNITUINAMEZONEINDICATOR\nUnitUINamebindstonese=0,unituiname,`bindstonese`,WESTRING_UNITUINAMEBINDSTONESE\nUnitUINamebindstonesw=0,unituiname,`bindstonesw`,WESTRING_UNITUINAMEBINDSTONESW\nUnitUINamechaosspaceorc=0,unituiname,`chaosspaceorc`,WESTRING_UNITUINAMECHAOSSPACEORC\nUnitUINamehydralisk=0,unituiname,`hydralisk`,WESTRING_UNITUINAMEHYDRALISK\nUnitUINameorcjuggernaut=0,unituiname,`orcjuggernaut`,WESTRING_UNITUINAMEORCJUGGERNAUT\nUnitUINamemarine=0,unituiname,`marine`,WESTRING_UNITUINAMEMARINE\nUnitUINametheshoveler=0,unituiname,`theshoveler`,WESTRING_UNITUINAMETHESHOVELER\nUnitUINamesammycube=0,unituiname,`sammycube`,WESTRING_UNITUINAMESAMMYCUBE\nUnitUINamezergling=0,unituiname,`zergling`,WESTRING_UNITUINAMEZERGLING\nUnitUINamelichking=0,unituiname,`lichking`,WESTRING_UNITUINAMELICHKING\nRegionNull=0,region,null,WESTRING_TRIGREGION_NULL\nRaceNone=0,race,ConvertRace(0),WESTRING_TRIGRACE_NONE\nRaceOther=0,race,RACE_OTHER,WESTRING_TRIGRACE_OTHER\nRaceCreep=0,race,ConvertRace(8),WESTRING_TRIGRACE_CREEP\nRaceCommoner=0,race,ConvertRace(9),WESTRING_TRIGRACE_COMMONER\nRaceCritter=0,race,ConvertRace(10),WESTRING_TRIGRACE_CRITTER\nRaceNaga=0,race,ConvertRace(11),WESTRING_TRIGRACE_NAGA\nSaveIgnoreOptionSave=1,saveignoreoption,true,WESTRING_SAVEIGNORESAVE\nSaveIgnoreOptionIgnore=1,saveignoreoption,false,WESTRING_SAVEIGNOREIGNORE\nMapFlagFixedColors=0,mapflag,MAP_FIXED_COLORS,WESTRING_MAPFLAG_FIXEDCOLORS\nMapFlagCheats=0,mapflag,MAP_CHEATS,WESTRING_MAPFLAG_CHEATS\nMapFlagCheatsHidden=0,mapflag,MAP_CHEATS_HIDDED,WESTRING_MAPFLAG_CHEATSHIDDEN\nMapFlagLockSpeed=0,mapflag,MAP_LOCK_SPEED,WESTRING_MAPFLAG_LOCKSPEED\nMapFlagLockRandomSeed=0,mapflag,MAP_LOCK_RANDOM_SEED,WESTRING_MAPFLAG_RANDOMSEED\nMapFlagSharedAdvancedControl=0,mapflag,MAP_SHARED_ADVANCED_CONTROL,WESTRING_MAPFLAG_SHAREDADVANCEDCONTROL\nPermanentPerm=0,permanentoption,true,WESTRING_PERMANENTOPTION_PERM\nPermanentNoPerm=0,permanentoption,false,WESTRING_PERMANENTOPTION_NOPERM\nEffectTypeEffectBuff=0,effecttypebuff,EFFECT_TYPE_EFFECT,WESTRING_EFFECTTYPEOPTION_EFFECT\nEffectTypeTargetBuff=0,effecttypebuff,EFFECT_TYPE_TARGET,WESTRING_EFFECTTYPEOPTION_TARGET\nEffectTypeSpecialBuff=0,effecttypebuff,EFFECT_TYPE_SPECIAL,WESTRING_EFFECTTYPEOPTION_SPECIAL\nUnitOrderAttackItem=1,unitorderitarg,`attack`,WESTRING_UNITORDERITARG_ATTACK\nUnitOrderAttackItemOnce=1,unitorderitarg,`attackonce`,WESTRING_UNITORDERITARG_ATTACKONCE\nUnitOrderMoveItem=1,unitorderitarg,`move`,WESTRING_UNITORDERITARG_MOVE\nUnitOrderSmartItem=1,unitorderitarg,`smart`,WESTRING_UNITORDERITARG_SMART\nGameEventVictory=0,gameeventoption,EVENT_GAME_VICTORY,WESTRING_GAMEEVENTOPTION_VICTORY\nGameEventEndLevel=0,gameeventoption,EVENT_GAME_END_LEVEL,WESTRING_GAMEEVENTOPTION_ENDLEVEL\nGameEventVariableLimit=0,gameeventoption,EVENT_GAME_VARIABLE_LIMIT,WESTRING_GAMEEVENTOPTION_VARLIMIT\nGameEventStateLimit=0,gameeventoption,EVENT_GAME_STATE_LIMIT,WESTRING_GAMEEVENTOPTION_STATELIMIT\nGameEventTimerExpired=0,gameeventoption,EVENT_GAME_TIMER_EXPIRED,WESTRING_GAMEEVENTOPTION_TIMEREXPIRED\nGameEventEnterRegion=0,gameeventoption,EVENT_GAME_ENTER_REGION,WESTRING_GAMEEVENTOPTION_ENTERREGION\nGameEventLeaveRegion=0,gameeventoption,EVENT_GAME_LEAVE_REGION,WESTRING_GAMEEVENTOPTION_LEAVEREGION\nGameEventTrackableHit=0,gameeventoption,EVENT_GAME_TRACKABLE_HIT,WESTRING_GAMEEVENTOPTION_TRACKABLEHIT\nGameEventTrackableTrack=0,gameeventoption,EVENT_GAME_TRACKABLE_TRACK,WESTRING_GAMEEVENTOPTION_TRACKABLETRACK\nGameEventShowSkill=0,gameeventoption,EVENT_GAME_SHOW_SKILL,WESTRING_GAMEEVENTOPTION_SHOWSKILL\nGameEventBuildSubMenu=0,gameeventoption,EVENT_GAME_BUILD_SUBMENU,WESTRING_GAMEEVENTOPTION_BUILDMENU\nGameEventLoad=1,gameeventoption,EVENT_GAME_LOADED,\"Game Loaded\"\nGameEventSave=1,gameeventoption,EVENT_GAME_SAVE,\"Game Saved\"\nPlayerEventStateLimit=0,playereventoption,EVENT_PLAYER_STATE_LIMIT,WESTRING_PLAYEREVENTOPTION_STATELIMIT\nPlayerEventAllianceChange=0,playereventoption,EVENT_PLAYER_ALLIANCE_CHANGED,WESTRING_PLAYEREVENTOPTION_ALLIANCECHANGE\nPlayerEventDefeat=0,playereventoption,EVENT_PLAYER_DEFEAT,WESTRING_PLAYEREVENTOPTION_DEFEAT\nPlayerEventVictory=0,playereventoption,EVENT_PLAYER_VICTORY,WESTRING_PLAYEREVENTOPTION_VICTORY\nPlayerEventLeave=0,playereventoption,EVENT_PLAYER_LEAVE,WESTRING_PLAYEREVENTOPTION_LEAVE\nPlayerEventChat=0,playereventoption,EVENT_PLAYER_CHAT,WESTRING_PLAYEREVENTOPTION_CHAT\nPlayerEventEndCinematic=0,playereventoption,EVENT_PLAYER_END_CINEMATIC,WESTRING_PLAYEREVENTOPTION_ENDCINEMATIC\nPlayerEventALD=1,playereventoption,EVENT_PLAYER_ARROW_LEFT_DOWN,WESTRING_PLAYEREVENTALD\nPlayerEventALU=1,playereventoption,EVENT_PLAYER_ARROW_LEFT_UP,WESTRING_PLAYEREVENTALU\nPlayerEventARD=1,playereventoption,EVENT_PLAYER_ARROW_RIGHT_DOWN,WESTRING_PLAYEREVENTARD\nPlayerEventARU=1,playereventoption,EVENT_PLAYER_ARROW_RIGHT_UP,WESTRING_PLAYEREVENTARU\nPlayerEventADD=1,playereventoption,EVENT_PLAYER_ARROW_DOWN_DOWN,WESTRING_PLAYEREVENTADD\nPlayerEventADU=1,playereventoption,EVENT_PLAYER_ARROW_DOWN_UP,WESTRING_PLAYEREVENTADU\nPlayerEventAUD=1,playereventoption,EVENT_PLAYER_ARROW_UP_DOWN,WESTRING_PLAYEREVENTAUD\nPlayerEventAUU=1,playereventoption,EVENT_PLAYER_ARROW_UP_UP,WESTRING_PLAYEREVENTAUU\nPlayerUnitEventHidden=0,playerunitevent,EVENT_PLAYER_UNIT_HIDDEN,WESTRING_PUEVENT_HIDDEN\nPlayerUnitEventDetected=0,playerunitevent,EVENT_PLAYER_UNIT_DETECTED,WESTRING_PUEVENT_DETECTED\nUnitEventHidden=0,unitevent,EVENT_UNIT_HIDDEN,WESTRING_UEVENT_HIDDEN\nUnitEventDetected=0,unitevent,EVENT_UNIT_DETECTED,WESTRING_UEVENT_DETECTED\nUnitTypePlagued=0,unittype,UNIT_TYPE_PLAGUED,WESTRING_UNITTYPE_PLAGUED\nUnitTypeSnared=0,unittype,UNIT_TYPE_SNARED,WESTRING_UNITTYPE_SNARED\nUnitTypeStunned=0,unittype,UNIT_TYPE_STUNNED,WESTRING_UNITTYPE_STUNNED\nUnitTypePoisoned=0,unittype,UNIT_TYPE_POISONED,WESTRING_UNITTYPE_POISONED\nUnitTypePolymorphed=0,unittype,UNIT_TYPE_POLYMORPHED,WESTRING_UNITTYPE_POLYMORPHED\nUnitTypeSleeping=0,unittype,UNIT_TYPE_SLEEPING,WESTRING_UNITTYPE_SLEEPING\nUnitTypeResistant=0,unittype,UNIT_TYPE_RESISTANT,WESTRING_UNITTYPE_RESISTANT\nUnitTypeEthereal=0,unittype,UNIT_TYPE_ETHEREAL,WESTRING_UNITTYPE_ETHEREAL\nUnitTypeMagicImmune=0,unittype,UNIT_TYPE_MAGIC_IMMUNE,WESTRING_UNITTYPE_MAGICIMMUNE\nUnitTypeGiant=0,unittype,UNIT_TYPE_GIANT,WESTRING_UNITTYPE_GIANT\nUnitTypedead=0,unittype,UNIT_TYPE_DEAD,WESTRING_UNITTYPE_DEAD\nUnitTypeTauren=0,unittype,UNIT_TYPE_\nGlowcolor0=1,glowcolor,\"`Red`\",WESTRING_GLOWCOLOR0\nGlowcolor1=1,glowcolor,\"`Blue`\",WESTRING_GLOWCOLOR1\nGlowcolor2=1,glowcolor,\"`Teal`\",WESTRING_GLOWCOLOR2\nGlowcolor3=1,glowcolor,\"`Pruple`\",WESTRING_GLOWCOLOR3\nGlowcolor4=1,glowcolor,\"`Yellow`\",WESTRING_GLOWCOLOR4\nGlowcolor5=1,glowcolor,\"`Orange`\",WESTRING_GLOWCOLOR5\nGlowcolor6=1,glowcolor,\"`Green`\",WESTRING_GLOWCOLOR6\nGlowcolor7=1,glowcolor,\"`Pink`\",WESTRING_GLOWCOLOR7\nGlowcolor8=1,glowcolor,\"`Gray`\",WESTRING_GLOWCOLOR8\nGlowcolor9=1,glowcolor,\"`LightBlue`\",WESTRING_GLOWCOLOR9\nGlowcolor10=1,glowcolor,\"`DarkGreen`\",WESTRING_GLOWCOLOR10\nGlowcolor11=1,glowcolor,\"`Brown`\",WESTRING_GLOWCOLOR11\nGlowcolor12=1,glowcolor,\"`Neutral`\",WESTRING_GLOWCOLOR12\nGlowcolor13=1,glowcolor,bj_EmptyString,WESTRING_GLOWCOLOR13\nIncrease=1,increasedecreaseoption,true,WESTRING_INCREASE\nDecrease=1,increasedecreaseoption,false,WESTRING_DECREASE\nUpgrRaceHuman1=1,racepreset,0,WESTRING_UPGRRACEHUMAN1\nUpgrRaceOrc1=1,racepreset,1,WESTRING_UPGRRACEORC1\nUpgrRaceUndead1=1,racepreset,2,WESTRING_UPGRRACEUNDEAD1\nUpgrRaceNightelf1=1,racepreset,3,WESTRING_UPGRRACENIGHTELF1\nUpgrRaceHuman2=1,racepreset,4,WESTRING_UPGRRACEHUMAN2\nUpgrRaceOrc2=1,racepreset,5,WESTRING_UPGRRACEORC2\nUpgrRaceUndead2=1,racepreset,6,WESTRING_UPGRRACEUNDEAD2\nUpgrRaceNightelf2=1,racepreset,7,WESTRING_UPGRRACENIGHTELF2\nVeryBright=1,brightnesshex,\"`ff`\",WESTRING_PRESET_FF\nBright=1,brightnesshex,\"`bb`\",WESTRING_PRESET_BB\nNormalBright=1,brightnesshex,\"`99`\",WESTRING_PRESET_99\nQuiteDark=1,brightnesshex,\"`55`\",WESTRING_PRESET_55\nDark=1,brightnesshex,\"`00`\",WESTRING_PRESET_00\nColorRed=1,colorhex,\"`ff0000`\",WESTRING_PRESET_COLORRED\nColorBlue=1,colorhex,\"`0000ff`\",WESTRING_PRESET_COLORBLUE\nColorCyan=1,colorhex,\"`00ffff`\",WESTRING_PRESET_COLORCYAN\nColorPurple=1,colorhex,\"`660099`\",WESTRING_PRESET_COLORPURPLE\nColorYellow=1,colorhex,\"`ffff00`\",WESTRING_PRESET_COLORYELLOW\nColorOrange=1,colorhex,\"`ff9933`\",WESTRING_PRESET_COLORORANGE\nColorGreen=1,colorhex,\"`00ff00`\",WESTRING_PRESET_COLORGREEN\nColorPink=1,colorhex,\"`ff00ff`\",WESTRING_PRESET_COLORPINK\nColorLightGray=1,colorhex,\"`dddddd`\",WESTRING_PRESET_COLORLIGHTGRAY\nColorLightBlue=1,colorhex,\"`33ccff`\",WESTRING_PRESET_COLORLIGHTBLUE\nColorAqua=1,colorhex,\"`7fffd4`\",WESTRING_PRESET_COLORAQUA\nColorBrown=1,colorhex,\"`660000`\",WESTRING_PRESET_COLORBROWN\nColorBlack=1,colorhex,\"`000000`\",WESTRING_PRESET_COLORBLACK\nColorWhite=1,colorhex,\"`ffffff`\",WESTRING_PRESET_COLORWHITE\nColorGold=1,colorhex,\"`ffcc00`\",WESTRING_PRESET_COLORGOLD\nColorHexSNOW=1,colorhex,`FFFAFA`,WESTRING_HEXPRESET_SNOW\nColorHexGHOSTWHITE=1,colorhex,`F8F8FF`,WESTRING_HEXPRESET_GHOSTWHITE\nColorHexWHITESMOKE=1,colorhex,`F5F5F5`,WESTRING_HEXPRESET_WHITESMOKE\nColorHexGAINSBORO=1,colorhex,`DCDCDC`,WESTRING_HEXPRESET_GAINSBORO\nColorHexFLORALWHITE=1,colorhex,`FFFAF0`,WESTRING_HEXPRESET_FLORALWHITE\nColorHexOLDLACE=1,colorhex,`FDF5E6`,WESTRING_HEXPRESET_OLDLACE\nColorHexLINEN=1,colorhex,`FAF0E6`,WESTRING_HEXPRESET_LINEN\nColorHexANTIQUEWHITE=1,colorhex,`FAEBD7`,WESTRING_HEXPRESET_ANTIQUEWHITE\nColorHexPAPAYAWHIP=1,colorhex,`FFEFD5`,WESTRING_HEXPRESET_PAPAYAWHIP\nColorHexBLANCHEDALMOND=1,colorhex,`FFEBCD`,WESTRING_HEXPRESET_BLANCHEDALMOND\nColorHexBISQUE=1,colorhex,`FFE4C4`,WESTRING_HEXPRESET_BISQUE\nColorHexPEACHPUFF=1,colorhex,`FFDAB9`,WESTRING_HEXPRESET_PEACHPUFF\nColorHexNAVAJOWHITE=1,colorhex,`FFDEAD`,WESTRING_HEXPRESET_NAVAJOWHITE\nColorHexMOCCASIN=1,colorhex,`FFE4B5`,WESTRING_HEXPRESET_MOCCASIN\nColorHexCORNSILK=1,colorhex,`FFF8DC`,WESTRING_HEXPRESET_CORNSILK\nColorHexIVORY=1,colorhex,`FFFFF0`,WESTRING_HEXPRESET_IVORY\nColorHexLEMONCHIFFON=1,colorhex,`FFFACD`,WESTRING_HEXPRESET_LEMONCHIFFON\nColorHexSEASHELL=1,colorhex,`FFF5EE`,WESTRING_HEXPRESET_SEASHELL\nColorHexHONEYDEW=1,colorhex,`F0FFF0`,WESTRING_HEXPRESET_HONEYDEW\nColorHexMINTCREAM=1,colorhex,`F5FFFA`,WESTRING_HEXPRESET_MINTCREAM\nColorHexAZURE=1,colorhex,`F0FFFF`,WESTRING_HEXPRESET_AZURE\nColorHexALICEBLUE=1,colorhex,`F0F8FF`,WESTRING_HEXPRESET_ALICEBLUE\nColorHexLAVENDER=1,colorhex,`E6E6FA`,WESTRING_HEXPRESET_LAVENDER\nColorHexLAVENDERBLUSH=1,colorhex,`FFF0F5`,WESTRING_HEXPRESET_LAVENDERBLUSH\nColorHexMISTYROSE=1,colorhex,`FFE4E1`,WESTRING_HEXPRESET_MISTYROSE\nColorHexWHITE=1,colorhex,`FFFFFF`,WESTRING_HEXPRESET_WHITE\nColorHexBLACK=1,colorhex,`000000`,WESTRING_HEXPRESET_BLACK\nColorHexDARKSLATEGRAY=1,colorhex,`2F4F4F`,WESTRING_HEXPRESET_DARKSLATEGRAY\nColorHexDARKSLATEGREY=1,colorhex,`2F4F4F`,WESTRING_HEXPRESET_DARKSLATEGREY\nColorHexDIMGRAY=1,colorhex,`696969`,WESTRING_HEXPRESET_DIMGRAY\nColorHexDIMGREY=1,colorhex,`696969`,WESTRING_HEXPRESET_DIMGREY\nColorHexSLATEGRAY=1,colorhex,`708090`,WESTRING_HEXPRESET_SLATEGRAY\nColorHexSLATEGREY=1,colorhex,`708090`,WESTRING_HEXPRESET_SLATEGREY\nColorHexLIGHTSLATEGRAY=1,colorhex,`778899`,WESTRING_HEXPRESET_LIGHTSLATEGRAY\nColorHexLIGHTSLATEGREY=1,colorhex,`778899`,WESTRING_HEXPRESET_LIGHTSLATEGREY\nColorHexGRAY=1,colorhex,`BEBEBE`,WESTRING_HEXPRESET_GRAY\nColorHexGREY=1,colorhex,`BEBEBE`,WESTRING_HEXPRESET_GREY\nColorHexLIGHTGREY=1,colorhex,`D3D3D3`,WESTRING_HEXPRESET_LIGHTGREY\nColorHexLIGHTGRAY=1,colorhex,`D3D3D3`,WESTRING_HEXPRESET_LIGHTGRAY\nColorHexMIDNIGHTBLUE=1,colorhex,`191970`,WESTRING_HEXPRESET_MIDNIGHTBLUE\nColorHexNAVY=1,colorhex,`000080`,WESTRING_HEXPRESET_NAVY\nColorHexNAVYBLUE=1,colorhex,`000080`,WESTRING_HEXPRESET_NAVYBLUE\nColorHexCORNFLOWERBLUE=1,colorhex,`6495ED`,WESTRING_HEXPRESET_CORNFLOWERBLUE\nColorHexDARKSLATEBLUE=1,colorhex,`483D8B`,WESTRING_HEXPRESET_DARKSLATEBLUE\nColorHexSLATEBLUE=1,colorhex,`6A5ACD`,WESTRING_HEXPRESET_SLATEBLUE\nColorHexMEDIUMSLATEBLUE=1,colorhex,`7B68EE`,WESTRING_HEXPRESET_MEDIUMSLATEBLUE\nColorHexLIGHTSLATEBLUE=1,colorhex,`8470FF`,WESTRING_HEXPRESET_LIGHTSLATEBLUE\nColorHexMEDIUMBLUE=1,colorhex,`0000CD`,WESTRING_HEXPRESET_MEDIUMBLUE\nColorHexROYALBLUE=1,colorhex,`4169E1`,WESTRING_HEXPRESET_ROYALBLUE\nColorHexBLUE=1,colorhex,`0000FF`,WESTRING_HEXPRESET_BLUE\nColorHexDODGERBLUE=1,colorhex,`1E90FF`,WESTRING_HEXPRESET_DODGERBLUE\nColorHexDEEPSKYBLUE=1,colorhex,`00BFFF`,WESTRING_HEXPRESET_DEEPSKYBLUE\nColorHexSKYBLUE=1,colorhex,`87CEEB`,WESTRING_HEXPRESET_SKYBLUE\nColorHexLIGHTSKYBLUE=1,colorhex,`87CEFA`,WESTRING_HEXPRESET_LIGHTSKYBLUE\nColorHexSTEELBLUE=1,colorhex,`4682B4`,WESTRING_HEXPRESET_STEELBLUE\nColorHexLIGHTSTEELBLUE=1,colorhex,`B0C4DE`,WESTRING_HEXPRESET_LIGHTSTEELBLUE\nColorHexLIGHTBLUE=1,colorhex,`ADD8E6`,WESTRING_HEXPRESET_LIGHTBLUE\nColorHexPOWDERBLUE=1,colorhex,`B0E0E6`,WESTRING_HEXPRESET_POWDERBLUE\nColorHexPALETURQUOISE=1,colorhex,`AFEEEE`,WESTRING_HEXPRESET_PALETURQUOISE\nColorHexDARKTURQUOISE=1,colorhex,`00CED1`,WESTRING_HEXPRESET_DARKTURQUOISE\nColorHexMEDIUMTURQUOISE=1,colorhex,`48D1CC`,WESTRING_HEXPRESET_MEDIUMTURQUOISE\nColorHexTURQUOISE=1,colorhex,`40E0D0`,WESTRING_HEXPRESET_TURQUOISE\nColorHexCYAN=1,colorhex,`00FFFF`,WESTRING_HEXPRESET_CYAN\nColorHexLIGHTCYAN=1,colorhex,`E0FFFF`,WESTRING_HEXPRESET_LIGHTCYAN\nColorHexCADETBLUE=1,colorhex,`5F9EA0`,WESTRING_HEXPRESET_CADETBLUE\nColorHexMEDIUMAQUAMARINE=1,colorhex,`66CDAA`,WESTRING_HEXPRESET_MEDIUMAQUAMARINE\nColorHexAQUAMARINE=1,colorhex,`7FFFD4`,WESTRING_HEXPRESET_AQUAMARINE\nColorHexDARKGREEN=1,colorhex,`006400`,WESTRING_HEXPRESET_DARKGREEN\nColorHexDARKOLIVEGREEN=1,colorhex,`556B2F`,WESTRING_HEXPRESET_DARKOLIVEGREEN\nColorHexDARKSEAGREEN=1,colorhex,`8FBC8F`,WESTRING_HEXPRESET_DARKSEAGREEN\nColorHexSEAGREEN=1,colorhex,`2E8B57`,WESTRING_HEXPRESET_SEAGREEN\nColorHexMEDIUMSEAGREEN=1,colorhex,`3CB371`,WESTRING_HEXPRESET_MEDIUMSEAGREEN\nColorHexLIGHTSEAGREEN=1,colorhex,`20B2AA`,WESTRING_HEXPRESET_LIGHTSEAGREEN\nColorHexPALEGREEN=1,colorhex,`98FB98`,WESTRING_HEXPRESET_PALEGREEN\nColorHexSPRINGGREEN=1,colorhex,`00FF7F`,WESTRING_HEXPRESET_SPRINGGREEN\nColorHexLAWNGREEN=1,colorhex,`7CFC00`,WESTRING_HEXPRESET_LAWNGREEN\nColorHexGREEN=1,colorhex,`00FF00`,WESTRING_HEXPRESET_GREEN\nColorHexCHARTREUSE=1,colorhex,`7FFF00`,WESTRING_HEXPRESET_CHARTREUSE\nColorHexMEDIUMSPRINGGREEN=1,colorhex,`00FA9A`,WESTRING_HEXPRESET_MEDIUMSPRINGGREEN\nColorHexGREENYELLOW=1,colorhex,`ADFF2F`,WESTRING_HEXPRESET_GREENYELLOW\nColorHexLIMEGREEN=1,colorhex,`32CD32`,WESTRING_HEXPRESET_LIMEGREEN\nColorHexYELLOWGREEN=1,colorhex,`9ACD32`,WESTRING_HEXPRESET_YELLOWGREEN\nColorHexFORESTGREEN=1,colorhex,`228B22`,WESTRING_HEXPRESET_FORESTGREEN\nColorHexOLIVEDRAB=1,colorhex,`6B8E23`,WESTRING_HEXPRESET_OLIVEDRAB\nColorHexDARKKHAKI=1,colorhex,`BDB76B`,WESTRING_HEXPRESET_DARKKHAKI\nColorHexKHAKI=1,colorhex,`F0E68C`,WESTRING_HEXPRESET_KHAKI\nColorHexPALEGOLDENROD=1,colorhex,`EEE8AA`,WESTRING_HEXPRESET_PALEGOLDENROD\nColorHexLIGHTGOLDENRODYELLOW=1,colorhex,`FAFAD2`,WESTRING_HEXPRESET_LIGHTGOLDENRODYELLOW\nColorHexLIGHTYELLOW=1,colorhex,`FFFFE0`,WESTRING_HEXPRESET_LIGHTYELLOW\nColorHexYELLOW=1,colorhex,`FFFF00`,WESTRING_HEXPRESET_YELLOW\nColorHexGOLD=1,colorhex,`FFD700`,WESTRING_HEXPRESET_GOLD\nColorHexLIGHTGOLDENROD=1,colorhex,`EEDD82`,WESTRING_HEXPRESET_LIGHTGOLDENROD\nColorHexGOLDENROD=1,colorhex,`DAA520`,WESTRING_HEXPRESET_GOLDENROD\nColorHexDARKGOLDENROD=1,colorhex,`B8860B`,WESTRING_HEXPRESET_DARKGOLDENROD\nColorHexROSYBROWN=1,colorhex,`BC8F8F`,WESTRING_HEXPRESET_ROSYBROWN\nColorHexINDIAN=1,colorhex,`CD5C5C`,WESTRING_HEXPRESET_INDIAN\nColorHexINDIANRED=1,colorhex,`CD5C5C`,WESTRING_HEXPRESET_INDIANRED\nColorHexSADDLEBROWN=1,colorhex,`8B4513`,WESTRING_HEXPRESET_SADDLEBROWN\nColorHexSIENNA=1,colorhex,`A0522D`,WESTRING_HEXPRESET_SIENNA\nColorHexPERU=1,colorhex,`CD853F`,WESTRING_HEXPRESET_PERU\nColorHexBURLYWOOD=1,colorhex,`DEB887`,WESTRING_HEXPRESET_BURLYWOOD\nColorHexBEIGE=1,colorhex,`F5F5DC`,WESTRING_HEXPRESET_BEIGE\nColorHexWHEAT=1,colorhex,`F5DEB3`,WESTRING_HEXPRESET_WHEAT\nColorHexSANDYBROWN=1,colorhex,`F4A460`,WESTRING_HEXPRESET_SANDYBROWN\nColorHexTAN=1,colorhex,`D2B48C`,WESTRING_HEXPRESET_TAN\nColorHexCHOCOLATE=1,colorhex,`D2691E`,WESTRING_HEXPRESET_CHOCOLATE\nColorHexFIREBRICK=1,colorhex,`B22222`,WESTRING_HEXPRESET_FIREBRICK\nColorHexBROWN=1,colorhex,`A52A2A`,WESTRING_HEXPRESET_BROWN\nColorHexDARKSALMON=1,colorhex,`E9967A`,WESTRING_HEXPRESET_DARKSALMON\nColorHexSALMON=1,colorhex,`FA8072`,WESTRING_HEXPRESET_SALMON\nColorHexLIGHTSALMON=1,colorhex,`FFA07A`,WESTRING_HEXPRESET_LIGHTSALMON\nColorHexORANGE=1,colorhex,`FFA500`,WESTRING_HEXPRESET_ORANGE\nColorHexDARKORANGE=1,colorhex,`FF8C00`,WESTRING_HEXPRESET_DARKORANGE\nColorHexCORAL=1,colorhex,`FF7F50`,WESTRING_HEXPRESET_CORAL\nColorHexLIGHTCORAL=1,colorhex,`F08080`,WESTRING_HEXPRESET_LIGHTCORAL\nColorHexTOMATO=1,colorhex,`FF6347`,WESTRING_HEXPRESET_TOMATO\nColorHexORANGERED=1,colorhex,`FF4500`,WESTRING_HEXPRESET_ORANGERED\nColorHexRED=1,colorhex,`FF0000`,WESTRING_HEXPRESET_RED\nColorHexHOTPINK=1,colorhex,`FF69B4`,WESTRING_HEXPRESET_HOTPINK\nColorHexDEEPPINK=1,colorhex,`FF1493`,WESTRING_HEXPRESET_DEEPPINK\nColorHexPINK=1,colorhex,`FFC0CB`,WESTRING_HEXPRESET_PINK\nColorHexLIGHTPINK=1,colorhex,`FFB6C1`,WESTRING_HEXPRESET_LIGHTPINK\nColorHexPALEVIOLETRED=1,colorhex,`DB7093`,WESTRING_HEXPRESET_PALEVIOLETRED\nColorHexMAROON=1,colorhex,`B03060`,WESTRING_HEXPRESET_MAROON\nColorHexMEDIUMVIOLETRED=1,colorhex,`C71585`,WESTRING_HEXPRESET_MEDIUMVIOLETRED\nColorHexVIOLETRED=1,colorhex,`D02090`,WESTRING_HEXPRESET_VIOLETRED\nColorHexMAGENTA=1,colorhex,`FF00FF`,WESTRING_HEXPRESET_MAGENTA\nColorHexVIOLET=1,colorhex,`EE82EE`,WESTRING_HEXPRESET_VIOLET\nColorHexPLUM=1,colorhex,`DDA0DD`,WESTRING_HEXPRESET_PLUM\nColorHexORCHID=1,colorhex,`DA70D6`,WESTRING_HEXPRESET_ORCHID\nColorHexMEDIUMORCHID=1,colorhex,`BA55D3`,WESTRING_HEXPRESET_MEDIUMORCHID\nColorHexDARKORCHID=1,colorhex,`9932CC`,WESTRING_HEXPRESET_DARKORCHID\nColorHexDARKVIOLET=1,colorhex,`9400D3`,WESTRING_HEXPRESET_DARKVIOLET\nColorHexBLUEVIOLET=1,colorhex,`8A2BE2`,WESTRING_HEXPRESET_BLUEVIOLET\nColorHexPURPLE=1,colorhex,`A020F0`,WESTRING_HEXPRESET_PURPLE\nColorHexMEDIUMPURPLE=1,colorhex,`9370DB`,WESTRING_HEXPRESET_MEDIUMPURPLE\nColorHexTHISTLE=1,colorhex,`D8BFD8`,WESTRING_HEXPRESET_THISTLE\nColorHexDARKGREY=1,colorhex,`A9A9A9`,WESTRING_HEXPRESET_DARKGREY\nColorHexDARKGRAY=1,colorhex,`A9A9A9`,WESTRING_HEXPRESET_DARKGRAY\nColorHexDARKBLUE=1,colorhex,`00008B`,WESTRING_HEXPRESET_DARKBLUE\nColorHexDARKCYAN=1,colorhex,`008B8B`,WESTRING_HEXPRESET_DARKCYAN\nColorHexDARKMAGENTA=1,colorhex,`8B008B`,WESTRING_HEXPRESET_DARKMAGENTA\nColorHexDARKRED=1,colorhex,`8B0000`,WESTRING_HEXPRESET_DARKRED\nColorHexLIGHTGREEN=1,colorhex,`90EE90`,WESTRING_HEXPRESET_LIGHTGREEN\nAnim1=1,string,\"`stand`\",WESTRING_ANIM1\nAnim2=1,string,\"`walk`\",WESTRING_ANIM2\nAnim3=1,string,\"`attack`\",WESTRING_ANIM3\nAnim4=1,string,\"`death`\",WESTRING_ANIM4\nAnim5=1,string,\"`decay`\",WESTRING_ANIM5\nAnim6=1,string,\"`spell`\",WESTRING_ANIM6\nAnim7=1,string,\"`dissipate`\",WESTRING_ANIM7\nAnim8=1,string,\"`birth`\",WESTRING_ANIM8\nAnim9=1,string,\"`morph`\",WESTRING_ANIM9\nATag1=1,string,\"`gold`\",WESTRING_ATAG1\nATag2=1,string,\"`lumber`\",WESTRING_ATAG2\nATag3=1,string,\"`ready`\",WESTRING_ATAG3\nATag4=1,string,\"`work`\",WESTRING_ATAG4\nATag5=1,string,\"`bone`\",WESTRING_ATAG5\nATag6=1,string,\"`flesh`\",WESTRING_ATAG6\nATag7=1,string,\"`victory`\",WESTRING_ATAG7\nATag8=1,string,\"`defend`\",WESTRING_ATAG8\nATag9=1,string,\"`spell`\",WESTRING_ATAG9\nATag10=1,string,\"`one`\",WESTRING_ATAG10\nATag11=1,string,\"`two`\",WESTRING_ATAG11\nATag12=1,string,\"`channel`\",WESTRING_ATAG12\nATag13=1,string,\"`alternate`\",WESTRING_ATAG13\nATag14=1,string,\"`hit`\",WESTRING_ATAG14\nATag15=1,string,\"`slam`\",WESTRING_ATAG15\nATag16=1,string,\"`throw`\",WESTRING_ATAG16\nATag17=1,string,\"`morph`\",WESTRING_ATAG17\nATag18=1,string,\"`fast`\",WESTRING_ATAG18\nATag19=1,string,\"`cinematic`\",WESTRING_ATAG19\nATag20=1,string,\"`upgrade`\",WESTRING_ATAG20\nATag21=1,string,\"`first`\",WESTRING_ATAG21\nATag22=1,string,\"`second`\",WESTRING_ATAG22\nATag23=1,string,\"`eat tree`\",WESTRING_ATAG23\nATag24=1,string,\"`itch head`\",WESTRING_ATAG24\nATag25=1,string,\"`stretch`\",WESTRING_ATAG25\nATag26=1,string,\"`talk gesture`\",WESTRING_ATAG26\nATag27=1,string,\"`wail`\",WESTRING_ATAG27\nATag28=1,string,\"`chain lightning`\",WESTRING_ATAG28\nAnimationAttack=0,string,`attack`,WESTRING_ANIMATION_ATTACK\nAnimationAttackAlternate=0,string,`attack alternate`,WESTRING_ANIMATION_ATTACKALTERNATE\nAnimationAttackOneAlternate=0,string,`attack one alternate`,WESTRING_ANIMATION_ATTACKONEALTERNATE\nAnimationAttackDefend=0,string,`attack defend`,WESTRING_ANIMATION_ATTACKDEFEND\nAnimationAttackGold=0,string,`attack gold`,WESTRING_ANIMATION_ATTACKGOLD\nAnimationAttackLumber=0,string,`attack lumber`,WESTRING_ANIMATION_ATTACKLUMBER\nAnimationAttackRange=0,string,`attack range`,WESTRING_ANIMATION_ATTACKRANGE\nAnimationAttackSlam=0,string,`attack slam`,WESTRING_ANIMATION_ATTACKSLAM\nAnimationAttackSlamAlternate=0,string,`attack slam alternate`,WESTRING_ANIMATION_ATTACKSLAMALTERNATE\nAnimationAttackSpell=0,string,`attack spell`,WESTRING_ANIMATION_ATTACKSPELL\nAnimationAttackSpellAlternate=0,string,`attack spell alternate`,WESTRING_ANIMATION_ATTACKSPELLALTERNATE\nAnimationAttackSpellSwim=0,string,`attack spell swim`,WESTRING_ANIMATION_ATTACKSPELLSWIM\nAnimationAttackStandReadyUpgradeSecond=0,string,`attack stand ready upgrade second`,WESTRING_ANIMATION_ATTACKSTANDREADYUPGRADESECOND\nAnimationAttackSwim=0,string,`attack swim`,WESTRING_ANIMATION_ATTACKSWIM\nAnimationAttackSwimSpell=0,string,`attack swim spell`,WESTRING_ANIMATION_ATTACKSWIMSPELL\nAnimationAttackTwoAlternate=0,string,`attack two alternate`,WESTRING_ANIMATION_ATTACKTWOALTERNATE\nAnimationAttackUpgrade=0,string,`attack upgrade`,WESTRING_ANIMATION_ATTACKUPGRADE\nAnimationAttackUpgradeFirst=0,string,`attack upgrade first`,WESTRING_ANIMATION_ATTACKUPGRADEFIRST\nAnimationAttackUpgradeSecond=0,string,`attack upgrade second`,WESTRING_ANIMATION_ATTACKUPGRADESECOND\nAnimationAttackWalkStandSpin=0,string,`attack walk stand spin`,WESTRING_ANIMATION_ATTACKWALKSTANDSPIN\nAnimationBirth=0,string,`birth`,WESTRING_ANIMATION_BIRTH\nAnimationBirthAlternate=0,string,`birth alternate`,WESTRING_ANIMATION_BIRTHALTERNATE\nAnimationBirthUpgradeFirst=0,string,`birth upgrade first`,WESTRING_ANIMATION_BIRTHUPGRADEFIRST\nAnimationBirthUpgradesecond=0,string,`birth upgrade second`,WESTRING_ANIMATION_BIRTHUPGRADESECOND\nAnimationDeath=0,string,`death`,WESTRING_ANIMATION_DEATH\nAnimationDeathAlternate=0,string,`death alternate`,WESTRING_ANIMATION_DEATHALTERNATE\nAnimationDeathSpell=0,string,`death spell`,WESTRING_ANIMATION_DEATHSPELL\nAnimationDeathSwim=0,string,`death swim`,WESTRING_ANIMATION_DEATHSWIM\nAnimationDeathUpgrade=0,string,`death upgrade`,WESTRING_ANIMATION_DEATHUPGRADE\nAnimationDecayAlternate=0,string,`decay alternate`,WESTRING_ANIMATION_DECAYALTERNATE\nAnimationDecayAlternateBone=0,string,`decay alternate bone`,WESTRING_ANIMATION_DECAYALTERNATEBONE\nAnimationDecayBone=0,string,`decay bone`,WESTRING_ANIMATION_DECAYBONE\nAnimationDecayFlesh=0,string,`decay flesh`,WESTRING_ANIMATION_DECAYFLESH\nAnimationDecayFleshAlternate=0,string,`decay flesh alternate`,WESTRING_ANIMATION_DECAYFLESHALTERNATE\nAnimationDecayUpgrade=0,string,`decay upgrade`,WESTRING_ANIMATION_DECAYUPGRADE\nAnimationDissipate=0,string,`dissipate`,WESTRING_ANIMATION_DISSIPATE\nAnimationDissipateAlternate=0,string,`dissipate alternate`,WESTRING_ANIMATION_DISSIPATEALTERNATE\nAnimationDissipateSwim=0,string,`dissipate swim`,WESTRING_ANIMATION_DISSIPATESWIM\nAnimationMorph=0,string,`morph`,WESTRING_ANIMATION_MORPH\nAnimationMorphAlternate=0,string,`morph alternate`,WESTRING_ANIMATION_MORPHALTERNATE\nAnimationMorphAlternateSwim=0,string,`morph alternate swim`,WESTRING_ANIMATION_MORPHALTERNATESWIM\nAnimationMorphDefend=0,string,`morph defend`,WESTRING_ANIMATION_MORPHDEFEND\nAnimationMorphSwim=0,string,`morph swim`,WESTRING_ANIMATION_MORPHSWIM\nAnimationSpell=0,string,`spell`,WESTRING_ANIMATION_SPELL\nAnimationSpellAlternate=0,string,`spell alternate`,WESTRING_ANIMATION_SPELLALTERNATE\nAnimationSpellAttack=0,string,`spell attack`,WESTRING_ANIMATION_SPELLATTACK\nAnimationSpellChainLightning=0,string,`spell chain lightning`,WESTRING_ANIMATION_SPELLCHAINLIGHTNING\nAnimationSpellChannel=0,string,`spell channel`,WESTRING_ANIMATION_SPELLCHANNEL\nAnimationSpellEatTree=0,string,`spell eat tree`,WESTRING_ANIMATION_SPELLEATTREE\nAnimationSpellMorph=0,string,`spell morph`,WESTRING_ANIMATION_SPELLMORPH\nAnimationSpellPuke=0,string,`spell puke`,WESTRING_ANIMATION_SPELLPUKE\nAnimationSpellSlam=0,string,`spell slam`,WESTRING_ANIMATION_SPELLSLAM\nAnimationSpellSwim=0,string,`spell swim`,WESTRING_ANIMATION_SPELLSWIM\nAnimationSpellThrow=0,string,`spell throw`,WESTRING_ANIMATION_SPELLTHROW\nAnimationSpellUpgrade=0,string,`spell upgrade`,WESTRING_ANIMATION_SPELLUPGRADE\nAnimationStand=0,string,`stand`,WESTRING_ANIMATION_STAND\nAnimationStandAlternate=0,string,`stand alternate`,WESTRING_ANIMATION_STANDALTERNATE\nAnimationStandAlternateSwim=0,string,`stand alternate swim`,WESTRING_ANIMATION_STANDALTERNATESWIM\nAnimationStandAlternateUpgradeFirstSecond=0,string,`stand alternate upgrade first second`,WESTRING_ANIMATION_STANDALTERNATEUPGRADEFIRSTSECOND\nAnimationStandBirthAlternateWorkUpgradeFirstSecond=0,string,`stand birth alternate work upgrade first second`,WESTRING_ANIMATION_STANDBIRTHALTERNATEWORKUPGRADESECOND\nAnimationStandChannel=0,string,`stand channel`,WESTRING_ANIMATION_STANDCHANNEL\nAnimationStandChannelLumber=0,string,`stand channel lumber`,WESTRING_ANIMATION_STANDCHANNELLUMBER\nAnimationStandCinematic=0,string,`stand cinematic`,WESTRING_ANIMATION_STANDCINEMATIC\nAnimationStandDefend=0,string,`stand defend`,WESTRING_ANIMATION_STANDDEFEND\nAnimationStandGold=0,string,`stand gold`,WESTRING_ANIMATION_STANDGOLD\nAnimationStandHit=0,string,`stand hit`,WESTRING_ANIMATION_STANDHIT\nAnimationStandLumber=0,string,`stand lumber`,WESTRING_ANIMATION_STANDLUMBER\nAnimationStandReady=0,string,`stand ready`,WESTRING_ANIMATION_STANDREADY\nAnimationStandReadyAlternate=0,string,`stand ready alternate`,WESTRING_ANIMATION_STANDREADYALTERNATE\nAnimationStandReadyAttack=0,string,`stand ready attack`,WESTRING_ANIMATION_STANDREADYATTACK\nAnimationStandReadyGold=0,string,`stand ready gold`,WESTRING_ANIMATION_STANDREADYGOLD\nAnimationStandReadyLumber=0,string,`stand ready lumber`,WESTRING_ANIMATION_STANDREADYLUMBER\nAnimationStandReadySwim=0,string,`stand ready swim`,WESTRING_ANIMATION_STANDREADYSWIM\nAnimationStandSwim=0,string,`stand swim`,WESTRING_ANIMATION_STANDSWIM\nAnimationStandUpgrade=0,string,`stand upgrade`,WESTRING_ANIMATION_STANDUPGRADE\nAnimationStandUpgradeFirst=0,string,`stand upgrade first`,WESTRING_ANIMATION_STANDUPGRADEFIRST\nAnimationStandUpgradeFirstSecond=0,string,`stand upgrade first second`,WESTRING_ANIMATION_STANDUPGRADEFIRSTSECOND\nAnimationStandUpgradeFirstReadyAttack=0,string,`stand upgrade first ready attack`,WESTRING_ANIMATION_STANDUPGRADEFIRSTREADYATTACK\nAnimationStandUpgradeSecond=0,string,`stand upgrade second`,WESTRING_ANIMATION_STANDUPGRADESECOND\nAnimationStandUpgradeThirdAttackReady=0,string,`stand upgrade third attack ready`,WESTRING_ANIMATION_STANDUPGRADETHIRDATTACKREADY\nAnimationStandVictory=0,string,`stand victory`,WESTRING_ANIMATION_STANDVICTORY\nAnimationStandWalkAlternate=0,string,`stand walk alternate`,WESTRING_ANIMATION_STANDWALKALTERNATE\nAnimationStandWork=0,string,`stand work`,WESTRING_ANIMATION_STANDWORK\nAnimationStandWorkAlternate=0,string,`stand work alternate`,WESTRING_ANIMATION_STANDWORKALTERNATE\nAnimationStandWorkGold=0,string,`stand work gold`,WESTRING_ANIMATION_STANDWORKGOLD\nAnimationStandWorkLumber=0,string,`stand work lumber`,WESTRING_ANIMATION_STANDWORKLUMBER\nAnimationStandWorkSwim=0,string,`stand work swim`,WESTRING_ANIMATION_STANDWORKSWIM\nAnimationStandWorkUpgradeFirst=0,string,`stand work upgrade first`,WESTRING_ANIMATION_STANDWORKUPGRADEFIRST\nAnimationStandWorkUpgradeSecond=0,string,`stand work upgrade second`,WESTRING_ANIMATION_STANDWORKUPGRADESECOND\nAnimationWalk=0,string,`walk`,WESTRING_ANIMATION_WALK\nAnimationWalkAlternate=0,string,`walk alternate`,WESTRING_ANIMATION_WALKALTERNATE\nAnimationWalkChannel=0,string,`walk channel`,WESTRING_ANIMATION_WALKCHANNEL\nAnimationWalkChannelFast=0,string,`walk channel fast`,WESTRING_ANIMATION_WALKCHANNELFAST\nAnimationWalkDefend=0,string,`walk defend`,WESTRING_ANIMATION_WALKDEFEND\nAnimationWalkFast=0,string,`walk fast`,WESTRING_ANIMATION_WALKFAST\nAnimationWalkGold=0,string,`walk gold`,WESTRING_ANIMATION_WALKGOLD\nAnimationWalkLumber=0,string,`walk lumber`,WESTRING_ANIMATION_WALKLUMBER\nAnimationWalkSwim=0,string,`walk swim`,WESTRING_ANIMATION_WALKSWIM\nAnimationWalkUpgrade=0,string,`walk upgrade`,WESTRING_ANIMATION_WALKUPGRADE\nHexPresetSNOW=0,string,`c|FFFAFA`,WESTRING_HEXPRESET_SNOW\nHexPresetGHOSTWHITE=0,string,`c|F8F8FF`,WESTRING_HEXPRESET_GHOSTWHITE\nHexPresetWHITESMOKE=0,string,`c|F5F5F5`,WESTRING_HEXPRESET_WHITESMOKE\nHexPresetGAINSBORO=0,string,`c|DCDCDC`,WESTRING_HEXPRESET_GAINSBORO\nHexPresetFLORALWHITE=0,string,`c|FFFAF0`,WESTRING_HEXPRESET_FLORALWHITE\nHexPresetOLDLACE=0,string,`c|FDF5E6`,WESTRING_HEXPRESET_OLDLACE\nHexPresetLINEN=0,string,`c|FAF0E6`,WESTRING_HEXPRESET_LINEN\nHexPresetANTIQUEWHITE=0,string,`c|FAEBD7`,WESTRING_HEXPRESET_ANTIQUEWHITE\nHexPresetPAPAYAWHIP=0,string,`c|FFEFD5`,WESTRING_HEXPRESET_PAPAYAWHIP\nHexPresetBLANCHEDALMOND=0,string,`c|FFEBCD`,WESTRING_HEXPRESET_BLANCHEDALMOND\nHexPresetBISQUE=0,string,`c|FFE4C4`,WESTRING_HEXPRESET_BISQUE\nHexPresetPEACHPUFF=0,string,`c|FFDAB9`,WESTRING_HEXPRESET_PEACHPUFF\nHexPresetNAVAJOWHITE=0,string,`c|FFDEAD`,WESTRING_HEXPRESET_NAVAJOWHITE\nHexPresetMOCCASIN=0,string,`c|FFE4B5`,WESTRING_HEXPRESET_MOCCASIN\nHexPresetCORNSILK=0,string,`c|FFF8DC`,WESTRING_HEXPRESET_CORNSILK\nHexPresetIVORY=0,string,`c|FFFFF0`,WESTRING_HEXPRESET_IVORY\nHexPresetLEMONCHIFFON=0,string,`c|FFFACD`,WESTRING_HEXPRESET_LEMONCHIFFON\nHexPresetSEASHELL=0,string,`c|FFF5EE`,WESTRING_HEXPRESET_SEASHELL\nHexPresetHONEYDEW=0,string,`c|F0FFF0`,WESTRING_HEXPRESET_HONEYDEW\nHexPresetMINTCREAM=0,string,`c|F5FFFA`,WESTRING_HEXPRESET_MINTCREAM\nHexPresetAZURE=0,string,`c|F0FFFF`,WESTRING_HEXPRESET_AZURE\nHexPresetALICEBLUE=0,string,`c|F0F8FF`,WESTRING_HEXPRESET_ALICEBLUE\nHexPresetLAVENDER=0,string,`c|E6E6FA`,WESTRING_HEXPRESET_LAVENDER\nHexPresetLAVENDERBLUSH=0,string,`c|FFF0F5`,WESTRING_HEXPRESET_LAVENDERBLUSH\nHexPresetMISTYROSE=0,string,`c|FFE4E1`,WESTRING_HEXPRESET_MISTYROSE\nHexPresetWHITE=0,string,`c|FFFFFF`,WESTRING_HEXPRESET_WHITE\nHexPresetBLACK=0,string,`c|000000`,WESTRING_HEXPRESET_BLACK\nHexPresetDARKSLATEGRAY=0,string,`c|2F4F4F`,WESTRING_HEXPRESET_DARKSLATEGRAY\nHexPresetDARKSLATEGREY=0,string,`c|2F4F4F`,WESTRING_HEXPRESET_DARKSLATEGREY\nHexPresetDIMGRAY=0,string,`c|696969`,WESTRING_HEXPRESET_DIMGRAY\nHexPresetDIMGREY=0,string,`c|696969`,WESTRING_HEXPRESET_DIMGREY\nHexPresetSLATEGRAY=0,string,`c|708090`,WESTRING_HEXPRESET_SLATEGRAY\nHexPresetSLATEGREY=0,string,`c|708090`,WESTRING_HEXPRESET_SLATEGREY\nHexPresetLIGHTSLATEGRAY=0,string,`c|778899`,WESTRING_HEXPRESET_LIGHTSLATEGRAY\nHexPresetLIGHTSLATEGREY=0,string,`c|778899`,WESTRING_HEXPRESET_LIGHTSLATEGREY\nHexPresetGRAY=0,string,`c|BEBEBE`,WESTRING_HEXPRESET_GRAY\nHexPresetGREY=0,string,`c|BEBEBE`,WESTRING_HEXPRESET_GREY\nHexPresetLIGHTGREY=0,string,`c|D3D3D3`,WESTRING_HEXPRESET_LIGHTGREY\nHexPresetLIGHTGRAY=0,string,`c|D3D3D3`,WESTRING_HEXPRESET_LIGHTGRAY\nHexPresetMIDNIGHTBLUE=0,string,`c|191970`,WESTRING_HEXPRESET_MIDNIGHTBLUE\nHexPresetNAVY=0,string,`c|000080`,WESTRING_HEXPRESET_NAVY\nHexPresetNAVYBLUE=0,string,`c|000080`,WESTRING_HEXPRESET_NAVYBLUE\nHexPresetCORNFLOWERBLUE=0,string,`c|6495ED`,WESTRING_HEXPRESET_CORNFLOWERBLUE\nHexPresetDARKSLATEBLUE=0,string,`c|483D8B`,WESTRING_HEXPRESET_DARKSLATEBLUE\nHexPresetSLATEBLUE=0,string,`c|6A5ACD`,WESTRING_HEXPRESET_SLATEBLUE\nHexPresetMEDIUMSLATEBLUE=0,string,`c|7B68EE`,WESTRING_HEXPRESET_MEDIUMSLATEBLUE\nHexPresetLIGHTSLATEBLUE=0,string,`c|8470FF`,WESTRING_HEXPRESET_LIGHTSLATEBLUE\nHexPresetMEDIUMBLUE=0,string,`c|0000CD`,WESTRING_HEXPRESET_MEDIUMBLUE\nHexPresetROYALBLUE=0,string,`c|4169E1`,WESTRING_HEXPRESET_ROYALBLUE\nHexPresetBLUE=0,string,`c|0000FF`,WESTRING_HEXPRESET_BLUE\nHexPresetDODGERBLUE=0,string,`c|1E90FF`,WESTRING_HEXPRESET_DODGERBLUE\nHexPresetDEEPSKYBLUE=0,string,`c|00BFFF`,WESTRING_HEXPRESET_DEEPSKYBLUE\nHexPresetSKYBLUE=0,string,`c|87CEEB`,WESTRING_HEXPRESET_SKYBLUE\nHexPresetLIGHTSKYBLUE=0,string,`c|87CEFA`,WESTRING_HEXPRESET_LIGHTSKYBLUE\nHexPresetSTEELBLUE=0,string,`c|4682B4`,WESTRING_HEXPRESET_STEELBLUE\nHexPresetLIGHTSTEELBLUE=0,string,`c|B0C4DE`,WESTRING_HEXPRESET_LIGHTSTEELBLUE\nHexPresetLIGHTBLUE=0,string,`c|ADD8E6`,WESTRING_HEXPRESET_LIGHTBLUE\nHexPresetPOWDERBLUE=0,string,`c|B0E0E6`,WESTRING_HEXPRESET_POWDERBLUE\nHexPresetPALETURQUOISE=0,string,`c|AFEEEE`,WESTRING_HEXPRESET_PALETURQUOISE\nHexPresetDARKTURQUOISE=0,string,`c|00CED1`,WESTRING_HEXPRESET_DARKTURQUOISE\nHexPresetMEDIUMTURQUOISE=0,string,`c|48D1CC`,WESTRING_HEXPRESET_MEDIUMTURQUOISE\nHexPresetTURQUOISE=0,string,`c|40E0D0`,WESTRING_HEXPRESET_TURQUOISE\nHexPresetCYAN=0,string,`c|00FFFF`,WESTRING_HEXPRESET_CYAN\nHexPresetLIGHTCYAN=0,string,`c|E0FFFF`,WESTRING_HEXPRESET_LIGHTCYAN\nHexPresetCADETBLUE=0,string,`c|5F9EA0`,WESTRING_HEXPRESET_CADETBLUE\nHexPresetMEDIUMAQUAMARINE=0,string,`c|66CDAA`,WESTRING_HEXPRESET_MEDIUMAQUAMARINE\nHexPresetAQUAMARINE=0,string,`c|7FFFD4`,WESTRING_HEXPRESET_AQUAMARINE\nHexPresetDARKGREEN=0,string,`c|006400`,WESTRING_HEXPRESET_DARKGREEN\nHexPresetDARKOLIVEGREEN=0,string,`c|556B2F`,WESTRING_HEXPRESET_DARKOLIVEGREEN\nHexPresetDARKSEAGREEN=0,string,`c|8FBC8F`,WESTRING_HEXPRESET_DARKSEAGREEN\nHexPresetSEAGREEN=0,string,`c|2E8B57`,WESTRING_HEXPRESET_SEAGREEN\nHexPresetMEDIUMSEAGREEN=0,string,`c|3CB371`,WESTRING_HEXPRESET_MEDIUMSEAGREEN\nHexPresetLIGHTSEAGREEN=0,string,`c|20B2AA`,WESTRING_HEXPRESET_LIGHTSEAGREEN\nHexPresetPALEGREEN=0,string,`c|98FB98`,WESTRING_HEXPRESET_PALEGREEN\nHexPresetSPRINGGREEN=0,string,`c|00FF7F`,WESTRING_HEXPRESET_SPRINGGREEN\nHexPresetLAWNGREEN=0,string,`c|7CFC00`,WESTRING_HEXPRESET_LAWNGREEN\nHexPresetGREEN=0,string,`c|00FF00`,WESTRING_HEXPRESET_GREEN\nHexPresetCHARTREUSE=0,string,`c|7FFF00`,WESTRING_HEXPRESET_CHARTREUSE\nHexPresetMEDIUMSPRINGGREEN=0,string,`c|00FA9A`,WESTRING_HEXPRESET_MEDIUMSPRINGGREEN\nHexPresetGREENYELLOW=0,string,`c|ADFF2F`,WESTRING_HEXPRESET_GREENYELLOW\nHexPresetLIMEGREEN=0,string,`c|32CD32`,WESTRING_HEXPRESET_LIMEGREEN\nHexPresetYELLOWGREEN=0,string,`c|9ACD32`,WESTRING_HEXPRESET_YELLOWGREEN\nHexPresetFORESTGREEN=0,string,`c|228B22`,WESTRING_HEXPRESET_FORESTGREEN\nHexPresetOLIVEDRAB=0,string,`c|6B8E23`,WESTRING_HEXPRESET_OLIVEDRAB\nHexPresetDARKKHAKI=0,string,`c|BDB76B`,WESTRING_HEXPRESET_DARKKHAKI\nHexPresetKHAKI=0,string,`c|F0E68C`,WESTRING_HEXPRESET_KHAKI\nHexPresetPALEGOLDENROD=0,string,`c|EEE8AA`,WESTRING_HEXPRESET_PALEGOLDENROD\nHexPresetLIGHTGOLDENRODYELLOW=0,string,`c|FAFAD2`,WESTRING_HEXPRESET_LIGHTGOLDENRODYELLOW\nHexPresetLIGHTYELLOW=0,string,`c|FFFFE0`,WESTRING_HEXPRESET_LIGHTYELLOW\nHexPresetYELLOW=0,string,`c|FFFF00`,WESTRING_HEXPRESET_YELLOW\nHexPresetGOLD=0,string,`c|FFD700`,WESTRING_HEXPRESET_GOLD\nHexPresetLIGHTGOLDENROD=0,string,`c|EEDD82`,WESTRING_HEXPRESET_LIGHTGOLDENROD\nHexPresetGOLDENROD=0,string,`c|DAA520`,WESTRING_HEXPRESET_GOLDENROD\nHexPresetDARKGOLDENROD=0,string,`c|B8860B`,WESTRING_HEXPRESET_DARKGOLDENROD\nHexPresetROSYBROWN=0,string,`c|BC8F8F`,WESTRING_HEXPRESET_ROSYBROWN\nHexPresetINDIAN=0,string,`c|CD5C5C`,WESTRING_HEXPRESET_INDIAN\nHexPresetINDIANRED=0,string,`c|CD5C5C`,WESTRING_HEXPRESET_INDIANRED\nHexPresetSADDLEBROWN=0,string,`c|8B4513`,WESTRING_HEXPRESET_SADDLEBROWN\nHexPresetSIENNA=0,string,`c|A0522D`,WESTRING_HEXPRESET_SIENNA\nHexPresetPERU=0,string,`c|CD853F`,WESTRING_HEXPRESET_PERU\nHexPresetBURLYWOOD=0,string,`c|DEB887`,WESTRING_HEXPRESET_BURLYWOOD\nHexPresetBEIGE=0,string,`c|F5F5DC`,WESTRING_HEXPRESET_BEIGE\nHexPresetWHEAT=0,string,`c|F5DEB3`,WESTRING_HEXPRESET_WHEAT\nHexPresetSANDYBROWN=0,string,`c|F4A460`,WESTRING_HEXPRESET_SANDYBROWN\nHexPresetTAN=0,string,`c|D2B48C`,WESTRING_HEXPRESET_TAN\nHexPresetCHOCOLATE=0,string,`c|D2691E`,WESTRING_HEXPRESET_CHOCOLATE\nHexPresetFIREBRICK=0,string,`c|B22222`,WESTRING_HEXPRESET_FIREBRICK\nHexPresetBROWN=0,string,`c|A52A2A`,WESTRING_HEXPRESET_BROWN\nHexPresetDARKSALMON=0,string,`c|E9967A`,WESTRING_HEXPRESET_DARKSALMON\nHexPresetSALMON=0,string,`c|FA8072`,WESTRING_HEXPRESET_SALMON\nHexPresetLIGHTSALMON=0,string,`c|FFA07A`,WESTRING_HEXPRESET_LIGHTSALMON\nHexPresetORANGE=0,string,`c|FFA500`,WESTRING_HEXPRESET_ORANGE\nHexPresetDARKORANGE=0,string,`c|FF8C00`,WESTRING_HEXPRESET_DARKORANGE\nHexPresetCORAL=0,string,`c|FF7F50`,WESTRING_HEXPRESET_CORAL\nHexPresetLIGHTCORAL=0,string,`c|F08080`,WESTRING_HEXPRESET_LIGHTCORAL\nHexPresetTOMATO=0,string,`c|FF6347`,WESTRING_HEXPRESET_TOMATO\nHexPresetORANGERED=0,string,`c|FF4500`,WESTRING_HEXPRESET_ORANGERED\nHexPresetRED=0,string,`c|FF0000`,WESTRING_HEXPRESET_RED\nHexPresetHOTPINK=0,string,`c|FF69B4`,WESTRING_HEXPRESET_HOTPINK\nHexPresetDEEPPINK=0,string,`c|FF1493`,WESTRING_HEXPRESET_DEEPPINK\nHexPresetPINK=0,string,`c|FFC0CB`,WESTRING_HEXPRESET_PINK\nHexPresetLIGHTPINK=0,string,`c|FFB6C1`,WESTRING_HEXPRESET_LIGHTPINK\nHexPresetPALEVIOLETRED=0,string,`c|DB7093`,WESTRING_HEXPRESET_PALEVIOLETRED\nHexPresetMAROON=0,string,`c|B03060`,WESTRING_HEXPRESET_MAROON\nHexPresetMEDIUMVIOLETRED=0,string,`c|C71585`,WESTRING_HEXPRESET_MEDIUMVIOLETRED\nHexPresetVIOLETRED=0,string,`c|D02090`,WESTRING_HEXPRESET_VIOLETRED\nHexPresetMAGENTA=0,string,`c|FF00FF`,WESTRING_HEXPRESET_MAGENTA\nHexPresetVIOLET=0,string,`c|EE82EE`,WESTRING_HEXPRESET_VIOLET\nHexPresetPLUM=0,string,`c|DDA0DD`,WESTRING_HEXPRESET_PLUM\nHexPresetORCHID=0,string,`c|DA70D6`,WESTRING_HEXPRESET_ORCHID\nHexPresetMEDIUMORCHID=0,string,`c|BA55D3`,WESTRING_HEXPRESET_MEDIUMORCHID\nHexPresetDARKORCHID=0,string,`c|9932CC`,WESTRING_HEXPRESET_DARKORCHID\nHexPresetDARKVIOLET=0,string,`c|9400D3`,WESTRING_HEXPRESET_DARKVIOLET\nHexPresetBLUEVIOLET=0,string,`c|8A2BE2`,WESTRING_HEXPRESET_BLUEVIOLET\nHexPresetPURPLE=0,string,`c|A020F0`,WESTRING_HEXPRESET_PURPLE\nHexPresetMEDIUMPURPLE=0,string,`c|9370DB`,WESTRING_HEXPRESET_MEDIUMPURPLE\nHexPresetTHISTLE=0,string,`c|D8BFD8`,WESTRING_HEXPRESET_THISTLE\nHexPresetDARKGREY=0,string,`c|A9A9A9`,WESTRING_HEXPRESET_DARKGREY\nHexPresetDARKGRAY=0,string,`c|A9A9A9`,WESTRING_HEXPRESET_DARKGRAY\nHexPresetDARKBLUE=0,string,`c|00008B`,WESTRING_HEXPRESET_DARKBLUE\nHexPresetDARKCYAN=0,string,`c|008B8B`,WESTRING_HEXPRESET_DARKCYAN\nHexPresetDARKMAGENTA=0,string,`c|8B008B`,WESTRING_HEXPRESET_DARKMAGENTA\nHexPresetDARKRED=0,string,`c|8B0000`,WESTRING_HEXPRESET_DARKRED\nHexPresetLIGHTGREEN=0,string,`c|90EE90`,WESTRING_HEXPRESET_LIGHTGREEN\nHexPresetEndColor=0,string,`r|`,WESTRING_HEXPRESET_ENDCOLOR\nLargeSmallOptionLarge=1,largesmalloption,true,WESTRING_LARGESMALLOPTIONLARGE\nLargeSmallOptionSmall=1,largesmalloption,false,WESTRING_LARGESMALLOPTIONSMALL\nBuildableOptionBuildable=1,buildableoption,false,WESTRING_BUILDABLEOPTIONBUILDABLE\nBuildableOptionUnbuildable=1,buildableoption,true,WESTRING_BUILDABLEOPTIONUNBUILDABLE\nDropOptionRemove=1,dropoption,true,WESTRING_DROPOPTIONREMOVE\nDropOptionDrop=1,dropoption,false,WESTRING_DROPOPTIONDROP\nUnitEventSummon=0,unitevent,EVENT_UNIT_SUMMON,WESTRING_UEVENT_SUMMON\nPlayer00=0,player,Player(0),WESTRING_PLAYER_00\nPlayer01=0,player,Player(1),WESTRING_PLAYER_01\nPlayer02=0,player,Player(2),WESTRING_PLAYER_02\nPlayer03=0,player,Player(3),WESTRING_PLAYER_03\nPlayer04=0,player,Player(4),WESTRING_PLAYER_04\nPlayer05=0,player,Player(5),WESTRING_PLAYER_05\nPlayer06=0,player,Player(6),WESTRING_PLAYER_06\nPlayer07=0,player,Player(7),WESTRING_PLAYER_07\nPlayer08=0,player,Player(8),WESTRING_PLAYER_08\nPlayer09=0,player,Player(9),WESTRING_PLAYER_09\nPlayer10=0,player,Player(10),WESTRING_PLAYER_10\nPlayer11=0,player,Player(11),WESTRING_PLAYER_11\nPlayerNA=0,player,Player(PLAYER_NEUTRAL_AGGRESSIVE),WESTRING_PLAYER_NA\nPlayerNV=0,player,Player(bj_PLAYER_NEUTRAL_VICTIM),WESTRING_PLAYER_NV\nPlayerNE=0,player,Player(bj_PLAYER_NEUTRAL_EXTRA),WESTRING_PLAYER_NE\nPlayerNP=0,player,Player(PLAYER_NEUTRAL_PASSIVE),WESTRING_PLAYER_NP\nForce00=0,force,bj_FORCE_PLAYER[0],WESTRING_FORCE_00\nForce01=0,force,bj_FORCE_PLAYER[1],WESTRING_FORCE_01\nForce02=0,force,bj_FORCE_PLAYER[2],WESTRING_FORCE_02\nForce03=0,force,bj_FORCE_PLAYER[3],WESTRING_FORCE_03\nForce04=0,force,bj_FORCE_PLAYER[4],WESTRING_FORCE_04\nForce05=0,force,bj_FORCE_PLAYER[5],WESTRING_FORCE_05\nForce06=0,force,bj_FORCE_PLAYER[6],WESTRING_FORCE_06\nForce07=0,force,bj_FORCE_PLAYER[7],WESTRING_FORCE_07\nForce08=0,force,bj_FORCE_PLAYER[8],WESTRING_FORCE_08\nForce09=0,force,bj_FORCE_PLAYER[9],WESTRING_FORCE_09\nForce10=0,force,bj_FORCE_PLAYER[10],WESTRING_FORCE_10\nForce11=0,force,bj_FORCE_PLAYER[11],WESTRING_FORCE_11\nForceNA=0,force,bj_FORCE_PLAYER[PLAYER_NEUTRAL_AGGRESSIVE],WESTRING_FORCE_NA\nForceNV=0,force,bj_FORCE_PLAYER[bj_PLAYER_NEUTRAL_VICTIM],WESTRING_FORCE_NV\nForceNE=0,force,bj_FORCE_PLAYER[bj_PLAYER_NEUTRAL_EXTRA],WESTRING_FORCE_NE\nForceNP=0,force,bj_FORCE_PLAYER[PLAYER_NEUTRAL_PASSIVE],WESTRING_FORCE_NP\nColor00=0,playercolor,PLAYER_COLOR_RED,WESTRING_UNITCOLOR_00\nColor01=0,playercolor,PLAYER_COLOR_BLUE,WESTRING_UNITCOLOR_01\nColor02=0,playercolor,PLAYER_COLOR_CYAN,WESTRING_UNITCOLOR_02\nColor03=0,playercolor,PLAYER_COLOR_PURPLE,WESTRING_UNITCOLOR_03\nColor04=0,playercolor,PLAYER_COLOR_YELLOW,WESTRING_UNITCOLOR_04\nColor05=0,playercolor,PLAYER_COLOR_ORANGE,WESTRING_UNITCOLOR_05\nColor06=0,playercolor,PLAYER_COLOR_GREEN,WESTRING_UNITCOLOR_06\nColor07=0,playercolor,PLAYER_COLOR_PINK,WESTRING_UNITCOLOR_07\nColor08=0,playercolor,PLAYER_COLOR_LIGHT_GRAY,WESTRING_UNITCOLOR_08\nColor09=0,playercolor,PLAYER_COLOR_LIGHT_BLUE,WESTRING_UNITCOLOR_09\nColor10=0,playercolor,PLAYER_COLOR_AQUA,WESTRING_UNITCOLOR_10\nColor11=0,playercolor,PLAYER_COLOR_BROWN,WESTRING_UNITCOLOR_11\nColor12=1,playercolor,ConvertPlayerColor(12),WESTRING_UNITCOLOR_12\nRaceHuman=0,race,RACE_HUMAN,WESTRING_TRIGRACE_HUMAN\nRaceOrc=0,race,RACE_ORC,WESTRING_TRIGRACE_ORC\nRaceUndead=0,race,RACE_UNDEAD,WESTRING_TRIGRACE_UNDEAD\nRaceNightElf=0,race,RACE_NIGHTELF,WESTRING_TRIGRACE_NIGHTELF\nRaceDemon=0,race,RACE_DEMON,WESTRING_TRIGRACE_DEMON\nItemTypeAny=1,itemtype,ITEM_TYPE_ANY,WESTRING_ITEMTYPE_ANY\nItemTypePermanent=1,itemtype,ITEM_TYPE_PERMANENT,WESTRING_ITEMTYPE_PERMANENT\nItemTypeCharged=1,itemtype,ITEM_TYPE_CHARGED,WESTRING_ITEMTYPE_CHARGED\nItemTypePowerup=1,itemtype,ITEM_TYPE_POWERUP,WESTRING_ITEMTYPE_POWERUP\nItemTypeArtifact=1,itemtype,ITEM_TYPE_ARTIFACT,WESTRING_ITEMTYPE_ARTIFACT\nItemTypePurchasable=1,itemtype,ITEM_TYPE_PURCHASABLE,WESTRING_ITEMTYPE_PURCHASABLE\nItemTypeCampaign=1,itemtype,ITEM_TYPE_CAMPAIGN,WESTRING_ITEMTYPE_CAMPAIGN\nItemTypeMiscellaneous=1,itemtype,ITEM_TYPE_MISCELLANEOUS,WESTRING_ITEMTYPE_MISCELLANEOUS\nItemTypeUnknown=1,itemtype,ITEM_TYPE_UNKNOWN,WESTRING_ITEMTYPE_UNKNOWN\nUnitNull=0,unit,null,WESTRING_TRIGUNIT_NULL\nUnitTypeNull=0,unitcode,0,WESTRING_TRIGUNITTYPE_NULL\nItemNull=0,item,null,WESTRING_TRIGITEM_NULL\nDestructableNull=0,destructable,null,WESTRING_TRIGDESTRUCTABLE_NULL\nRectNull=0,rect,null,WESTRING_TRIGRECT_NULL\nSoundNull=0,sound,null,WESTRING_TRIGSOUND_NULL\nMusicFileMusic=0,musicfile,`music`,WESTRING_TRIGMUSICFILE_MUSIC\nLimitOpEqual=0,limitop,EQUAL,WESTRING_LIMITOP_EQUAL\nLimitOpNotEqual=0,limitop,NOT_EQUAL,WESTRING_LIMITOP_NOTEQUAL\nLimitOpLessThan=0,limitop,LESS_THAN,WESTRING_LIMITOP_LESSTHAN\nLimitOpLessThanOrEqual=0,limitop,LESS_THAN_OR_EQUAL,WESTRING_LIMITOP_LESSTHANOREQUAL\nLimitOpGreaterThan=0,limitop,GREATER_THAN,WESTRING_LIMITOP_GREATERTHAN\nLimitOpGreaterThanOrEqual=0,limitop,GREATER_THAN_OR_EQUAL,WESTRING_LIMITOP_GREATERTHANOREQUAL\nGameResultWin=0,playergameresult,PLAYER_GAME_RESULT_VICTORY,WESTRING_VICTORY\nGameResultLose=0,playergameresult,PLAYER_GAME_RESULT_DEFEAT,WESTRING_DEFEAT\nGameResultDraw=0,playergameresult,PLAYER_GAME_RESULT_TIE,WESTRING_DRAW\nMapFlagUseHandicaps=0,mapflag,MAP_USE_HANDICAPS,WESTRING_MAPFLAG_USEHANDICAPS\nMapFlagObservers=0,mapflag,MAP_OBSERVERS,WESTRING_MAPFLAG_OBSERVERS\nMapFlagObserversChat=0,mapflag,MAP_OBSERVERS_ON_DEATH,WESTRING_MAPFLAG_OBSERVERSONDEATH\nMapFlagResourceTradingLock=0,mapflag,MAP_LOCK_RESOURCE_TRADING,WESTRING_MAPFLAG_RESOURCETRADINGLOCK\nMapFlagResourceTradingAllies=0,mapflag,MAP_RESOURCE_TRADING_ALLIES_ONLY,WESTRING_MAPFLAG_RESOURCETRADINGALLIES\nMapFlagAllianceChangesLock=0,mapflag,MAP_LOCK_ALLIANCE_CHANGES,WESTRING_MAPFLAG_ALLIANCECHANGESLOCK\nMapFlagAllianceChangesHidden=0,mapflag,MAP_ALLIANCE_CHANGES_HIDDEN,WESTRING_MAPFLAG_ALLIANCECHANGESHIDDEN\nMapFlagMapReloaded=1,mapflag,MAP_RELOADED,WESTRING_MAPFLAG_MAPRELOADED\nMapFlagRandomHeroes=1,mapflag,MAP_RANDOM_HERO,WESTRING_MAPFLAG_RANDOM_HERO\nMapFlagRandomRaces=1,mapflag,MAP_RANDOM_RACES,WESTRING_MAPFLAG_RANDOM_RACES\nMapFlagFogHideTerrain=1,mapflag,MAP_FOG_HIDE_TERRAIN,WESTRING_MAPFLAG_FOG_HIDE_TERRAIN\nMapFlagFogMapExplored=1,mapflag,MAP_FOG_MAP_EXPLORED,WESTRING_MAPFLAG_FOG_MAP_EXPLORED\nMapFlagFogAlwaysVisible=1,mapflag,MAP_FOG_ALWAYS_VISIBLE,WESTRING_MAPFLAG_FOG_ALWAYS_VISIBLE\nPlayerStateGold=0,playerstate,PLAYER_STATE_RESOURCE_GOLD,WESTRING_PSTATE_GOLD\nPlayerStateLumber=0,playerstate,PLAYER_STATE_RESOURCE_LUMBER,WESTRING_PSTATE_LUMBER\nPlayerStateHeroTokens=0,playerstate,PLAYER_STATE_RESOURCE_HERO_TOKENS,WESTRING_PSTATE_HEROTOKENS\nPlayerStateGoldUpkeepRate=0,playerstate,PLAYER_STATE_GOLD_UPKEEP_RATE,WESTRING_PSTATE_UPKEEPGOLD\nPlayerStateLumberUpkeepRate=0,playerstate,PLAYER_STATE_LUMBER_UPKEEP_RATE,WESTRING_PSTATE_UPKEEPLUMBER\nPlayerStateGoldGathered=0,playerstate,PLAYER_STATE_GOLD_GATHERED,WESTRING_PSTATE_GOLDGATHERED\nPlayerStateLumberGathered=0,playerstate,PLAYER_STATE_LUMBER_GATHERED,WESTRING_PSTATE_LUMBER_GATHERED\nPlayerStateFoodUsed=0,playerstate,PLAYER_STATE_RESOURCE_FOOD_USED,WESTRING_PSTATE_FOODUSED\nPlayerStateFoodCap=0,playerstate,PLAYER_STATE_RESOURCE_FOOD_CAP,WESTRING_PSTATE_FOODCAP\nPlayerStateFoodLimit=0,playerstate,PLAYER_STATE_FOOD_CAP_CEILING,WESTRING_PSTATE_FOODCAPLIMIT\nPlayerStateGameResult=0,playerstate,PLAYER_STATE_GAME_RESULT,WESTRING_PSTATE_GAMERESULT\nPlayerScoreUnitsTrained=1,playerscore,PLAYER_SCORE_UNITS_TRAINED,WESTRING_PSCORE_UNITSTRAINED\nPlayerScoreUnitsKilled=1,playerscore,PLAYER_SCORE_UNITS_KILLED,WESTRING_PSCORE_UNITSKILLED\nPlayerScoreStructBuilt=1,playerscore,PLAYER_SCORE_STRUCT_BUILT,WESTRING_PSCORE_STRUCTBUILT\nPlayerScoreStructRazed=1,playerscore,PLAYER_SCORE_STRUCT_RAZED,WESTRING_PSCORE_STRUCTRAZED\nPlayerScoreTechPercent=1,playerscore,PLAYER_SCORE_TECH_PERCENT,WESTRING_PSCORE_TECHPERCENT\nPlayerScoreFoodProd=1,playerscore,PLAYER_SCORE_FOOD_MAXPROD,WESTRING_PSCORE_FOODPROD\nPlayerScoreFoodUsed=1,playerscore,PLAYER_SCORE_FOOD_MAXUSED,WESTRING_PSCORE_FOODUSED\nPlayerScoreHeroesKilled=1,playerscore,PLAYER_SCORE_HEROES_KILLED,WESTRING_PSCORE_HEROESKILLED\nPlayerScoreItemsGained=1,playerscore,PLAYER_SCORE_ITEMS_GAINED,WESTRING_PSCORE_ITEMSGAINED\nPlayerScoreMercsHired=1,playerscore,PLAYER_SCORE_MERCS_HIRED,WESTRING_PSCORE_MERCSHIRED\nPlayerScoreGoldTotal=1,playerscore,PLAYER_SCORE_GOLD_MINED_TOTAL,WESTRING_PSCORE_GOLDTOTAL\nPlayerScoreGoldUpkeep=1,playerscore,PLAYER_SCORE_GOLD_MINED_UPKEEP,WESTRING_PSCORE_GOLDUPKEEP\nPlayerScoreGoldLostUpkeep=1,playerscore,PLAYER_SCORE_GOLD_LOST_UPKEEP,WESTRING_PSCORE_GOLDLOSTUPKEEP\nPlayerScoreGoldLostTax=1,playerscore,PLAYER_SCORE_GOLD_LOST_TAX,WESTRING_PSCORE_GOLDLOSTTAX\nPlayerScoreGoldGiven=1,playerscore,PLAYER_SCORE_GOLD_GIVEN,WESTRING_PSCORE_GOLDGIVEN\nPlayerScoreGoldReceived=1,playerscore,PLAYER_SCORE_GOLD_RECEIVED,WESTRING_PSCORE_GOLDRECEIVED\nPlayerScoreLumberTotal=1,playerscore,PLAYER_SCORE_LUMBER_TOTAL,WESTRING_PSCORE_LUMBERTOTAL\nPlayerScoreLumberLostUpkeep=1,playerscore,PLAYER_SCORE_LUMBER_LOST_UPKEEP,WESTRING_PSCORE_LUMBERLOSTUPKEEP\nPlayerScoreLumberLostTax=1,playerscore,PLAYER_SCORE_LUMBER_LOST_TAX,WESTRING_PSCORE_LUMBERLOSTTAX\nPlayerScoreLumberGiven=1,playerscore,PLAYER_SCORE_LUMBER_GIVEN,WESTRING_PSCORE_LUMBERGIVEN\nPlayerScoreLumberReceived=1,playerscore,PLAYER_SCORE_LUMBER_RECEIVED,WESTRING_PSCORE_LUMBERECEIVED\nPlayerScoreUnitTotal=1,playerscore,PLAYER_SCORE_UNIT_TOTAL,WESTRING_PSCORE_UNITTOTAL\nPlayerScoreHeroTotal=1,playerscore,PLAYER_SCORE_HERO_TOTAL,WESTRING_PSCORE_HEROTOTAL\nPlayerScoreResourceTotal=1,playerscore,PLAYER_SCORE_RESOURCE_TOTAL,WESTRING_PSCORE_RESOURCETOTAL\nPlayerScoreTotal=1,playerscore,PLAYER_SCORE_TOTAL,WESTRING_PSCORE_TOTAL\nPlayerFlagUnfollowable=0,playerflag,PLAYER_STATE_UNFOLLOWABLE,WESTRING_PFLAG_UNFOLLOWABLE\nPlayerFlagGivesBounty=0,playerflag,PLAYER_STATE_GIVES_BOUNTY,WESTRING_PFLAG_GIVESBOUNTY\nPlayerFlagAlliedVictory=0,playerflag,PLAYER_STATE_ALLIED_VICTORY,WESTRING_PFLAG_ALLIEDVICTORY\nGateOperationClosed=0,gateoperation,bj_GATEOPERATION_CLOSE,WESTRING_GATEOPERATION_CLOSE\nGateOperationOpen=0,gateoperation,bj_GATEOPERATION_OPEN,WESTRING_GATEOPERATION_OPEN\nGateOperationDestroyed=0,gateoperation,bj_GATEOPERATION_DESTROY,WESTRING_GATEOPERATION_DESTROY\nElevatorWallOpClose=1,elevatorwallop,false,WESTRING_ELEVATORWALLOP_CLOSE\nElevatorWallOpOpen=1,elevatorwallop,true,WESTRING_ELEVATORWALLOP_OPEN\nElevatorWallTypeAll=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_ALL,WESTRING_ELEVATORWALLTYPE_ALL\nElevatorWallTypeEast=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_EAST,WESTRING_ELEVATORWALLTYPE_EAST\nElevatorWallTypeNorth=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_NORTH,WESTRING_ELEVATORWALLTYPE_NORTH\nElevatorWallTypeSouth=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_SOUTH,WESTRING_ELEVATORWALLTYPE_SOUTH\nElevatorWallTypeWest=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_WEST,WESTRING_ELEVATORWALLTYPE_WEST\nUseSkipOptionUse=0,useskipoption,true,WESTRING_USESKIPOPTION_USE\nUseSkipOptionSkip=0,useskipoption,false,WESTRING_USESKIPOPTION_SKIP\nSelDeselOptionSel=0,seldeseloption,true,WESTRING_SELDESELOPTION_SEL\nSelDeselOptionDesel=0,seldeseloption,false,WESTRING_SELDESELOPTION_DESEL\nAICaptainAttack=1,aicaptaintype,true,WESTRING_AICAPTAIN_ATTACK\nAICaptainDefense=1,aicaptaintype,false,WESTRING_AICAPTAIN_DEFENSE\nAICommandPop=1,aicommandpop,true,WESTRING_AICOMMAND_REMOVE\nAICommandLeave=1,aicommandpop,false,WESTRING_AICOMMAND_LEAVE\nCacheValueTypeBoolean=1,cachevaluetype,bj_GAMECACHE_BOOLEAN,WESTRING_CACHEVALUETYPE_BOOLEAN\nCacheValueTypeInteger=1,cachevaluetype,bj_GAMECACHE_INTEGER,WESTRING_CACHEVALUETYPE_INTEGER\nCacheValueTypeReal=1,cachevaluetype,bj_GAMECACHE_REAL,WESTRING_CACHEVALUETYPE_REAL\nCacheValueTypeUnit=1,cachevaluetype,bj_GAMECACHE_UNIT,WESTRING_CACHEVALUETYPE_UNIT\nCacheValueTypeString=1,cachevaluetype,bj_GAMECACHE_STRING,WESTRING_CACHEVALUETYPE_STRING\nMapControlNone=0,mapcontrol,MAP_CONTROL_NONE,WESTRING_MAPCONTROL_NONE\nMapControlUser=0,mapcontrol,MAP_CONTROL_USER,WESTRING_MAPCONTROL_USER\nMapControlComputer=0,mapcontrol,MAP_CONTROL_COMPUTER,WESTRING_MAPCONTROL_COMPUTER\nMapControlRescuable=0,mapcontrol,MAP_CONTROL_RESCUABLE,WESTRING_MAPCONTROL_RESCUABLE\nMapControlNeutral=0,mapcontrol,MAP_CONTROL_NEUTRAL,WESTRING_MAPCONTROL_NEUTRAL\nMapControlCreep=0,mapcontrol,MAP_CONTROL_CREEP,WESTRING_MAPCONTROL_CREEP\nPlayerSlotStateEmpty=0,playerslotstate,PLAYER_SLOT_STATE_EMPTY,WESTRING_PSLOT_EMPTY\nPlayerSlotStatePlaying=0,playerslotstate,PLAYER_SLOT_STATE_PLAYING,WESTRING_PSLOT_PLAYING\nPlayerSlotStateLeft=0,playerslotstate,PLAYER_SLOT_STATE_LEFT,WESTRING_PSLOT_LEFT\nPlayerUnitEventDeath=0,playerunitevent,EVENT_PLAYER_UNIT_DEATH,WESTRING_PUEVENT_DEATH\nPlayerUnitEventDecay=0,playerunitevent,EVENT_PLAYER_UNIT_DECAY,WESTRING_PUEVENT_DECAY\nPlayerUnitEventChangesOwner=1,playerunitevent,EVENT_PLAYER_UNIT_CHANGE_OWNER,WESTRING_PUEVENT_CHANGESOWNER\nPlayerUnitEventHero_Level=0,playerunitevent,EVENT_PLAYER_HERO_LEVEL,WESTRING_PUEVENT_HEROLEVEL\nPlayerUnitEventHero_Skill=0,playerunitevent,EVENT_PLAYER_HERO_SKILL,WESTRING_PUEVENT_HEROSKILL\nPlayerUnitEventHero_Revivable=0,playerunitevent,EVENT_PLAYER_HERO_REVIVABLE,WESTRING_PUEVENT_HEROREVIVABLE\nPlayerUnitEventHeroUseItem=0,playerunitevent,EVENT_PLAYER_UNIT_USE_ITEM,WESTRING_PUEVENT_HEROUSEITEM\nPlayerUnitEventHeroPickUpItem=0,playerunitevent,EVENT_PLAYER_UNIT_PICKUP_ITEM,WESTRING_PUEVENT_HEROPICKUPITEM\nPlayerUnitEventHeroDropItem=0,playerunitevent,EVENT_PLAYER_UNIT_DROP_ITEM,WESTRING_PUEVENT_HERODROPITEM\nPlayerUnitEventSell=1,playerunitevent,EVENT_PLAYER_UNIT_SELL,WESTRING_PUEVENT_SELL\nPlayerUnitEventSellItem=1,playerunitevent,EVENT_PLAYER_UNIT_SELL_ITEM,WESTRING_PUEVENT_SELLITEM\nPlayerUnitEventPawnItem=1,playerunitevent,EVENT_PLAYER_UNIT_PAWN_ITEM,WESTRING_PUEVENT_PAWNITEM\nPlayerUnitEventAttacked=0,playerunitevent,EVENT_PLAYER_UNIT_ATTACKED,WESTRING_PUEVENT_ATTACKED\nPlayerUnitEventRescued=0,playerunitevent,EVENT_PLAYER_UNIT_RESCUED,WESTRING_PUEVENT_RESCUED\nPlayerUnitEventSummoned=0,playerunitevent,EVENT_PLAYER_UNIT_SUMMON,WESTRING_PUEVENT_SUMMONED\nPlayerUnitEventSpellChannel=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_CHANNEL,WESTRING_PUEVENT_SPELLCHANNEL\nPlayerUnitEventSpellCast=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_CAST,WESTRING_PUEVENT_SPELLCAST\nPlayerUnitEventSpellEndCast=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_ENDCAST,WESTRING_PUEVENT_SPELLENDCAST\nPlayerUnitEventSpellEffect=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_EFFECT,WESTRING_PUEVENT_SPELLEFFECT\nPlayerUnitEventSpellFinish=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_FINISH,WESTRING_PUEVENT_SPELLFINISH\nPlayerUnitEventLoaded=0,playerunitevent,EVENT_PLAYER_UNIT_LOADED,WESTRING_PUEVENT_LOADED\nPlayerUnitEventTrain_Start=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_START,WESTRING_PUEVENT_TRAINSTART\nPlayerUnitEventTrain_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_CANCEL,WESTRING_PUEVENT_TRAINCANCEL\nPlayerUnitEventTrain_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_FINISH,WESTRING_PUEVENT_TRAINFINISH\nPlayerUnitEventConstruct_Start=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_START,WESTRING_PUEVENT_CONSTRUCTSTART\nPlayerUnitEventConstruct_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL,WESTRING_PUEVENT_CONSTRUCTCANCEL\nPlayerUnitEventConstruct_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_FINISH,WESTRING_PUEVENT_CONSTRUCTFINISH\nPlayerUnitEventReviveStart=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_START,WESTRING_PUEVENT_REVIVESTART\nPlayerUnitEventReviveCancel=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_CANCEL,WESTRING_PUEVENT_REVIVECANCEL\nPlayerUnitEventReviveFinish=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_FINISH,WESTRING_PUEVENT_REVIVEFINISH\nPlayerUnitEventUpgrade_Start=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_START,WESTRING_PUEVENT_UPGRADESTART\nPlayerUnitEventUpgrade_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_CANCEL,WESTRING_PUEVENT_UPGRADECANCEL\nPlayerUnitEventUpgrade_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_FINISH,WESTRING_PUEVENT_UPGRADEFINISH\nPlayerUnitEventResearch_Start=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_START,WESTRING_PUEVENT_RESEARCHSTART\nPlayerUnitEventResearch_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_CANCEL,WESTRING_PUEVENT_RESEARCHCANCEL\nPlayerUnitEventResearch_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_FINISH,WESTRING_PUEVENT_RESEARCHFINISH\nPlayerUnitEventIssued_Unit_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER,WESTRING_PUEVENT_ISSUEDUNITORDER\nPlayerUnitEventIssued_Point_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,WESTRING_PUEVENT_ISSUEDPOINTORDER\nPlayerUnitEventIssued_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_ORDER,WESTRING_PUEVENT_ISSUEDORDER\nUnitEventDeath=0,unitevent,EVENT_UNIT_DEATH,WESTRING_UEVENT_DEATH\nUnitEventDecay=0,unitevent,EVENT_UNIT_DECAY,WESTRING_UEVENT_DECAY\nUnitEventChangesOwner=1,unitevent,EVENT_UNIT_CHANGE_OWNER,WESTRING_UEVENT_CHANGESOWNER\nUnitEventDamaged=0,unitevent,EVENT_UNIT_DAMAGED,WESTRING_UEVENT_DAMAGED\nUnitEventHeroLevel=0,unitevent,EVENT_UNIT_HERO_LEVEL,WESTRING_UEVENT_HEROLEVEL\nUnitEventHeroSkill=0,unitevent,EVENT_UNIT_HERO_SKILL,WESTRING_UEVENT_HEROSKILL\nUnitEventHeroRevivable=0,unitevent,EVENT_UNIT_HERO_REVIVABLE,WESTRING_UEVENT_HEROREVIVABLE\nUnitEventHeroUseItem=0,unitevent,EVENT_UNIT_USE_ITEM,WESTRING_UEVENT_HEROUSEITEM\nUnitEventHeroPickUpItem=0,unitevent,EVENT_UNIT_PICKUP_ITEM,WESTRING_UEVENT_HEROPICKUPITEM\nUnitEventHeroDropItem=0,unitevent,EVENT_UNIT_DROP_ITEM,WESTRING_UEVENT_HERODROPITEM\nUnitEventSell=1,unitevent,EVENT_UNIT_SELL,WESTRING_UEVENT_SELL\nUnitEventSellItem=1,unitevent,EVENT_UNIT_SELL_ITEM,WESTRING_UEVENT_SELLITEM\nUnitEventPawnItem=1,unitevent,EVENT_UNIT_PAWN_ITEM,WESTRING_UEVENT_PAWNITEM\nUnitEventAttacked=0,unitevent,EVENT_UNIT_ATTACKED,WESTRING_UEVENT_ATTACKED\nUnitEventRescued=0,unitevent,EVENT_UNIT_RESCUED,WESTRING_UEVENT_RESCUED\nUnitEventSelected=0,unitevent,EVENT_UNIT_SELECTED,WESTRING_UEVENT_SELECTED\nUnitEventDeselected=0,unitevent,EVENT_UNIT_DESELECTED,WESTRING_UEVENT_DESELECTED\nUnitEventSpellChannel=1,unitevent,EVENT_UNIT_SPELL_CHANNEL,WESTRING_UEVENT_SPELLCHANNEL\nUnitEventSpellCast=1,unitevent,EVENT_UNIT_SPELL_CAST,WESTRING_UEVENT_SPELLCAST\nUnitEventSpellEndCast=1,unitevent,EVENT_UNIT_SPELL_ENDCAST,WESTRING_UEVENT_SPELLENDCAST\nUnitEventSpellEffect=1,unitevent,EVENT_UNIT_SPELL_EFFECT,WESTRING_UEVENT_SPELLEFFECT\nUnitEventSpellFinish=1,unitevent,EVENT_UNIT_SPELL_FINISH,WESTRING_UEVENT_SPELLFINISH\nUnitEventLoaded=0,unitevent,EVENT_UNIT_LOADED,WESTRING_UEVENT_LOADED\nUnitEventAcquiredTarget=0,unitevent,EVENT_UNIT_ACQUIRED_TARGET,WESTRING_UEVENT_ACQUIREDTARGET\nUnitEventTargetInRange=0,unitevent,EVENT_UNIT_TARGET_IN_RANGE,WESTRING_UEVENT_TARGETINRANGE\nUnitEventTrainStart=0,unitevent,EVENT_UNIT_TRAIN_START,WESTRING_UEVENT_TRAINSTART\nUnitEventTrainCancel=0,unitevent,EVENT_UNIT_TRAIN_CANCEL,WESTRING_UEVENT_TRAINCANCEL\nUnitEventTrainFinish=0,unitevent,EVENT_UNIT_TRAIN_FINISH,WESTRING_UEVENT_TRAINFINISH\nUnitEventReviveStart=0,unitevent,EVENT_UNIT_HERO_REVIVE_START,WESTRING_UEVENT_REVIVESTART\nUnitEventReviveCancel=0,unitevent,EVENT_UNIT_HERO_REVIVE_CANCEL,WESTRING_UEVENT_REVIVECANCEL\nUnitEventReviveFinish=0,unitevent,EVENT_UNIT_HERO_REVIVE_FINISH,WESTRING_UEVENT_REVIVEFINISH\nUnitEventUpgradeStart=0,unitevent,EVENT_UNIT_UPGRADE_START,WESTRING_UEVENT_UPGRADESTART\nUnitEventUpgradeCancel=0,unitevent,EVENT_UNIT_UPGRADE_CANCEL,WESTRING_UEVENT_UPGRADECANCEL\nUnitEventUpgradeFinish=0,unitevent,EVENT_UNIT_UPGRADE_FINISH,WESTRING_UEVENT_UPGRADEFINISH\nUnitEventResearchStart=0,unitevent,EVENT_UNIT_RESEARCH_START,WESTRING_UEVENT_RESEARCHSTART\nUnitEventResearchCancel=0,unitevent,EVENT_UNIT_RESEARCH_CANCEL,WESTRING_UEVENT_RESEARCHCANCEL\nUnitEventResearchFinish=0,unitevent,EVENT_UNIT_RESEARCH_FINISH,WESTRING_UEVENT_RESEARCHFINISH\nUnitEventIssueUnitOrder=0,unitevent,EVENT_UNIT_ISSUED_TARGET_ORDER,WESTRING_UEVENT_ISSUEUNITORDER\nUnitEventIssuePointOrder=0,unitevent,EVENT_UNIT_ISSUED_POINT_ORDER,WESTRING_UEVENT_ISSUEPOINTORDER\nUnitEventIssueOrder=0,unitevent,EVENT_UNIT_ISSUED_ORDER,WESTRING_UEVENT_ISSUEORDER\nUnitStateLife=0,unitstate,UNIT_STATE_LIFE,WESTRING_USTATE_LIFE\nUnitStateMaxLife=0,unitstate,UNIT_STATE_MAX_LIFE,WESTRING_USTATE_MAXLIFE\nUnitStateMana=0,unitstate,UNIT_STATE_MANA,WESTRING_USTATE_MANA\nUnitStateMaxMana=0,unitstate,UNIT_STATE_MAX_MANA,WESTRING_USTATE_MAXMANA\nKeyEventTypeDepress=1,keyeventtype,bj_KEYEVENTTYPE_DEPRESS,WESTRING_KEYEVENTTYPE_DEPRESS\nKeyEventTypeRelease=1,keyeventtype,bj_KEYEVENTTYPE_RELEASE,WESTRING_KEYEVENTTYPE_RELEASE\nKeyEventKeyLeft=1,keyeventkey,bj_KEYEVENTKEY_LEFT,WESTRING_KEYEVENTKEY_LEFT\nKeyEventKeyRight=1,keyeventkey,bj_KEYEVENTKEY_RIGHT,WESTRING_KEYEVENTKEY_RIGHT\nKeyEventKeyDown=1,keyeventkey,bj_KEYEVENTKEY_DOWN,WESTRING_KEYEVENTKEY_DOWN\nKeyEventKeyUp=1,keyeventkey,bj_KEYEVENTKEY_UP,WESTRING_KEYEVENTKEY_UP\nUnitTypeStructure=0,unittype,UNIT_TYPE_STRUCTURE,WESTRING_UNITTYPE_STRUCTURE\nUnitTypeHero=0,unittype,UNIT_TYPE_HERO,WESTRING_UNITTYPE_HERO\nUnitTypeGround=0,unittype,UNIT_TYPE_GROUND,WESTRING_UNITTYPE_GROUND\nUnitTypeFlying=0,unittype,UNIT_TYPE_FLYING,WESTRING_UNITTYPE_FLYING\nUnitTypeAttacksGround=0,unittype,UNIT_TYPE_ATTACKS_GROUND,WESTRING_UNITTYPE_ATTACKSGROUND\nUnitTypeAttacksFlying=0,unittype,UNIT_TYPE_ATTACKS_FLYING,WESTRING_UNITTYPE_ATTACKSFLYING\nUnitTypeMeleeAttacker=0,unittype,UNIT_TYPE_MELEE_ATTACKER,WESTRING_UNITTYPE_MELEEATTACKER\nUnitTypeRangedAttacker=0,unittype,UNIT_TYPE_RANGED_ATTACKER,WESTRING_UNITTYPE_RANGEDATTACKER\nUnitTypeSummoned=0,unittype,UNIT_TYPE_SUMMONED,WESTRING_UNITTYPE_SUMMONED\nUnitTypeUndead=0,unittype,UNIT_TYPE_UNDEAD,WESTRING_UNITTYPE_UNDEAD\nUnitTypeMechanical=0,unittype,UNIT_TYPE_MECHANICAL,WESTRING_UNITTYPE_MECHANICAL\nUnitTypeAncient=0,unittype,UNIT_TYPE_ANCIENT,WESTRING_UNITTYPE_ANCIENT\nUnitTypePeon=0,unittype,UNIT_TYPE_PEON,WESTRING_UNITTYPE_PEON\nUnitTypeTownHall=0,unittype,UNIT_TYPE_TOWNHALL,WESTRING_UNITTYPE_TOWNHALL\nUnitTypeSapper=0,unittype,UNIT_TYPE_SAPPER,WESTRING_UNITTYPE_SAPPER\nGameSpeedSlowest=0,gamespeed,MAP_SPEED_SLOWEST,WESTRING_GAMESPEED_SLOWEST\nGameSpeedSlow=0,gamespeed,MAP_SPEED_SLOW,WESTRING_GAMESPEED_SLOW\nGameSpeedNormal=0,gamespeed,MAP_SPEED_NORMAL,WESTRING_GAMESPEED_NORMAL\nGameSpeedFast=0,gamespeed,MAP_SPEED_FAST,WESTRING_GAMESPEED_FAST\nGameSpeedFastest=0,gamespeed,MAP_SPEED_FASTEST,WESTRING_GAMESPEED_FASTEST\nGameDifficultyEasy=0,gamedifficulty,MAP_DIFFICULTY_EASY,WESTRING_GAMEDIFFICULTY_EASY\nGameDifficultyNormal=0,gamedifficulty,MAP_DIFFICULTY_NORMAL,WESTRING_GAMEDIFFICULTY_NORMAL\nGameDifficultyHard=0,gamedifficulty,MAP_DIFFICULTY_HARD,WESTRING_GAMEDIFFICULTY_HARD\nAIDifficultyNewbie=0,aidifficulty,AI_DIFFICULTY_NEWBIE,WESTRING_AIDIFFICULTY_NEWBIE\nAIDifficultyNormal=0,aidifficulty,AI_DIFFICULTY_NORMAL,WESTRING_AIDIFFICULTY_NORMAL\nAIDifficultyInsane=0,aidifficulty,AI_DIFFICULTY_INSANE,WESTRING_AIDIFFICULTY_INSANE\nMapDensityNone=0,mapdensity,MAP_DENSITY_NONE,WESTRING_MAPDENSITY_NONE\nMapDensityLight=0,mapdensity,MAP_DENSITY_LIGHT,WESTRING_MAPDENSITY_LIGHT\nMapDensityMedium=0,mapdensity,MAP_DENSITY_MEDIUM,WESTRING_MAPDENSITY_MEDIUM\nMapDensityHeavy=0,mapdensity,MAP_DENSITY_HEAVY,WESTRING_MAPDENSITY_HEAVY\nAllianceSettingUnallied=0,alliancesetting,bj_ALLIANCE_UNALLIED,WESTRING_ALLIANCE_UNALLIED\nAllianceSettingUnalliedVision=0,alliancesetting,bj_ALLIANCE_UNALLIED_VISION,WESTRING_ALLIANCE_UNALLIEDVISION\nAllianceSettingNeutral=0,alliancesetting,bj_ALLIANCE_NEUTRAL,WESTRING_ALLIANCE_NEUTRAL\nAllianceSettingNeutralVision=1,alliancesetting,bj_ALLIANCE_NEUTRAL_VISION,WESTRING_ALLIANCE_NEUTRAL_VISION\nAllianceSettingAllied=0,alliancesetting,bj_ALLIANCE_ALLIED,WESTRING_ALLIANCE_ALLIED\nAllianceSettingAlliedVision=0,alliancesetting,bj_ALLIANCE_ALLIED_VISION,WESTRING_ALLIANCE_ALLIEDVISION\nAllianceSettingAlliedUnits=0,alliancesetting,bj_ALLIANCE_ALLIED_UNITS,WESTRING_ALLIANCE_ALLIEDUNITS\nAllianceSettingAlliedAdvUnits=0,alliancesetting,bj_ALLIANCE_ALLIED_ADVUNITS,WESTRING_ALLIANCE_ALLIEDADVUNITS\nAllianceTypePassive=0,alliancetype,ALLIANCE_PASSIVE,WESTRING_ALLIANCE_PASSIVE\nAllianceTypeSharedVision=0,alliancetype,ALLIANCE_SHARED_VISION,WESTRING_ALLIANCE_SHAREDVISION\nAllianceTypeSharedControl=0,alliancetype,ALLIANCE_SHARED_CONTROL,WESTRING_ALLIANCE_SHAREDCONTROL\nAllianceTypeSharedFullControl=0,alliancetype,ALLIANCE_SHARED_ADVANCED_CONTROL,WESTRING_ALLIANCE_SHAREDFULLCONTROL\nAllianceTypeXP=0,alliancetype,ALLIANCE_SHARED_XP,WESTRING_ALLIANCE_XP\nAllianceTypeSpells=0,alliancetype,ALLIANCE_SHARED_SPELLS,WESTRING_ALLIANCE_SPELLS\nAllianceTypeHelpRequest=0,alliancetype,ALLIANCE_HELP_REQUEST,WESTRING_ALLIANCE_HELPREQUEST\nAllianceTypeHelpResponse=0,alliancetype,ALLIANCE_HELP_RESPONSE,WESTRING_ALLIANCE_HELPRESPONSE\nCameraFieldTargetDistance=0,camerafield,CAMERA_FIELD_TARGET_DISTANCE,WESTRING_CAMERA_TARGETDISTANCE\nCameraFieldFarZ=0,camerafield,CAMERA_FIELD_FARZ,WESTRING_CAMERA_FARZ\nCameraFieldAOA=0,camerafield,CAMERA_FIELD_ANGLE_OF_ATTACK,WESTRING_CAMERA_AOA\nCameraFieldFOV=0,camerafield,CAMERA_FIELD_FIELD_OF_VIEW,WESTRING_CAMERA_FOV\nCameraFieldRoll=0,camerafield,CAMERA_FIELD_ROLL,WESTRING_CAMERA_ROLL\nCameraFieldRotation=0,camerafield,CAMERA_FIELD_ROTATION,WESTRING_CAMERA_ROTATION\nCameraFieldZOffset=1,camerafield,CAMERA_FIELD_ZOFFSET,WESTRING_CAMERA_ZOFFSET\nRarityControlFrequent=0,raritycontrol,RARITY_FREQUENT,WESTRING_RARITY_FREQUENT\nRarityControlRare=0,raritycontrol,RARITY_RARE,WESTRING_RARITY_RARE\nBlendModeNone=0,blendmode,BLEND_MODE_NONE,WESTRING_BLENDMODE_NONE\nBlendModeBlend=0,blendmode,BLEND_MODE_BLEND,WESTRING_BLENDMODE_BLEND\nBlendModeAdditive=0,blendmode,BLEND_MODE_ADDITIVE,WESTRING_BLENDMODE_ADDITIVE\nBlendModeModulate=0,blendmode,BLEND_MODE_MODULATE,WESTRING_BLENDMODE_MODULATE\nBlendModeModulate2x=0,blendmode,BLEND_MODE_MODULATE_2X,WESTRING_BLENDMODE_MODULATE_2X\nBlendModeKeyAlpha=0,blendmode,BLEND_MODE_KEYALPHA,WESTRING_BLENDMODE_KEYALPHA\nVolumeGroupAmbient=0,volumegroup,SOUND_VOLUMEGROUP_AMBIENTSOUNDS,WESTRING_VOLUMEGROUP_AMBIENTSOUNDS\nVolumeGroupSpells=0,volumegroup,SOUND_VOLUMEGROUP_SPELLS,WESTRING_VOLUMEGROUP_SPELLS\nVolumeGroupCombat=0,volumegroup,SOUND_VOLUMEGROUP_COMBAT,WESTRING_VOLUMEGROUP_COMBAT\nVolumeGroupFire=0,volumegroup,SOUND_VOLUMEGROUP_FIRE,WESTRING_VOLUMEGROUP_FIRE\nVolumeGroupMusic=0,volumegroup,SOUND_VOLUMEGROUP_MUSIC,WESTRING_VOLUMEGROUP_MUSIC\nVolumeGroupUnitMovement=0,volumegroup,SOUND_VOLUMEGROUP_UNITMOVEMENT,WESTRING_VOLUMEGROUP_UNITMOVEMENT\nVolumeGroupUnitSounds=0,volumegroup,SOUND_VOLUMEGROUP_UNITSOUNDS,WESTRING_VOLUMEGROUP_UNITSOUNDS\nVolumeGroupUI=0,volumegroup,SOUND_VOLUMEGROUP_UI,WESTRING_VOLUMEGROUP_UI\nFogStateMasked=0,fogstate,FOG_OF_WAR_MASKED,WESTRING_FOGSTATE_MASKED\nFogStateFogged=0,fogstate,FOG_OF_WAR_FOGGED,WESTRING_FOGSTATE_FOGGED\nFogStateVisible=0,fogstate,FOG_OF_WAR_VISIBLE,WESTRING_FOGSTATE_VISIBLE\nFogStyleLinear=0,fogstyle,0,WESTRING_FOGSTYLE_LINEAR\nFogStyleExp1=0,fogstyle,1,WESTRING_FOGSTYLE_EXP1\nFogStyleExp2=0,fogstyle,2,WESTRING_FOGSTYLE_EXP2\nTimedLifeBuffCodeAnimateDead=1,timedlifebuffcode,'BUan',WESTRING_TIMEDLIFEBUFFCODE_ANIMATEDEAD\nTimedLifeBuffCodePlagueWard=1,timedlifebuffcode,'Bapl',WESTRING_TIMEDLIFEBUFFCODE_PLAGUEWARD\nTimedLifeBuffCodeForceOfNature=1,timedlifebuffcode,'BEfn',WESTRING_TIMEDLIFEBUFFCODE_FORCEOFNATURE\nTimedLifeBuffCodeGeneric=1,timedlifebuffcode,'BTLF',WESTRING_TIMEDLIFEBUFFCODE_GENERIC\nTimedLifeBuffCodeHealingWard=1,timedlifebuffcode,'Bhwd',WESTRING_TIMEDLIFEBUFFCODE_HEALINGWARD\nTimedLifeBuffCodeRaiseDead=1,timedlifebuffcode,'Brai',WESTRING_TIMEDLIFEBUFFCODE_RAISEDEAD\nTimedLifeBuffCodeWaterElemental=1,timedlifebuffcode,'BHwe',WESTRING_TIMEDLIFEBUFFCODE_WATERELEMENTAL\nTimedLifeBuffCodeWaterSummoned=1,timedlifebuffcode,'BFig',WESTRING_TIMEDLIFEBUFFCODE_SUMMONED\nItemStatusHidden=1,itemstatus,bj_ITEM_STATUS_HIDDEN,WESTRING_ITEMSTATUS_HIDDEN\nItemStatusOwned=1,itemstatus,bj_ITEM_STATUS_OWNED,WESTRING_ITEMSTATUS_OWNED\nItemStatusInvulnerable=1,itemstatus,bj_ITEM_STATUS_INVULNERABLE,WESTRING_ITEMSTATUS_INVULNERABLE\nItemStatusPowerup=1,itemstatus,bj_ITEM_STATUS_POWERUP,WESTRING_ITEMSTATUS_POWERUP\nItemStatusSellable=1,itemstatus,bj_ITEM_STATUS_SELLABLE,WESTRING_ITEMSTATUS_SELLABLE\nItemStatusPawnable=1,itemstatus,bj_ITEM_STATUS_PAWNABLE,WESTRING_ITEMSTATUS_PAWNABLE\nItemcodeStatusPowerup=1,itemcodestatus,bj_ITEMCODE_STATUS_POWERUP,WESTRING_ITEMCODESTATUS_POWERUP\nItemcodeStatusSellable=1,itemcodestatus,bj_ITEMCODE_STATUS_SELLABLE,WESTRING_ITEMCODESTATUS_SELLABLE\nItemcodeStatusPawnable=1,itemcodestatus,bj_ITEMCODE_STATUS_PAWNABLE,WESTRING_ITEMCODESTATUS_PAWNABLE\nMinimapPingStyleSimple=1,minimappingstyle,bj_MINIMAPPINGSTYLE_SIMPLE,WESTRING_MINIMAPPINGSTYLE_SIMPLE\nMinimapPingStyleFlashy=1,minimappingstyle,bj_MINIMAPPINGSTYLE_FLASHY,WESTRING_MINIMAPPINGSTYLE_FLASHY\nMinimapPingStyleAttack=1,minimappingstyle,bj_MINIMAPPINGSTYLE_ATTACK,WESTRING_MINIMAPPINGSTYLE_ATTACK\nCorpseTypeFlesh=1,corpsetype,bj_CORPSETYPE_FLESH,WESTRING_CORPSETYPE_FLESH\nCorpseTypeBone=1,corpsetype,bj_CORPSETYPE_BONE,WESTRING_CORPSETYPE_BONE\nStringCaseLower=1,stringcaseoption,false,WESTRING_STRINGCASE_LOWER\nStringCaseUpper=1,stringcaseoption,true,WESTRING_STRINGCASE_UPPER\nChangeColorTrue=0,colorchangeoption,true,WESTRING_CHANGECOLOR_CHANGE\nChangeColorFalse=0,colorchangeoption,false,WESTRING_CHANGECOLOR_RETAIN\nPlayerChangeColorChange=0,playerchangecoloroption,true,WESTRING_SETPLAYERCOLOR_CHANGE\nPlayerChangeColorRetain=0,playerchangecoloroption,false,WESTRING_SETPLAYERCOLOR_RETAIN\nChatMatchTypeExact=0,chatmatchtype,true,WESTRING_CHATMATCH_EXACT\nChatMatchTypeSubstring=0,chatmatchtype,false,WESTRING_CHATMATCH_SUBSTRING\nUnitFacingBoneHead=0,unitfacingbone,`bone_head`,WESTRING_UNITFACINGBONE_HEAD\nUnitFacingBoneChest=0,unitfacingbone,`bone_chest`,WESTRING_UNITFACINGBONE_CHEST\nInclusionInclude=0,includeoption,true,WESTRING_INCLUSION_INCLUDE\nInclusionExclude=0,includeoption,false,WESTRING_INCLUSION_EXCLUDE\nCameraApply=0,cameraapplyoption,true,WESTRING_CAMERAAPPLYOPTION_APPLY\nCameraApplyNoPan=0,cameraapplyoption,false,WESTRING_CAMERAAPPLYOPTION_APPLYNOPAN\nCameraOrientationNormal=0,cameraorientationoption,false,WESTRING_CAMERAORIENTATION_NORMAL\nCameraOrientationInherit=0,cameraorientationoption,true,WESTRING_CAMERAORIENTATION_INHERIT\nInvulnerabilityInvulnerable=0,invulnerableoption,true,WESTRING_INVULNERABILITY_INVULNERABLE\nInvulnerabilityVulnerable=0,invulnerableoption,false,WESTRING_INVULNERABILITY_VULNERABLE\nAvailabilityOptionAvailable=0,availabilityoption,true,WESTRING_AVAILABILITY_AVAILABLE\nAvailabilityOptionUnavailable=0,availabilityoption,false,WESTRING_AVAILABILITY_UNAVAILABLE\nShowHideHide=0,showhideoption,false,WESTRING_SHOWHIDE_HIDE\nShowHideShow=0,showhideoption,true,WESTRING_SHOWHIDE_SHOW\nMinimize=1,minimizeoption,true,WESTRING_MINIMIZEOPTION_MINIMIZE\nMaximize=1,minimizeoption,false,WESTRING_MINIMIZEOPTION_MAXIMIZE\nSkyModelNone=0,skymodelstring,null,WESTRING_SKYMODEL_NONE\nSkyModelSky08=0,skymodelstring,`Environment\\\\Sky\\\\BlizzardSky\\\\BlizzardSky.mdl`,WESTRING_SKYMODEL_SKY08\nSkyModelSky02=0,skymodelstring,`Environment\\\\Sky\\\\DalaranSky\\\\DalaranSky.mdl`,WESTRING_SKYMODEL_SKY02\nSkyModelSky06=0,skymodelstring,`Environment\\\\Sky\\\\FelwoodSky\\\\FelwoodSky.mdl`,WESTRING_SKYMODEL_SKY06\nSkyModelSky07=0,skymodelstring,`Environment\\\\Sky\\\\FoggedSky\\\\FoggedSky.mdl`,WESTRING_SKYMODEL_SKY07\nSkyModelSky01=0,skymodelstring,`Environment\\\\Sky\\\\Sky\\\\SkyLight.mdl`,WESTRING_SKYMODEL_SKY01\nSkyModelSky03=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronFallSky\\\\LordaeronFallSky.mdl`,WESTRING_SKYMODEL_SKY03\nSkyModelSky04=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronSummerSky\\\\LordaeronSummerSky.mdl`,WESTRING_SKYMODEL_SKY04\nSkyModelSky05=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSky\\\\LordaeronWinterSky.mdl`,WESTRING_SKYMODEL_SKY05\nSkyModelSky09=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyBrightGreen\\\\LordaeronWinterSkyBrightGreen.mdl`,WESTRING_SKYMODEL_SKY09\nSkyModelSky10=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyPink\\\\LordaeronWinterSkyPink.mdl`,WESTRING_SKYMODEL_SKY10\nSkyModelSky11=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyPurple\\\\LordaeronWinterSkyPurple.mdl`,WESTRING_SKYMODEL_SKY11\nSkyModelSky12=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyRed\\\\LordaeronWinterSkyRed.mdl`,WESTRING_SKYMODEL_SKY12\nSkyModelSky13=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyYellow\\\\LordaeronWinterSkyYellow.mdl`,WESTRING_SKYMODEL_SKY13\nSkyModelSky14=1,skymodelstring,`Environment\\\\Sky\\\\Outland_Sky\\\\Outland_Sky.mdl`,WESTRING_SKYMODEL_SKY14\nSkyModelSky15=1,skymodelstring,`Environment\\\\Sky\\\\CustomSky\\\\CustomSky.mdl`,WESTRING_SKYMODEL_SKY15\nCineFilterTextureWhite=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\White_mask.blp`,WESTRING_CINEFILTERTEX_WHITE\nCineFilterTextureBlack=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Black_mask.blp`,WESTRING_CINEFILTERTEX_BLACK\nCineFilterTextureHaze=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\HazeFilter_mask.blp`,WESTRING_CINEFILTERTEX_HAZE\nCineFilterTextureGroundFog=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\GroundFog_mask.blp`,WESTRING_CINEFILTERTEX_GROUNDFOG\nCineFilterTextureHazeAndFog=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\HazeAndFogFilter_Mask.blp`,WESTRING_CINEFILTERTEX_HAZEANDFOG\nCineFilterTextureDiagonal=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\DiagonalSlash_mask.blp`,WESTRING_CINEFILTERTEX_DIAGONAL\nCineFilterTextureDream=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\DreamFilter_Mask.blp`,WESTRING_CINEFILTERTEX_DREAM\nCineFilterTextureScope=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Scope_Mask.blp`,WESTRING_CINEFILTERTEX_SCOPE\nCineFilterTexturePow=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\SpecialPowMask.blp`,WESTRING_CINEFILTERTEX_POW\nCineFilterTextureSplat=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\SpecialSplatMask.blp`,WESTRING_CINEFILTERTEX_SPLAT\nCineFilterTexturePanda=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Panda-n-Cub.blp`,WESTRING_CINEFILTERTEX_PANDA\nCineFilterTextureCustom1=1,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Custom1.blp`,WESTRING_CINEFILTERTEX_CUSTOM1\nCineFilterTextureCustom2=1,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Custom2.blp`,WESTRING_CINEFILTERTEX_CUSTOM2\nCineFilterTextureCustom3=1,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Custom3.blp`,WESTRING_CINEFILTERTEX_CUSTOM3\nCineFilterTextureCustom4=1,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Custom4.blp`,WESTRING_CINEFILTERTEX_CUSTOM4\nCineFilterTextureCustom5=1,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Custom5.blp`,WESTRING_CINEFILTERTEX_CUSTOM5\nMusicThemeArthas=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\ArthasTheme.mp3`,WESTRING_MUSICTHEME_ARTHAS\nMusicThemeBloodElf=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\BloodElfTheme.mp3`,WESTRING_MUSICTHEME_BLOODELF\nMusicThemeComradeship=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Comradeship.mp3`,WESTRING_MUSICTHEME_COMRADESHIP\nMusicThemeCredits=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Credits.mp3`,WESTRING_MUSICTHEME_CREDITS\nMusicThemeDarkAgents=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\DarkAgents.mp3`,WESTRING_MUSICTHEME_DARKAGENTS\nMusicThemeDarkVictory=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\DarkVictory.mp3`,WESTRING_MUSICTHEME_DARKVICTORY\nMusicThemeDoom=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Doom.mp3`,WESTRING_MUSICTHEME_DOOM\nMusicThemeHeroicVictory=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HeroicVictory.mp3`,WESTRING_MUSICTHEME_HEROIC_VICTORY\nMusicThemeHuman1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human1.mp3`,WESTRING_MUSICTHEME_HUMAN1\nMusicThemeHuman2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human2.mp3`,WESTRING_MUSICTHEME_HUMAN2\nMusicThemeHuman3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human3.mp3`,WESTRING_MUSICTHEME_HUMAN3\nMusicThemeHumanX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanX1.mp3`,WESTRING_MUSICTHEME_HUMANX1\nMusicThemeDefeatHuman=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_HUMAN\nMusicThemeVictoryHuman=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_HUMAN\nMusicThemeIllidan=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\IllidansTheme.mp3`,WESTRING_MUSICTHEME_ILLIDAN\nMusicThemeLichKing=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\LichKingTheme.mp3`,WESTRING_MUSICTHEME_LICHKING\nMusicThemeMainScreen=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\MainScreen.mp3`,WESTRING_MUSICTHEME_MAINSCREEN\nMusicThemeMainScreenX=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\War3XMainScreen.mp3`,WESTRING_MUSICTHEME_MAINSCREENX\nMusicThemeNaga=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NagaTheme.mp3`,WESTRING_MUSICTHEME_NAGA\nMusicThemeNightElf1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf1.mp3`,WESTRING_MUSICTHEME_NIGHTELF1\nMusicThemeNightElf2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf2.mp3`,WESTRING_MUSICTHEME_NIGHTELF2\nMusicThemeNightElf3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf3.mp3`,WESTRING_MUSICTHEME_NIGHTELF3\nMusicThemeNightElfX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfX1.mp3`,WESTRING_MUSICTHEME_NIGHTELFX1\nMusicThemeDefeatNightElf=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_NIGHTELF\nMusicThemeVictoryNightElf=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_NIGHTELF\nMusicThemeOrc1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc1.mp3`,WESTRING_MUSICTHEME_ORC1\nMusicThemeOrc2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc2.mp3`,WESTRING_MUSICTHEME_ORC2\nMusicThemeOrc3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc3.mp3`,WESTRING_MUSICTHEME_ORC3\nMusicThemeOrcX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcX1.mp3`,WESTRING_MUSICTHEME_ORCX1\nMusicThemeDefeatOrc=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_ORC\nMusicThemeOrcTheme=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcTheme.mp3`,WESTRING_MUSICTHEME_ORC_THEME\nMusicThemeVictoryOrc=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_ORC\nMusicThemePersuit=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\PursuitTheme.mp3`,WESTRING_MUSICTHEME_PURSUIT\nMusicThemeSadMystery=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\SadMystery.mp3`,WESTRING_MUSICTHEME_SADMYSTERY\nMusicThemeTension=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Tension.mp3`,WESTRING_MUSICTHEME_TENSION\nMusicThemeTragicConfrontation=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\TragicConfrontation.mp3`,WESTRING_MUSICTHEME_TRAGICCONFRONTATION\nMusicThemeUndead1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead1.mp3`,WESTRING_MUSICTHEME_UNDEAD1\nMusicThemeUndead2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead2.mp3`,WESTRING_MUSICTHEME_UNDEAD2\nMusicThemeUndead3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead3.mp3`,WESTRING_MUSICTHEME_UNDEAD3\nMusicThemeUndeadX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadX1.mp3`,WESTRING_MUSICTHEME_UNDEADX1\nMusicThemeDefeatUndead=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_UNDEAD\nMusicThemeVictoryUndead=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_UNDEAD\nAmbientThemeDayA=0,ambientthemeday,`AshenvaleDay`,WESTRING_AMBIENTTHEMEDAY_A\nAmbientThemeDayB=0,ambientthemeday,`BarrensDay`,WESTRING_AMBIENTTHEMEDAY_B\nAmbientThemeDayK=1,ambientthemeday,`BlackCitadelDay`,WESTRING_AMBIENTTHEMEDAY_K\nAmbientThemeDayY=0,ambientthemeday,`CityScapeDay`,WESTRING_AMBIENTTHEMEDAY_Y\nAmbientThemeDayX=0,ambientthemeday,`DalaranDay`,WESTRING_AMBIENTTHEMEDAY_X\nAmbientThemeDayJ=1,ambientthemeday,`DalaranRuinsDay`,WESTRING_AMBIENTTHEMEDAY_J\nAmbientThemeDayD=0,ambientthemeday,`DungeonDay`,WESTRING_AMBIENTTHEMEDAY_D\nAmbientThemeDayC=0,ambientthemeday,`FelwoodDay`,WESTRING_AMBIENTTHEMEDAY_C\nAmbientThemeDayI=1,ambientthemeday,`IceCrownDay`,WESTRING_AMBIENTTHEMEDAY_I\nAmbientThemeDayF=0,ambientthemeday,`LordaeronFallDay`,WESTRING_AMBIENTTHEMEDAY_F\nAmbientThemeDayL=0,ambientthemeday,`LordaeronSummerDay`,WESTRING_AMBIENTTHEMEDAY_L\nAmbientThemeDayW=0,ambientthemeday,`LordaeronWinterDay`,WESTRING_AMBIENTTHEMEDAY_W\nAmbientThemeDayN=0,ambientthemeday,`NorthrendDay`,WESTRING_AMBIENTTHEMEDAY_N\nAmbientThemeDayO=1,ambientthemeday,`BlackCitadelDay`,WESTRING_AMBIENTTHEMEDAY_O\nAmbientThemeDayZ=1,ambientthemeday,`SunkenRuinsDay`,WESTRING_AMBIENTTHEMEDAY_Z\nAmbientThemeDayV=0,ambientthemeday,`VillageDay`,WESTRING_AMBIENTTHEMEDAY_V\nAmbientThemeDayQ=0,ambientthemeday,`VillageFallDay`,WESTRING_AMBIENTTHEMEDAY_Q\nAmbientThemeNightA=0,ambientthemenight,`AshenvaleNight`,WESTRING_AMBIENTTHEMENIGHT_A\nAmbientThemeNightB=0,ambientthemenight,`BarrensNight`,WESTRING_AMBIENTTHEMENIGHT_B\nAmbientThemeNightK=1,ambientthemenight,`BlackCitadelNight`,WESTRING_AMBIENTTHEMENIGHT_K\nAmbientThemeNightY=0,ambientthemenight,`CityScapeNight`,WESTRING_AMBIENTTHEMENIGHT_Y\nAmbientThemeNightX=0,ambientthemenight,`DalaranNight`,WESTRING_AMBIENTTHEMENIGHT_X\nAmbientThemeNightJ=1,ambientthemenight,`DalaranRuinsNight`,WESTRING_AMBIENTTHEMENIGHT_J\nAmbientThemeNightD=0,ambientthemenight,`DungeonNight`,WESTRING_AMBIENTTHEMENIGHT_D\nAmbientThemeNightC=0,ambientthemenight,`FelwoodNight`,WESTRING_AMBIENTTHEMENIGHT_C\nAmbientThemeNightI=1,ambientthemenight,`IceCrownNight`,WESTRING_AMBIENTTHEMENIGHT_I\nAmbientThemeNightF=0,ambientthemenight,`LordaeronFallNight`,WESTRING_AMBIENTTHEMENIGHT_F\nAmbientThemeNightL=0,ambientthemenight,`LordaeronSummerNight`,WESTRING_AMBIENTTHEMENIGHT_L\nAmbientThemeNightW=0,ambientthemenight,`LordaeronWinterNight`,WESTRING_AMBIENTTHEMENIGHT_W\nAmbientThemeNightN=0,ambientthemenight,`NorthrendNight`,WESTRING_AMBIENTTHEMENIGHT_N\nAmbientThemeNightO=1,ambientthemenight,`BlackCitadelNight`,WESTRING_AMBIENTTHEMENIGHT_O\nAmbientThemeNightZ=1,ambientthemenight,`SunkenRuinsNight`,WESTRING_AMBIENTTHEMENIGHT_Z\nAmbientThemeNightV=0,ambientthemenight,`VillageNight`,WESTRING_AMBIENTTHEMENIGHT_V\nAmbientThemeNightQ=0,ambientthemenight,`VillageFallNight`,WESTRING_AMBIENTTHEMENIGHT_Q\nUnitStateMethodAbsolute=0,unitstatemethod,bj_UNIT_STATE_METHOD_ABSOLUTE,WESTRING_UNITSTATEMETHOD_ABSOLUTE\nUnitStateMethodRelative=0,unitstatemethod,bj_UNIT_STATE_METHOD_RELATIVE,WESTRING_UNITSTATEMETHOD_RELATIVE\nUnitStateMethodDefaults=0,unitstatemethod,bj_UNIT_STATE_METHOD_DEFAULTS,WESTRING_UNITSTATEMETHOD_DEFAULTS\nUnitStateMethodMaximum=0,unitstatemethod,bj_UNIT_STATE_METHOD_MAXIMUM,WESTRING_UNITSTATEMETHOD_MAXIMUM\nCheckingIgnoringChecking=0,checkingignoringoption,true,WESTRING_CHECKINGIGNORINGOPTION_CHECKING\nCheckingIgnoringIgnoring=0,checkingignoringoption,false,WESTRING_CHECKINGIGNORINGOPTION_IGNORING\nPathingOn=0,pathingoption,true,WESTRING_PATHING_ON\nPathingOff=0,pathingoption,false,WESTRING_PATHING_OFF\nPawnableOptionPawnable=1,pawnableoption,true,WESTRING_PAWNABLEOPTION_PAWNABLE\nPawnableOptionUnpawnable=1,pawnableoption,false,WESTRING_PAWNABLEOPTION_UNPAWNABLE\nDropNoDropOptionDrop=0,dropnodropoption,true,WESTRING_DROPNODROPOPTION_DROP\nDropNoDropOptionNoDrop=0,dropnodropoption,false,WESTRING_DROPNODROPOPTION_NODROP\nDroppableOptionDrop=0,droppableoption,true,WESTRING_DROPPABLE_DROP\nDroppableOptionNoDrop=0,droppableoption,false,WESTRING_DROPPABLE_NODROP\nBeforeAfterBefore=0,beforeafteroption,false,WESTRING_BEFOREAFTER_BEFORE\nBeforeAfterAfter=0,beforeafteroption,true,WESTRING_BEFOREAFTER_AFTER\nOnOffOn=0,onoffoption,true,WESTRING_ONOFF_ON\nOnOffOff=0,onoffoption,false,WESTRING_ONOFF_OFF\nEnableDisableEnable=0,enabledisableoption,true,WESTRING_ENABLEDISABLE_ENABLE\nEnableDisableDisable=0,enabledisableoption,false,WESTRING_ENABLEDISABLE_DISABLE\nEnabledDisabledEnabled=0,enableddisabledoption,true,WESTRING_ENABLEDDISABLED_ENABLED\nEnabledDisabledDisabled=0,enableddisabledoption,false,WESTRING_ENABLEDDISABLED_DISABLED\nRescuableOptionRescuable=0,rescuableoption,true,WESTRING_RESCUABLEOPTION_RESCUABLE\nRescuableOptionUnrescuable=0,rescuableoption,false,WESTRING_RESCUABLEOPTION_UNRESCUABLE\nAllowDontAllow=0,allowdontoption,true,WESTRING_ALLOWDONTOPTION_ALLOW\nAllowDontDont=0,allowdontoption,false,WESTRING_ALLOWDONTOPTION_DONT\nFadeDontFade=0,fadedontoption,true,WESTRING_FADEDONTOPTION_FADE\nFadeDontDont=0,fadedontoption,false,WESTRING_FADEDONTOPTION_DONT\nAddSetToAdd=0,addsettooption,bj_TIMETYPE_ADD,WESTRING_ADDSETTOOPTION_ADD\nAddSetToSub=0,addsettooption,bj_TIMETYPE_SUB,WESTRING_ADDSETTOOPTION_SUB\nAddSetToSet=0,addsettooption,bj_TIMETYPE_SET,WESTRING_ADDSETTOOPTION_SET\nModifyMethodAdd=1,modifymethod,bj_MODIFYMETHOD_ADD,WESTRING_MODIFYMETHOD_ADD\nModifyMethodSub=1,modifymethod,bj_MODIFYMETHOD_SUB,WESTRING_MODIFYMETHOD_SUB\nModifyMethodSet=1,modifymethod,bj_MODIFYMETHOD_SET,WESTRING_MODIFYMETHOD_SET\nWaitDontWait=0,waitdontoption,true,WESTRING_WAITDONTOPTION_WAIT\nWaitDontDont=0,waitdontoption,false,WESTRING_WAITDONTOPTION_DONT\nCraterTypeTemporary=1,cratertype,false,WESTRING_CRATERTYPE_TEMPORARY\nCraterTypePermanent=1,cratertype,true,WESTRING_CRATERTYPE_PERMANENT\nRippleTypeNormal=1,rippletype,false,WESTRING_RIPPLETYPE_NORMAL\nRippleTypeDepression=1,rippletype,true,WESTRING_RIPPLETYPE_DEPRESSION\nCreateRemoveCreate=0,createremoveoption,true,WESTRING_CREATEREMOVEOPTION_CREATE\nCreateRemoveRemove=0,createremoveoption,false,WESTRING_CREATEREMOVEOPTION_REMOVE\nAddRemoveAdd=0,addremoveoption,true,WESTRING_ADDREMOVEOPTION_ADD\nAddRemoveRemove=0,addremoveoption,false,WESTRING_ADDREMOVEOPTION_REMOVE\nQuestTypeReqDiscovered=0,questtypeoption,bj_QUESTTYPE_REQ_DISCOVERED,WESTRING_QUESTTYPE_REQ_DISCOVERED\nQuestTypeOptDiscovered=0,questtypeoption,bj_QUESTTYPE_OPT_DISCOVERED,WESTRING_QUESTTYPE_OPT_DISCOVERED\nQuestTypeReqUndiscovered=0,questtypeoption,bj_QUESTTYPE_REQ_UNDISCOVERED,WESTRING_QUESTTYPE_REQ_UNDISCOVERED\nQuestTypeOptUndiscovered=0,questtypeoption,bj_QUESTTYPE_OPT_UNDISCOVERED,WESTRING_QUESTTYPE_OPT_UNDISCOVERED\nQuestMessageTypeDiscovered=0,questmessagetype,bj_QUESTMESSAGE_DISCOVERED,WESTRING_QUESTMESSAGE_DISCOVERED\nQuestMessageTypeUpdated=0,questmessagetype,bj_QUESTMESSAGE_UPDATED,WESTRING_QUESTMESSAGE_UPDATED\nQuestMessageTypeCompleted=0,questmessagetype,bj_QUESTMESSAGE_COMPLETED,WESTRING_QUESTMESSAGE_COMPLETED\nQuestMessageTypeFailed=0,questmessagetype,bj_QUESTMESSAGE_FAILED,WESTRING_QUESTMESSAGE_FAILED\nQuestMessageTypeRequirement=0,questmessagetype,bj_QUESTMESSAGE_REQUIREMENT,WESTRING_QUESTMESSAGE_REQUIREMENT\nQuestMessageTypeMissionFailed=0,questmessagetype,bj_QUESTMESSAGE_MISSIONFAILED,WESTRING_QUESTMESSAGE_MISSIONFAILED\nQuestMessageTypeAlwaysHint=0,questmessagetype,bj_QUESTMESSAGE_ALWAYSHINT,WESTRING_QUESTMESSAGE_ALWAYSHINT\nQuestMessageTypeHint=0,questmessagetype,bj_QUESTMESSAGE_HINT,WESTRING_QUESTMESSAGE_HINT\nQuestMessageTypeSecret=0,questmessagetype,bj_QUESTMESSAGE_SECRET,WESTRING_QUESTMESSAGE_SECRET\nQuestMessageTypeWarning=1,questmessagetype,bj_QUESTMESSAGE_WARNING,WESTRING_QUESTMESSAGE_WARNING\nQuestMessageTypeUnitAcquired=0,questmessagetype,bj_QUESTMESSAGE_UNITACQUIRED,WESTRING_QUESTMESSAGE_UNITACQUIRED\nQuestMessageTypeUnitAvailable=0,questmessagetype,bj_QUESTMESSAGE_UNITAVAILABLE,WESTRING_QUESTMESSAGE_UNITAVAILABLE\nQuestMessageTypeItemAcquired=0,questmessagetype,bj_QUESTMESSAGE_ITEMACQUIRED,WESTRING_QUESTMESSAGE_ITEMACQUIRED\nHeroStatStr=1,herostat,bj_HEROSTAT_STR,WESTRING_HEROSTAT_STR\nHeroStatAgi=1,herostat,bj_HEROSTAT_AGI,WESTRING_HEROSTAT_AGI\nHeroStatInt=1,herostat,bj_HEROSTAT_INT,WESTRING_HEROSTAT_INT\nCompletionOptionCompleted=0,completionoption,true,WESTRING_COMPLETIONOPTION_COMPLETED\nCompletionOptionIncomplete=0,completionoption,false,WESTRING_COMPLETIONOPTION_INCOMPLETE\nFailureOptionFailed=0,failureoption,true,WESTRING_FAILUREOPTION_FAILED\nFailureOptionNotFailed=0,failureoption,false,WESTRING_FAILUREOPTION_NOTFAILED\nDiscoveredOptionDiscovered=0,discoveredoption,true,WESTRING_DISCOVEREDOPTION_DISCOVERED\nDiscoveredOptionUndiscovered=0,discoveredoption,false,WESTRING_DISCOVEREDOPTION_UNDISCOVERED\nPauseResumePause=0,pauseresumeoption,true,WESTRING_PAUSERESUMEOPTION_PAUSE\nPauseResumeResume=0,pauseresumeoption,false,WESTRING_PAUSERESUMEOPTION_RESUME\nPeriodicOptionOneTime=0,periodicoption,false,WESTRING_PERIODICOPTION_ONETIME\nPeriodicOptionPeriodic=0,periodicoption,true,WESTRING_PERIODICOPTION_PERIODIC\nLeaderboardSortByValue=0,leaderboardsortoption,bj_SORTTYPE_SORTBYVALUE,WESTRING_LEADERBOARDSORT_BYVALUE\nLeaderboardSortByPlayer=0,leaderboardsortoption,bj_SORTTYPE_SORTBYPLAYER,WESTRING_LEADERBOARDSORT_BYPLAYER\nLeaderboardSortByLabel=0,leaderboardsortoption,bj_SORTTYPE_SORTBYLABEL,WESTRING_LEADERBOARDSORT_BYLABEL\nAscendingOptionAscending=0,ascendingoption,true,WESTRING_ASCENDINGOPTION_ASCENDING\nAscendingOptionDescending=0,ascendingoption,false,WESTRING_ASCENDINGOPTION_DESCENDING\nSleepWakeOptionSleep=0,sleepwakeoption,true,WESTRING_SLEEPWAKEOPTION_SLEEP\nSleepWakeOptionWake=0,sleepwakeoption,false,WESTRING_SLEEPWAKEOPTION_WAKE\nPauseUnpauseOptionPause=0,pauseunpauseoption,true,WESTRING_PAUSEUNPAUSEOPTION_PAUSE\nPauseUnpauseOptionUnpause=0,pauseunpauseoption,false,WESTRING_PAUSEUNPAUSEOPTION_UNPAUSE\nShareDontOptionShare=0,sharedontoption,true,WESTRING_SHAREDONTOPTION_SHARE\nShareDontOptionDont=0,sharedontoption,false,WESTRING_SHAREDONTOPTION_DONT\nFadeTypeOptionFadeOutIn=0,fadetypeoption,bj_CINEFADETYPE_FADEOUTIN,WESTRING_FADETYPEOPTION_FADEOUTIN\nFadeTypeOptionFadeOut=0,fadetypeoption,bj_CINEFADETYPE_FADEOUT,WESTRING_FADETYPEOPTION_FADEOUT\nFadeTypeOptionFadeIn=0,fadetypeoption,bj_CINEFADETYPE_FADEIN,WESTRING_FADETYPEOPTION_FADEIN\nBuffTypeAll=0,bufftype,bj_REMOVEBUFFS_ALL,WESTRING_BUFFTYPE_ALL\nBuffTypeNonTLife=1,bufftype,bj_REMOVEBUFFS_NONTLIFE,WESTRING_BUFFTYPE_NONTLIFE\nBuffTypePositive=0,bufftype,bj_REMOVEBUFFS_POSITIVE,WESTRING_BUFFTYPE_POSITIVE\nBuffTypeNegative=0,bufftype,bj_REMOVEBUFFS_NEGATIVE,WESTRING_BUFFTYPE_NEGATIVE\nBuffPolarityPositive=1,buffpolarity,bj_BUFF_POLARITY_POSITIVE,WESTRING_BUFF_POLARITY_POSITIVE\nBuffPolarityNegative=1,buffpolarity,bj_BUFF_POLARITY_NEGATIVE,WESTRING_BUFF_POLARITY_NEGATIVE\nBuffPolarityEither=1,buffpolarity,bj_BUFF_POLARITY_EITHER,WESTRING_BUFF_POLARITY_EITHER\nBuffResistMagic=1,buffresist,bj_BUFF_RESIST_MAGIC,WESTRING_BUFF_RESIST_MAGIC\nBuffResistPhysical=1,buffresist,bj_BUFF_RESIST_PHYSICAL,WESTRING_BUFF_RESIST_PHYSICAL\nBuffResistEither=1,buffresist,bj_BUFF_RESIST_EITHER,WESTRING_BUFF_RESIST_EITHER\nBuffResistBoth=1,buffresist,bj_BUFF_RESIST_BOTH,WESTRING_BUFF_RESIST_BOTH\nCameraBoundsAdjustAdd=0,cameraboundsadjusttype,bj_CAMERABOUNDS_ADJUST_ADD,WESTRING_CAMERABOUNDSADJUST_ADD\nCameraBoundsAdjustSub=0,cameraboundsadjusttype,bj_CAMERABOUNDS_ADJUST_SUB,WESTRING_CAMERABOUNDSADJUST_SUB\nAvailableOptionAvailable=0,availableoption,true,WESTRING_AVAILABLEOPTION_AVAILABLE\nAvailableOptionUnavailable=0,availableoption,false,WESTRING_AVAILABLEOPTION_UNAVAILABLE\nExplodeDontExplode=0,explodedontoption,true,WESTRING_EXPLODEDONTOPTION_EXPLODE\nExplodeDontDont=0,explodedontoption,false,WESTRING_EXPLODEDONTOPTION_DONT\nSuspendResumeSuspend=0,suspendresumeoption,true,WESTRING_SUSPENDRESUMEOPTION_SUSPEND\nSuspendResumeResume=0,suspendresumeoption,true,WESTRING_SUSPENDRESUMEOPTION_RESUME\nGameEventTourneySoon=1,gameevent,EVENT_GAME_TOURNAMENT_FINISH_SOON,WESTRING_GAMEEVENT_TOURNAMENTFINISHSOON\nGameEventTourneyNow=1,gameevent,EVENT_GAME_TOURNAMENT_FINISH_NOW,WESTRING_GAMEEVENT_TOURNAMENTFINISHNOW\nMissionIndexT00=0,missionindex,bj_MISSION_INDEX_T00,WESTRING_MISSION_INDEX_T00\nMissionIndexT01=0,missionindex,bj_MISSION_INDEX_T01,WESTRING_MISSION_INDEX_T01\nMissionIndexH00=0,missionindex,bj_MISSION_INDEX_H00,WESTRING_MISSION_INDEX_H00\nMissionIndexH01=0,missionindex,bj_MISSION_INDEX_H01,WESTRING_MISSION_INDEX_H01\nMissionIndexH02=0,missionindex,bj_MISSION_INDEX_H02,WESTRING_MISSION_INDEX_H02\nMissionIndexH03=0,missionindex,bj_MISSION_INDEX_H03,WESTRING_MISSION_INDEX_H03\nMissionIndexH04=0,missionindex,bj_MISSION_INDEX_H04,WESTRING_MISSION_INDEX_H04\nMissionIndexH05=0,missionindex,bj_MISSION_INDEX_H05,WESTRING_MISSION_INDEX_H05\nMissionIndexH06=0,missionindex,bj_MISSION_INDEX_H06,WESTRING_MISSION_INDEX_H06\nMissionIndexH07=0,missionindex,bj_MISSION_INDEX_H07,WESTRING_MISSION_INDEX_H07\nMissionIndexH08=0,missionindex,bj_MISSION_INDEX_H08,WESTRING_MISSION_INDEX_H08\nMissionIndexH09=0,missionindex,bj_MISSION_INDEX_H09,WESTRING_MISSION_INDEX_H09\nMissionIndexH10=0,missionindex,bj_MISSION_INDEX_H10,WESTRING_MISSION_INDEX_H10\nMissionIndexH11=0,missionindex,bj_MISSION_INDEX_H11,WESTRING_MISSION_INDEX_H11\nMissionIndexU00=0,missionindex,bj_MISSION_INDEX_U00,WESTRING_MISSION_INDEX_U00\nMissionIndexU01=0,missionindex,bj_MISSION_INDEX_U01,WESTRING_MISSION_INDEX_U01\nMissionIndexU02=0,missionindex,bj_MISSION_INDEX_U02,WESTRING_MISSION_INDEX_U02\nMissionIndexU03=0,missionindex,bj_MISSION_INDEX_U03,WESTRING_MISSION_INDEX_U03\nMissionIndexU05=0,missionindex,bj_MISSION_INDEX_U05,WESTRING_MISSION_INDEX_U05\nMissionIndexU07=0,missionindex,bj_MISSION_INDEX_U07,WESTRING_MISSION_INDEX_U07\nMissionIndexU08=0,missionindex,bj_MISSION_INDEX_U08,WESTRING_MISSION_INDEX_U08\nMissionIndexU09=0,missionindex,bj_MISSION_INDEX_U09,WESTRING_MISSION_INDEX_U09\nMissionIndexU10=0,missionindex,bj_MISSION_INDEX_U10,WESTRING_MISSION_INDEX_U10\nMissionIndexU11=0,missionindex,bj_MISSION_INDEX_U11,WESTRING_MISSION_INDEX_U11\nMissionIndexO00=0,missionindex,bj_MISSION_INDEX_O00,WESTRING_MISSION_INDEX_O00\nMissionIndexO01=0,missionindex,bj_MISSION_INDEX_O01,WESTRING_MISSION_INDEX_O01\nMissionIndexO02=0,missionindex,bj_MISSION_INDEX_O02,WESTRING_MISSION_INDEX_O02\nMissionIndexO03=0,missionindex,bj_MISSION_INDEX_O03,WESTRING_MISSION_INDEX_O03\nMissionIndexO04=0,missionindex,bj_MISSION_INDEX_O04,WESTRING_MISSION_INDEX_O04\nMissionIndexO05=0,missionindex,bj_MISSION_INDEX_O05,WESTRING_MISSION_INDEX_O05\nMissionIndexO06=0,missionindex,bj_MISSION_INDEX_O06,WESTRING_MISSION_INDEX_O06\nMissionIndexO07=0,missionindex,bj_MISSION_INDEX_O07,WESTRING_MISSION_INDEX_O07\nMissionIndexO08=0,missionindex,bj_MISSION_INDEX_O08,WESTRING_MISSION_INDEX_O08\nMissionIndexO09=0,missionindex,bj_MISSION_INDEX_O09,WESTRING_MISSION_INDEX_O09\nMissionIndexO10=0,missionindex,bj_MISSION_INDEX_O10,WESTRING_MISSION_INDEX_O10\nMissionIndexN00=0,missionindex,bj_MISSION_INDEX_N00,WESTRING_MISSION_INDEX_N00\nMissionIndexN01=0,missionindex,bj_MISSION_INDEX_N01,WESTRING_MISSION_INDEX_N01\nMissionIndexN02=0,missionindex,bj_MISSION_INDEX_N02,WESTRING_MISSION_INDEX_N02\nMissionIndexN03=0,missionindex,bj_MISSION_INDEX_N03,WESTRING_MISSION_INDEX_N03\nMissionIndexN04=0,missionindex,bj_MISSION_INDEX_N04,WESTRING_MISSION_INDEX_N04\nMissionIndexN05=0,missionindex,bj_MISSION_INDEX_N05,WESTRING_MISSION_INDEX_N05\nMissionIndexN06=0,missionindex,bj_MISSION_INDEX_N06,WESTRING_MISSION_INDEX_N06\nMissionIndexN07=0,missionindex,bj_MISSION_INDEX_N07,WESTRING_MISSION_INDEX_N07\nMissionIndexXN00=1,missionindex,bj_MISSION_INDEX_XN00,WESTRING_MISSION_INDEX_XN00\nMissionIndexXN01=1,missionindex,bj_MISSION_INDEX_XN01,WESTRING_MISSION_INDEX_XN01\nMissionIndexXN02=1,missionindex,bj_MISSION_INDEX_XN02,WESTRING_MISSION_INDEX_XN02\nMissionIndexXN03=1,missionindex,bj_MISSION_INDEX_XN03,WESTRING_MISSION_INDEX_XN03\nMissionIndexXN04=1,missionindex,bj_MISSION_INDEX_XN04,WESTRING_MISSION_INDEX_XN04\nMissionIndexXN05=1,missionindex,bj_MISSION_INDEX_XN05,WESTRING_MISSION_INDEX_XN05\nMissionIndexXN06=1,missionindex,bj_MISSION_INDEX_XN06,WESTRING_MISSION_INDEX_XN06\nMissionIndexXN07=1,missionindex,bj_MISSION_INDEX_XN07,WESTRING_MISSION_INDEX_XN07\nMissionIndexXN08=1,missionindex,bj_MISSION_INDEX_XN08,WESTRING_MISSION_INDEX_XN08\nMissionIndexXN09=1,missionindex,bj_MISSION_INDEX_XN09,WESTRING_MISSION_INDEX_XN09\nMissionIndexXN10=1,missionindex,bj_MISSION_INDEX_XN10,WESTRING_MISSION_INDEX_XN10\nMissionIndexXH00=1,missionindex,bj_MISSION_INDEX_XH00,WESTRING_MISSION_INDEX_XH00\nMissionIndexXH01=1,missionindex,bj_MISSION_INDEX_XH01,WESTRING_MISSION_INDEX_XH01\nMissionIndexXH02=1,missionindex,bj_MISSION_INDEX_XH02,WESTRING_MISSION_INDEX_XH02\nMissionIndexXH03=1,missionindex,bj_MISSION_INDEX_XH03,WESTRING_MISSION_INDEX_XH03\nMissionIndexXH04=1,missionindex,bj_MISSION_INDEX_XH04,WESTRING_MISSION_INDEX_XH04\nMissionIndexXH05=1,missionindex,bj_MISSION_INDEX_XH05,WESTRING_MISSION_INDEX_XH05\nMissionIndexXH06=1,missionindex,bj_MISSION_INDEX_XH06,WESTRING_MISSION_INDEX_XH06\nMissionIndexXH07=1,missionindex,bj_MISSION_INDEX_XH07,WESTRING_MISSION_INDEX_XH07\nMissionIndexXH08=1,missionindex,bj_MISSION_INDEX_XH08,WESTRING_MISSION_INDEX_XH08\nMissionIndexXH09=1,missionindex,bj_MISSION_INDEX_XH09,WESTRING_MISSION_INDEX_XH09\nMissionIndexXU00=1,missionindex,bj_MISSION_INDEX_XU00,WESTRING_MISSION_INDEX_XU00\nMissionIndexXU01=1,missionindex,bj_MISSION_INDEX_XU01,WESTRING_MISSION_INDEX_XU01\nMissionIndexXU02=1,missionindex,bj_MISSION_INDEX_XU02,WESTRING_MISSION_INDEX_XU02\nMissionIndexXU03=1,missionindex,bj_MISSION_INDEX_XU03,WESTRING_MISSION_INDEX_XU03\nMissionIndexXU04=1,missionindex,bj_MISSION_INDEX_XU04,WESTRING_MISSION_INDEX_XU04\nMissionIndexXU05=1,missionindex,bj_MISSION_INDEX_XU05,WESTRING_MISSION_INDEX_XU05\nMissionIndexXU06=1,missionindex,bj_MISSION_INDEX_XU06,WESTRING_MISSION_INDEX_XU06\nMissionIndexXU07=1,missionindex,bj_MISSION_INDEX_XU07,WESTRING_MISSION_INDEX_XU07\nMissionIndexXU08=1,missionindex,bj_MISSION_INDEX_XU08,WESTRING_MISSION_INDEX_XU08\nMissionIndexXU09=1,missionindex,bj_MISSION_INDEX_XU09,WESTRING_MISSION_INDEX_XU09\nMissionIndexXU10=1,missionindex,bj_MISSION_INDEX_XU10,WESTRING_MISSION_INDEX_XU10\nMissionIndexXU11=1,missionindex,bj_MISSION_INDEX_XU11,WESTRING_MISSION_INDEX_XU11\nMissionIndexXU12=1,missionindex,bj_MISSION_INDEX_XU12,WESTRING_MISSION_INDEX_XU12\nMissionIndexXU13=1,missionindex,bj_MISSION_INDEX_XU13,WESTRING_MISSION_INDEX_XU13\nMissionIndexXO00=1,missionindex,bj_MISSION_INDEX_XO00,WESTRING_MISSION_INDEX_XO00\nCampaignIndexT=0,campaignindex,bj_CAMPAIGN_INDEX_T,WESTRING_CAMPAIGN_INDEX_T\nCampaignIndexH=0,campaignindex,bj_CAMPAIGN_INDEX_H,WESTRING_CAMPAIGN_INDEX_H\nCampaignIndexU=0,campaignindex,bj_CAMPAIGN_INDEX_U,WESTRING_CAMPAIGN_INDEX_U\nCampaignIndexO=0,campaignindex,bj_CAMPAIGN_INDEX_O,WESTRING_CAMPAIGN_INDEX_O\nCampaignIndexN=0,campaignindex,bj_CAMPAIGN_INDEX_N,WESTRING_CAMPAIGN_INDEX_N\nCampaignIndexXN=1,campaignindex,bj_CAMPAIGN_INDEX_XN,WESTRING_CAMPAIGN_INDEX_XN\nCampaignIndexXH=1,campaignindex,bj_CAMPAIGN_INDEX_XH,WESTRING_CAMPAIGN_INDEX_XH\nCampaignIndexXU=1,campaignindex,bj_CAMPAIGN_INDEX_XU,WESTRING_CAMPAIGN_INDEX_XU\nCampaignIndexXO=1,campaignindex,bj_CAMPAIGN_INDEX_XO,WESTRING_CAMPAIGN_INDEX_XO\nCinematicIndexTOP=0,cinematicindex,bj_CINEMATICINDEX_TOP,WESTRING_CINEMATICTYPE_TOP\nCinematicIndexHOP=0,cinematicindex,bj_CINEMATICINDEX_HOP,WESTRING_CINEMATICTYPE_HOP\nCinematicIndexHED=0,cinematicindex,bj_CINEMATICINDEX_HED,WESTRING_CINEMATICTYPE_HED\nCinematicIndexUED=0,cinematicindex,bj_CINEMATICINDEX_UED,WESTRING_CINEMATICTYPE_UED\nCinematicIndexOED=0,cinematicindex,bj_CINEMATICINDEX_OED,WESTRING_CINEMATICTYPE_OED\nCinematicIndexNED=0,cinematicindex,bj_CINEMATICINDEX_NED,WESTRING_CINEMATICTYPE_NED\nCinematicIndexXOP=1,cinematicindex,bj_CINEMATICINDEX_XOP,WESTRING_CINEMATICTYPE_XOP\nCinematicIndexXED=1,cinematicindex,bj_CINEMATICINDEX_XED,WESTRING_CINEMATICTYPE_XED\nPlayerResourceGold=1,playerresource,PLAYER_STATE_RESOURCE_GOLD,WESTRING_PRESOURCE_GOLD\nPlayerResourceLumber=1,playerresource,PLAYER_STATE_RESOURCE_LUMBER,WESTRING_PRESOURCE_LUMBER\nUnitOrderClusterRockets=1,unitorderptarg,`clusterrockets`,WESTRING_UNITORDERPTARG_CLUSTERROCKETS\nUnitOrderSummonFactory=1,unitorderptarg,`summonfactory`,WESTRING_UNITORDERPTARG_SUMMONFACTORY\nHeroSkillEngineeringUpgrade=1,heroskillcode,'ANeg',WESTRING_HEROSKILL_ENGINEERINGUPGRADE\nHeroSkillClusterRockets=1,heroskillcode,'ANcs',WESTRING_HEROSKILL_CLUSTERROCKETS\nHeroSkillSummonFactory=1,heroskillcode,'ANsy',WESTRING_HEROSKILL_SUMMONFACTORY\nHeroSkillRoboGoblin=1,heroskillcode,'ANrg',WESTRING_HEROSKILL_ROBOGOBLIN\nInstantOrderGive=0,unitorderinstant,`dropitem`,WESTRING_INSTANTORDER_GIVE\nItemOrderAttack=0,unitorderitarg,`attack`,WESTRING_UNITORDERITARGOLD_ATTACK\nItemOrderAttackOnce=0,unitorderitarg,`attackonce`,WESTRING_UNITORDERITARGOLD_ATTONCE\nItemOrderMoveTo=0,unitorderitarg,`move`,WESTRING_UNITORDERITARGOLD_MOVE\nItemOrderPickUp=0,unitorderitarg,`getitem`,WESTRING_UNITORDERITARGOLD_PICKUP\nOrderCodeItemSlot0=0,ordercode,852002,WESTRING_UNITORDERUTARG_SLOT0\nOrderCodeItemSlot1=0,ordercode,852003,WESTRING_UNITORDERUTARG_SLOT1\nOrderCodeItemSlot2=0,ordercode,852004,WESTRING_UNITORDERUTARG_SLOT2\nOrderCodeItemSlot3=0,ordercode,852005,WESTRING_UNITORDERUTARG_SLOT3\nOrderCodeItemSlot4=0,ordercode,852006,WESTRING_UNITORDERUTARG_SLOT4\nOrderCodeItemSlot5=0,ordercode,852007,WESTRING_UNITORDERUTARG_SLOT5\nOrderCodeUseSlot0=0,ordercode,852008,WESTRING_UNITORDER_USESLOT0\nOrderCodeUseSlot1=0,ordercode,852009,WESTRING_UNITORDER_USESLOT1\nOrderCodeUseSlot2=0,ordercode,852010,WESTRING_UNITORDER_USESLOT2\nOrderCodeUseSlot3=0,ordercode,852011,WESTRING_UNITORDER_USESLOT3\nOrderCodeUseSlot4=0,ordercode,852012,WESTRING_UNITORDER_USESLOT4\nOrderCodeUseSlot5=0,ordercode,852013,WESTRING_UNITORDER_USESLOT5\nOrderCodeDoCancel=0,ordercode,851976,WESTRING_UNITORDERUTARG_CANCEL\nOrderCodeAttackUnit=0,ordercode,String2OrderIdBJ(\"attack\"),WESTRING_UNITORDERUTARG_ATTACK\nOrderCodeAttackGround=0,ordercode,String2OrderIdBJ(\"attackground\"),WESTRING_UNITORDERPTARG_ATTACKGROUND\nOrderCodeAttackUnitOnce=0,ordercode,String2OrderIdBJ(\"attackonce\"),WESTRING_UNITORDERUTARG_ATTACKONCE\nOrderCodeAutoHarvestGold=0,ordercode,String2OrderIdBJ(\"autoharvestgold\"),WESTRING_UNITORDERNOTARG_AUTOHARVESTGOLD\nOrderCodeAutoHarvestLumber=0,ordercode,String2OrderIdBJ(\"autoharvestlumber\"),WESTRING_UNITORDERNOTARG_AUTOHARVESTLUMBER\nOrderCodeAwaken=1,ordercode,String2OrderIdBJ(\"awaken\"),WESTRING_UNITORDERNOTARG_AWAKEN\nOrderCodeBoard=0,ordercode,String2OrderIdBJ(\"board\"),WESTRING_UNITORDERUTARG_BOARD\nOrderCodeBuild=1,ordercode,String2OrderIdBJ(\"build\"),WESTRING_UNITORDERNOTARG_BUILD\nOrderCodeForceBoard=0,ordercode,String2OrderIdBJ(\"forceboard\"),WESTRING_UNITORDERUTARG_FORCEBOARD\nOrderCodeHarvest=0,ordercode,String2OrderIdBJ(\"harvest\"),WESTRING_UNITORDERUTARG_HARVEST\nOrderCodeHoldPosition=0,ordercode,String2OrderIdBJ(\"holdposition\"),WESTRING_UNITORDERNOTARG_HOLDPOSITION\nOrderCodeLevelup=1,ordercode,String2OrderIdBJ(\"levelup\"),WESTRING_UNITORDERNOTARG_LEVELUP\nOrderCodeLoad=0,ordercode,String2OrderIdBJ(\"load\"),WESTRING_UNITORDERUTARG_LOAD\nOrderCodeMoveUnit=0,ordercode,String2OrderIdBJ(\"move\"),WESTRING_UNITORDERPTARG_MOVE\nOrderCodePatrol=0,ordercode,String2OrderIdBJ(\"patrol\"),WESTRING_UNITORDERPTARG_PATROL\nOrderCodeReturnResources=0,ordercode,String2OrderIdBJ(\"returnresources\"),WESTRING_UNITORDERNOTARG_RETURNRESOURCES\nOrderCodeRevive=0,ordercode,String2OrderIdBJ(\"revive\"),WESTRING_UNITORDERUTARG_REVIVE\nOrderCodeSmart=1,ordercode,String2OrderIdBJ(\"smart\"),WESTRING_UNITORDERUTARG_SMART\nOrderCodeSetRally=0,ordercode,String2OrderIdBJ(\"setrally\"),WESTRING_UNITORDERPTARG_SETRALLY\nOrderCodeStop=0,ordercode,String2OrderIdBJ(\"stop\"),WESTRING_UNITORDERNOTARG_STOP\nOrderCodeUnload=0,ordercode,String2OrderIdBJ(\"unload\"),WESTRING_UNITORDERUTARG_UNLOAD\nOrderCodeUnloadAll=0,ordercode,String2OrderIdBJ(\"unloadall\"),WESTRING_UNITORDERPTARG_UNLOADALL\nOrderCodeNull=0,ordercode,String2OrderIdBJ(\"(null)\"),WESTRING_UNITORDERUTARG_NULL\nOrderCodeResumeHarvesting=0,ordercode,String2OrderIdBJ(\"resumeharvesting\"),WESTRING_UNITORDERUTARG_RESUMEHARVESTING\nOrderCodeUnloadAllInstant=0,ordercode,String2OrderIdBJ(\"unloadallinstant\"),WESTRING_UNITORDERPTARG_UNLOADALLINSTANT\nOrderCodeHumanBuild=1,ordercode,String2OrderIdBJ(\"humanbuild\"),WESTRING_UNITORDERNOTARG_HUMANBUILD\nOrderCodeBlizzard=0,ordercode,String2OrderIdBJ(\"blizzard\"),WESTRING_UNITORDERPTARG_BLIZZARD\nOrderCodeWaterElemental=0,ordercode,String2OrderIdBJ(\"waterelemental\"),WESTRING_UNITORDERNOTARG_WATERELEMENTAL\nOrderCodeMassTeleport=0,ordercode,String2OrderIdBJ(\"massteleport\"),WESTRING_UNITORDERUTARG_MASSTELEPORT\nOrderCodeBanish=1,ordercode,String2OrderIdBJ(\"banish\"),WESTRING_UNITORDERUTARG_BANISH\nOrderCodeFlameStrike=1,ordercode,String2OrderIdBJ(\"flamestrike\"),WESTRING_UNITORDERPTARG_FLAMESTRIKE\nOrderCodePhoenix=1,ordercode,String2OrderIdBJ(\"phoenix\"),WESTRING_UNITORDERNOTARG_PHOENIX\nOrderCodeSiphonMana=1,ordercode,String2OrderIdBJ(\"drain\"),WESTRING_UNITORDERUTARG_SIPHONMANA\nOrderCodeAerialShackles=1,ordercode,String2OrderIdBJ(\"magicleash\"),WESTRING_UNITORDERUTARG_AERIALSHACKLES\nOrderCodeCloudOfFog=1,ordercode,String2OrderIdBJ(\"cloudoffog\"),WESTRING_UNITORDERPTARG_CLOUDOFFOG\nOrderCodeDefend=0,ordercode,String2OrderIdBJ(\"defend\"),WESTRING_UNITORDERNOTARG_DEFEND\nOrderCodeUnDefend=0,ordercode,String2OrderIdBJ(\"undefend\"),WESTRING_UNITORDERNOTARG_UNDEFEND\nOrderCodeMilitiaOff=0,ordercode,String2OrderIdBJ(\"militiaoff\"),WESTRING_UNITORDERNOTARG_MILITIAOFF\nOrderCodeFlare=0,ordercode,String2OrderIdBJ(\"flare\"),WESTRING_UNITORDERPTARG_FLARE\nOrderCodeAvatar=0,ordercode,String2OrderIdBJ(\"avatar\"),WESTRING_UNITORDERNOTARG_AVATAR\nOrderCodeThunderBolt=0,ordercode,String2OrderIdBJ(\"thunderbolt\"),WESTRING_UNITORDERUTARG_THUNDERBOLT\nOrderCodeThunderClap=0,ordercode,String2OrderIdBJ(\"thunderclap\"),WESTRING_UNITORDERNOTARG_THUNDERCLAP\nOrderCodeDivineShield=0,ordercode,String2OrderIdBJ(\"divineshield\"),WESTRING_UNITORDERNOTARG_DIVINESHIELD\nOrderCodeUnDivineShield=0,ordercode,String2OrderIdBJ(\"undivineshield\"),WESTRING_UNITORDERNOTARG_UNDIVINESHIELD\nOrderCodeHolyBolt=0,ordercode,String2OrderIdBJ(\"holybolt\"),WESTRING_UNITORDERUTARG_HOLYBOLT\nOrderCodeResurrection=0,ordercode,String2OrderIdBJ(\"resurrection\"),WESTRING_UNITORDERNOTARG_RESURRECTION\nOrderCodeMilitia=0,ordercode,String2OrderIdBJ(\"militia\"),WESTRING_UNITORDERNOTARG_MILITIA\nOrderCodeRepair=0,ordercode,String2OrderIdBJ(\"repair\"),WESTRING_UNITORDERUTARG_REPAIR\nOrderCodeRepairOn=0,ordercode,String2OrderIdBJ(\"repairon\"),WESTRING_UNITORDERNOTARG_REPAIRON\nOrderCodeRepairOff=0,ordercode,String2OrderIdBJ(\"repairoff\"),WESTRING_UNITORDERNOTARG_REPAIROFF\nOrderCodeHeal=0,ordercode,String2OrderIdBJ(\"heal\"),WESTRING_UNITORDERUTARG_HEAL\nOrderCodeHealOn=0,ordercode,String2OrderIdBJ(\"healon\"),WESTRING_UNITORDERNOTARG_HEALON\nOrderCodeHealOff=0,ordercode,String2OrderIdBJ(\"healoff\"),WESTRING_UNITORDERNOTARG_HEALOFF\nOrderCodeDispel=0,ordercode,String2OrderIdBJ(\"dispel\"),WESTRING_UNITORDERUTARG_DISPEL\nOrderCodeInnerFire=0,ordercode,String2OrderIdBJ(\"innerfire\"),WESTRING_UNITORDERUTARG_INNERFIRE\nOrderCodeInnerFireOn=0,ordercode,String2OrderIdBJ(\"innerfireon\"),WESTRING_UNITORDERNOTARG_INNERFIREON\nOrderCodeInnerFireOff=0,ordercode,String2OrderIdBJ(\"innerfireoff\"),WESTRING_UNITORDERNOTARG_INNERFIREOFF\nOrderCodeInvisibility=0,ordercode,String2OrderIdBJ(\"invisibility\"),WESTRING_UNITORDERUTARG_INVISIBILITY\nOrderCodePolymorph=0,ordercode,String2OrderIdBJ(\"polymorph\"),WESTRING_UNITORDERUTARG_POLYMORPH\nOrderCodeSlow=0,ordercode,String2OrderIdBJ(\"slow\"),WESTRING_UNITORDERUTARG_SLOW\nOrderCodeSlowOn=0,ordercode,String2OrderIdBJ(\"slowon\"),WESTRING_UNITORDERNOTARG_SLOWON\nOrderCodeSlowOff=0,ordercode,String2OrderIdBJ(\"slowoff\"),WESTRING_UNITORDERNOTARG_SLOWOFF\nOrderCodeControlMagic=1,ordercode,String2OrderIdBJ(\"controlmagic\"),WESTRING_UNITORDERUTARG_CONTROLMAGIC\nOrderCodeSpellSteal=1,ordercode,String2OrderIdBJ(\"spellsteal\"),WESTRING_UNITORDERNOTARG_SPELLSTEAL\nOrderCodeSpellStealOn=1,ordercode,String2OrderIdBJ(\"spellstealon\"),WESTRING_UNITORDERNOTARG_SPELLSTEALON\nOrderCodeSpellStealOff=1,ordercode,String2OrderIdBJ(\"spellstealoff\"),WESTRING_UNITORDERNOTARG_SPELLSTEALOFF\nOrderCodeTownBellOn=0,ordercode,String2OrderIdBJ(\"townbellon\"),WESTRING_UNITORDERNOTARG_TOWNBELLON\nOrderCodeTownBellOff=0,ordercode,String2OrderIdBJ(\"townbelloff\"),WESTRING_UNITORDERNOTARG_TOWNBELLOFF\nOrderCodeOrcBuild=1,ordercode,String2OrderIdBJ(\"orcbuild\"),WESTRING_UNITORDERNOTARG_ORCBUILD\nOrderCodeBattleStations=0,ordercode,String2OrderIdBJ(\"battlestations\"),WESTRING_UNITORDERNOTARG_BATTLESTATIONS\nOrderCodeStandDown=0,ordercode,String2OrderIdBJ(\"standdown\"),WESTRING_UNITORDERNOTARG_STANDDOWN\nOrderCodeBloodlust=0,ordercode,String2OrderIdBJ(\"bloodlust\"),WESTRING_UNITORDERUTARG_BLOODLUST\nOrderCodeBloodlustOn=0,ordercode,String2OrderIdBJ(\"bloodluston\"),WESTRING_UNITORDERNOTARG_BLOODLUSTON\nOrderCodeBloodlustOff=0,ordercode,String2OrderIdBJ(\"bloodlustoff\"),WESTRING_UNITORDERNOTARG_BLOODLUSTOFF\nOrderCodeChainLightning=0,ordercode,String2OrderIdBJ(\"chainlightning\"),WESTRING_UNITORDERUTARG_CHAINLIGHTNING\nOrderCodeDevour=0,ordercode,String2OrderIdBJ(\"devour\"),WESTRING_UNITORDERUTARG_DEVOUR\nOrderCodeDisenchant=1,ordercode,String2OrderIdBJ(\"disenchant\"),WESTRING_UNITORDERPTARG_DISENCHANT\nOrderCodeEarthquake=0,ordercode,String2OrderIdBJ(\"earthquake\"),WESTRING_UNITORDERPTARG_EARTHQUAKE\nOrderCodeEnsnare=0,ordercode,String2OrderIdBJ(\"ensnare\"),WESTRING_UNITORDERUTARG_ENSNARE\nOrderCodeSentryWard=0,ordercode,String2OrderIdBJ(\"evileye\"),WESTRING_UNITORDERPTARG_SENTRYWARD\nOrderCodeFarSight=0,ordercode,String2OrderIdBJ(\"farsight\"),WESTRING_UNITORDERPTARG_FARSIGHT\nOrderCodeHealingWard=0,ordercode,String2OrderIdBJ(\"healingward\"),WESTRING_UNITORDERPTARG_HEALINGWARD\nOrderCodeHealingWave=1,ordercode,String2OrderIdBJ(\"healingwave\"),WESTRING_UNITORDERUTARG_HEALINGWAVE\nOrderCodeHex=1,ordercode,String2OrderIdBJ(\"hex\"),WESTRING_UNITORDERUTARG_HEX\nOrderCodeLightningShield=0,ordercode,String2OrderIdBJ(\"lightningshield\"),WESTRING_UNITORDERUTARG_LIGHTNINGSHIELD\nOrderCodeMirrorImage=0,ordercode,String2OrderIdBJ(\"mirrorimage\"),WESTRING_UNITORDERNOTARG_MIRRORIMAGE\nOrderCodePurge=0,ordercode,String2OrderIdBJ(\"purge\"),WESTRING_UNITORDERUTARG_PURGE\nOrderCodeRepair=0,ordercode,String2OrderIdBJ(\"repair\"),WESTRING_UNITORDERUTARG_REPAIRO\nOrderCodeRepairOOn=0,ordercode,String2OrderIdBJ(\"repairon\"),WESTRING_UNITORDERNOTARG_REPAIROON\nOrderCodeRepairOOff=0,ordercode,String2OrderIdBJ(\"repairoff\"),WESTRING_UNITORDERNOTARG_REPAIROOFF\nOrderCodeSerpentWard=1,ordercode,String2OrderIdBJ(\"ward\"),WESTRING_UNITORDERPTARG_SERPENTWARD\nOrderCodeShockwave=0,ordercode,String2OrderIdBJ(\"shockwave\"),WESTRING_UNITORDERPTARG_SHOCKWAVE\nOrderCodeSpiritLink=1,ordercode,String2OrderIdBJ(\"spiritlink\"),WESTRING_UNITORDERUTARG_SPIRITLINK\nOrderCodeSpiritWolf=0,ordercode,String2OrderIdBJ(\"spiritwolf\"),WESTRING_UNITORDERNOTARG_FERALSPIRIT\nOrderCodeStasisTrap=0,ordercode,String2OrderIdBJ(\"stasistrap\"),WESTRING_UNITORDERPTARG_STASISTRAP\nOrderCodeStomp=0,ordercode,String2OrderIdBJ(\"stomp\"),WESTRING_UNITORDERNOTARG_WARSTOMP\nOrderCodeUnstableConcoction=1,ordercode,String2OrderIdBJ(\"unstableconcoction\"),WESTRING_UNITORDERUTARG_UNSTABLECONCOCTION\nOrderCodeWhirlWind=0,ordercode,String2OrderIdBJ(\"whirlwind\"),WESTRING_UNITORDERNOTARG_BLADESTORM\nOrderCodeWindWalk=0,ordercode,String2OrderIdBJ(\"windwalk\"),WESTRING_UNITORDERNOTARG_WINDWALK\nOrderCodeBerserk=1,ordercode,String2OrderIdBJ(\"berserk\"),WESTRING_UNITORDERNOTARG_BERSERK\nOrderCodeAncestralSpirit=1,ordercode,String2OrderIdBJ(\"ancestralspirit\"),WESTRING_UNITORDERNOTARG_ANCESTRALSPIRIT\nOrderCodeEtherealForm=1,ordercode,String2OrderIdBJ(\"uncorporealform\"),WESTRING_UNITORDERNOTARG_ETHEREALFORM\nOrderCodeCorporealForm=1,ordercode,String2OrderIdBJ(\"corporealform\"),WESTRING_UNITORDERNOTARG_CORPOREALFORM\nOrderCodeVoodoo=1,ordercode,String2OrderIdBJ(\"voodoo\"),WESTRING_UNITORDERNOTARG_VOODOO\nOrderCodeNightElfBuild=1,ordercode,String2OrderIdBJ(\"nightelfbuild\"),WESTRING_UNITORDERNOTARG_NIGHTELFBUILD\nOrderCodeBlink=1,ordercode,String2OrderIdBJ(\"blink\"),WESTRING_UNITORDERPTARG_BLINK\nOrderCodeRenew=0,ordercode,String2OrderIdBJ(\"renew\"),WESTRING_UNITORDERUTARG_RENEW\nOrderCodeEntangle=0,ordercode,String2OrderIdBJ(\"entangle\"),WESTRING_UNITORDERUTARG_ENTANGLE\nOrderCodeEntangleInstant=0,ordercode,String2OrderIdBJ(\"entangleinstant\"),WESTRING_UNITORDERUTARG_ENTANGLEINSTANT\nOrderCodeReplenish=0,ordercode,String2OrderIdBJ(\"replenish\"),WESTRING_UNITORDERUTARG_REPLENISH\nOrderCodeMountHippogryph=0,ordercode,String2OrderIdBJ(\"mounthippogryph\"),WESTRING_UNITORDERUTARG_MOUNTHIPPOGRYPH\nOrderCodeLoadArcher=0,ordercode,String2OrderIdBJ(\"loadarcher\"),WESTRING_UNITORDERUTARG_LOADARCHER\nOrderCodeAutoDispel=0,ordercode,String2OrderIdBJ(\"autodispel\"),WESTRING_UNITORDERUTARG_AUTODISPEL\nOrderCodeFaerieFire=0,ordercode,String2OrderIdBJ(\"faeriefire\"),WESTRING_UNITORDERUTARG_FAERIEFIRE\nOrderCodeCyclone=0,ordercode,String2OrderIdBJ(\"cyclone\"),WESTRING_UNITORDERUTARG_CYCLONE\nOrderCodeRejuvination=0,ordercode,String2OrderIdBJ(\"rejuvination\"),WESTRING_UNITORDERUTARG_REJUVINATION\nOrderCodeManaBurn=0,ordercode,String2OrderIdBJ(\"manaburn\"),WESTRING_UNITORDERUTARG_MANABURN\nOrderCodeEntanglingRoots=0,ordercode,String2OrderIdBJ(\"entanglingroots\"),WESTRING_UNITORDERUTARG_ENTANGLINGROOTS\nOrderCodeRoot=0,ordercode,String2OrderIdBJ(\"root\"),WESTRING_UNITORDERPTARG_ROOT\nOrderCodeDetonate=0,ordercode,String2OrderIdBJ(\"detonate\"),WESTRING_UNITORDERPTARG_DETONATE\nOrderCodeForceOfNature=0,ordercode,String2OrderIdBJ(\"forceofnature\"),WESTRING_UNITORDERPTARG_FORCEOFNATURE\nOrderCodeStarfall=0,ordercode,String2OrderIdBJ(\"rainoffire\"),WESTRING_UNITORDERPTARG_STARFALL\nOrderCodeConsumeTree=0,ordercode,String2OrderIdBJ(\"eattree\"),WESTRING_unitorderdtarg_CONSUMETREE\nOrderCodeSentinel=0,ordercode,String2OrderIdBJ(\"sentinel\"),WESTRING_unitorderdtarg_SENTINEL\nOrderCodeUnRoot=0,ordercode,String2OrderIdBJ(\"unroot\"),WESTRING_UNITORDERNOTARG_UNROOT\nOrderCodeAmbush=0,ordercode,String2OrderIdBJ(\"ambush\"),WESTRING_UNITORDERNOTARG_HIDE\nOrderCodeRenewOn=0,ordercode,String2OrderIdBJ(\"renewon\"),WESTRING_UNITORDERNOTARG_RENEWON\nOrderCodeRenewOff=0,ordercode,String2OrderIdBJ(\"renewoff\"),WESTRING_UNITORDERNOTARG_RENEWOFF\nOrderCodeAutoDispelOn=0,ordercode,String2OrderIdBJ(\"autodispelon\"),WESTRING_UNITORDERNOTARG_AUTODISPELON\nOrderCodeAutoDispelOff=0,ordercode,String2OrderIdBJ(\"autodispeloff\"),WESTRING_UNITORDERNOTARG_AUTODISPELOFF\nOrderCodeFaerieFireOn=0,ordercode,String2OrderIdBJ(\"faeriefireon\"),WESTRING_UNITORDERNOTARG_FAERIEFIREON\nOrderCodeFaerieFireOff=0,ordercode,String2OrderIdBJ(\"faeriefireoff\"),WESTRING_UNITORDERNOTARG_FAERIEFIREOFF\nOrderCodeRavenForm=0,ordercode,String2OrderIdBJ(\"ravenform\"),WESTRING_UNITORDERNOTARG_RAVENFORM\nOrderCodeUnRavenForm=0,ordercode,String2OrderIdBJ(\"unravenform\"),WESTRING_UNITORDERNOTARG_UNRAVENFORM\nOrderCodeRoar=0,ordercode,String2OrderIdBJ(\"roar\"),WESTRING_UNITORDERNOTARG_ROAR\nOrderCodeBearForm=0,ordercode,String2OrderIdBJ(\"bearform\"),WESTRING_UNITORDERNOTARG_BEARFORM\nOrderCodeUnBearForm=0,ordercode,String2OrderIdBJ(\"unbearform\"),WESTRING_UNITORDERNOTARG_UNBEARFORM\nOrderCodeImmolation=0,ordercode,String2OrderIdBJ(\"immolation\"),WESTRING_UNITORDERNOTARG_IMMOLATION\nOrderCodeUnImmolation=0,ordercode,String2OrderIdBJ(\"unimmolation\"),WESTRING_UNITORDERNOTARG_UNIMMOLATION\nOrderCodeMetamorphosis=0,ordercode,String2OrderIdBJ(\"metamorphosis\"),WESTRING_UNITORDERNOTARG_METAMORPHOSIS\nOrderCodeTranquility=0,ordercode,String2OrderIdBJ(\"tranquility\"),WESTRING_UNITORDERNOTARG_TRANQUILITY\nOrderCodeSearingArrows=0,ordercode,String2OrderIdBJ(\"flamingarrows\"),WESTRING_UNITORDERNOTARG_SEARINGARROWS\nOrderCodeUnSearingArrows=0,ordercode,String2OrderIdBJ(\"unflamingarrows\"),WESTRING_UNITORDERNOTARG_UNSEARINGARROWS\nOrderCodeVengeance=1,ordercode,String2OrderIdBJ(\"vengeance\"),WESTRING_UNITORDERUTARG_VENGEANCE\nOrderCodeScout=0,ordercode,String2OrderIdBJ(\"scout\"),WESTRING_UNITORDERNOTARG_SCOUT\nOrderCodeShadowStrike=1,ordercode,String2OrderIdBJ(\"shadowstrike\"),WESTRING_UNITORDERUTARG_SHADOWSTRIKE\nOrderCodeGrabTree=1,ordercode,String2OrderIdBJ(\"grabtree\"),WESTRING_UNITORDERDTARG_GRABTREE\nOrderCodeAutoEntangle=1,ordercode,String2OrderIdBJ(\"autoentangle\"),WESTRING_UNITORDERNOTARG_AUTOENTANGLE\nOrderCodeAutoEntangleInstant=1,ordercode,String2OrderIdBJ(\"autoentangleinstant\"),WESTRING_UNITORDERNOTARG_AUTOENTANGLEINSTANT\nOrderCodeReplenish=0,ordercode,String2OrderIdBJ(\"recharge\"),WESTRING_UNITORDERUTARG_REPLENISH\nOrderCodeReplenishOn=1,ordercode,String2OrderIdBJ(\"rechargeon\"),WESTRING_UNITORDERNOTARG_REPLENISHON\nOrderCodeReplenishOff=1,ordercode,String2OrderIdBJ(\"rechargeoff\"),WESTRING_UNITORDERNOTARG_REPLENISHOFF\nOrderCodeCoupleInstant1=1,ordercode,String2OrderIdBJ(\"coupleinstant\"),WESTRING_UNITORDERNOTARG_COUPLEINSTANT1\nOrderCodeCoupleInstant2=1,ordercode,String2OrderIdBJ(\"coupleinstant\"),WESTRING_UNITORDERNOTARG_COUPLEINSTANT2\nOrderCodeDecouple=1,ordercode,String2OrderIdBJ(\"decouple\"),WESTRING_UNITORDERNOTARG_DECOUPLE\nOrderCodeTaunt=1,ordercode,String2OrderIdBJ(\"taunt\"),WESTRING_UNITORDERNOTARG_TAUNT\nOrderCodeManaFlareOn=1,ordercode,String2OrderIdBJ(\"manaflareon\"),WESTRING_UNITORDERNOTARG_MANAFLAREON\nOrderCodeManaFlareOff=1,ordercode,String2OrderIdBJ(\"manaflareoff\"),WESTRING_UNITORDERNOTARG_MANAFLAREOFF\nOrderCodePhaseShift=1,ordercode,String2OrderIdBJ(\"phaseshift\"),WESTRING_UNITORDERNOTARG_PHASESHIFT\nOrderCodePhaseShiftOn=1,ordercode,String2OrderIdBJ(\"phaseshifton\"),WESTRING_UNITORDERNOTARG_PHASESHIFTON\nOrderCodePhaseShiftOff=1,ordercode,String2OrderIdBJ(\"phaseshiftoff\"),WESTRING_UNITORDERNOTARG_PHASESHIFTOFF\nOrderCodeVengeanceInstant=1,ordercode,String2OrderIdBJ(\"vengeanceinstant\"),WESTRING_UNITORDERNOTARG_VENGEANCEINSTANT\nOrderCodeVengeanceOn=1,ordercode,String2OrderIdBJ(\"vengeanceon\"),WESTRING_UNITORDERNOTARG_VENGEANCEON\nOrderCodeVengeanceOff=1,ordercode,String2OrderIdBJ(\"vengeanceoff\"),WESTRING_UNITORDERNOTARG_VENGEANCEOFF\nOrderCodeFanOfKnives=1,ordercode,String2OrderIdBJ(\"fanofknives\"),WESTRING_UNITORDERNOTARG_FANOFKNIVES\nOrderCodeSpiritOfVengeance=1,ordercode,String2OrderIdBJ(\"spiritofvengeance\"),WESTRING_UNITORDERNOTARG_SPIRITOFVENGEANCE\nOrderCodeUndeadBuild=1,ordercode,String2OrderIdBJ(\"undeadbuild\"),WESTRING_UNITORDERNOTARG_UNDEADBUILD\nOrderCodeDevourMagic=1,ordercode,String2OrderIdBJ(\"devourmagic\"),WESTRING_UNITORDERPTARG_DEVOURMAGIC\nOrderCodeRestoration=0,ordercode,String2OrderIdBJ(\"restoration\"),WESTRING_UNITORDERUTARG_RESTORE\nOrderCodeSacrificeAcolyte=0,ordercode,String2OrderIdBJ(\"sacrifice\"),WESTRING_UNITORDERUTARG_SACRIFICEACOLYTE\nOrderCodeSacrifice=0,ordercode,String2OrderIdBJ(\"sacrifice\"),WESTRING_UNITORDERUTARG_SACRIFICE\nOrderCodeUnsummon=0,ordercode,String2OrderIdBJ(\"unsummon\"),WESTRING_UNITORDERUTARG_UNSUMMON\nOrderCodeWeb=0,ordercode,String2OrderIdBJ(\"web\"),WESTRING_UNITORDERUTARG_WEB\nOrderCodeRaiseDead=0,ordercode,String2OrderIdBJ(\"raisedead\"),WESTRING_UNITORDERUTARG_RAISEDEAD\nOrderCodeUnholyFrenzy=0,ordercode,String2OrderIdBJ(\"unholyfrenzy\"),WESTRING_UNITORDERUTARG_UNHOLYFRENZY\nOrderCodeCripple=0,ordercode,String2OrderIdBJ(\"cripple\"),WESTRING_UNITORDERUTARG_CRIPPLE\nOrderCodeCurse=0,ordercode,String2OrderIdBJ(\"curse\"),WESTRING_UNITORDERUTARG_CURSE\nOrderCodeAntiMagicShell=0,ordercode,String2OrderIdBJ(\"antimagicshell\"),WESTRING_UNITORDERUTARG_ANTIMAGICSHELL\nOrderCodePossession=0,ordercode,String2OrderIdBJ(\"possession\"),WESTRING_UNITORDERUTARG_POSSESSION\nOrderCodeDeathCoil=0,ordercode,String2OrderIdBJ(\"deathcoil\"),WESTRING_UNITORDERUTARG_DEATHCOIL\nOrderCodeDeathPact=0,ordercode,String2OrderIdBJ(\"deathpact\"),WESTRING_UNITORDERUTARG_DEATHPACT\nOrderCodeSleep=0,ordercode,String2OrderIdBJ(\"sleep\"),WESTRING_UNITORDERUTARG_SLEEP\nOrderCodeFrostNova=0,ordercode,String2OrderIdBJ(\"frostnova\"),WESTRING_UNITORDERUTARG_FROSTNOVA\nOrderCodeFrostArmor=0,ordercode,String2OrderIdBJ(\"frostarmor\"),WESTRING_UNITORDERUTARG_FROSTARMOR\nOrderCodeFrostArmorOn=0,ordercode,String2OrderIdBJ(\"frostarmoron\"),WESTRING_UNITORDERNOTARG_FROSTARMORON\nOrderCodeFrostArmorOff=0,ordercode,String2OrderIdBJ(\"frostarmoroff\"),WESTRING_UNITORDERNOTARG_FROSTARMOROFF\nOrderCodeDarkRitual=0,ordercode,String2OrderIdBJ(\"darkritual\"),WESTRING_UNITORDERUTARG_DARKRITUAL\nOrderCodeCarrionSwarm=0,ordercode,String2OrderIdBJ(\"carrionswarm\"),WESTRING_UNITORDERPTARG_CARRIONSWARM\nOrderCodeDarkSummoning=0,ordercode,String2OrderIdBJ(\"dreadlordinferno\"),WESTRING_UNITORDERPTARG_DARKSUMMONING\nOrderCodeDeathAndDecay=0,ordercode,String2OrderIdBJ(\"deathanddecay\"),WESTRING_UNITORDERPTARG_DEATHANDDECAY\nOrderCodeRestorationOn=0,ordercode,String2OrderIdBJ(\"restorationon\"),WESTRING_UNITORDERNOTARG_RESTOREON\nOrderCodeRestorationOff=0,ordercode,String2OrderIdBJ(\"restorationoff\"),WESTRING_UNITORDERNOTARG_RESTOREOFF\nOrderCodeCannibalize=0,ordercode,String2OrderIdBJ(\"cannibalize\"),WESTRING_UNITORDERNOTARG_CANNIBALIZE\nOrderCodeWebOn=0,ordercode,String2OrderIdBJ(\"webon\"),WESTRING_UNITORDERNOTARG_WEBON\nOrderCodeWebOff=0,ordercode,String2OrderIdBJ(\"weboff\"),WESTRING_UNITORDERNOTARG_WEBOFF\nOrderCodeLoadCorpse=0,ordercode,String2OrderIdBJ(\"loadcorpse\"),WESTRING_UNITORDERNOTARG_LOADCORPSE\nOrderCodeUnloadAllCorpses=0,ordercode,String2OrderIdBJ(\"unloadallcorpses\"),WESTRING_UNITORDERNOTARG_UNLOADALLCORPSES\nOrderCodeStoneForm=0,ordercode,String2OrderIdBJ(\"stoneform\"),WESTRING_UNITORDERNOTARG_STONEFORM\nOrderCodeUnStoneForm=0,ordercode,String2OrderIdBJ(\"unstoneform\"),WESTRING_UNITORDERNOTARG_UNSTONEFORM\nOrderCodeRaiseDeadOn=0,ordercode,String2OrderIdBJ(\"raisedeadon\"),WESTRING_UNITORDERNOTARG_RAISEDEADON\nOrderCodeRaiseDeadOff=0,ordercode,String2OrderIdBJ(\"raisedeadoff\"),WESTRING_UNITORDERNOTARG_RAISEDEADOFF\nOrderCodeCurseOn=0,ordercode,String2OrderIdBJ(\"curseon\"),WESTRING_UNITORDERNOTARG_CURSEON\nOrderCodeCurseOff=0,ordercode,String2OrderIdBJ(\"curseoff\"),WESTRING_UNITORDERNOTARG_CURSEOFF\nOrderCodeAnimateDead=0,ordercode,String2OrderIdBJ(\"animatedead\"),WESTRING_UNITORDERNOTARG_ANIMATEDEAD\nOrderCodeAbsorbMana=1,ordercode,String2OrderIdBJ(\"absorb\"),WESTRING_UNITORDERUTARG_ABSORBMANA\nOrderCodeFlamingAttack=1,ordercode,String2OrderIdBJ(\"flamingattacktarg\"),WESTRING_UNITORDERUTARG_FLAMINGATTACK\nOrderCodeImpale=1,ordercode,String2OrderIdBJ(\"impale\"),WESTRING_UNITORDERUTARG_IMPALE\nOrderCodeCarrionScarabs=1,ordercode,String2OrderIdBJ(\"carrionscarabs\"),WESTRING_UNITORDERUTARG_CARRIONSCARABS\nOrderCodeBurrow=1,ordercode,String2OrderIdBJ(\"burrow\"),WESTRING_UNITORDERNOTARG_BURROW\nOrderCodeUnBurrow=1,ordercode,String2OrderIdBJ(\"unburrow\"),WESTRING_UNITORDERNOTARG_UNBURROW\nOrderCodeRaiseDeadInstant=1,ordercode,String2OrderIdBJ(\"instant\"),WESTRING_UNITORDERNOTARG_RAISEDEAD\nOrderCodeFlamingAttackOn=1,ordercode,String2OrderIdBJ(\"flamingattack\"),WESTRING_UNITORDERNOTARG_FLAMINGATTACKON\nOrderCodeFlamingAttackOff=1,ordercode,String2OrderIdBJ(\"unflamingattack\"),WESTRING_UNITORDERNOTARG_FLAMINGATTACKOFF\nOrderCodeSphinxForm=1,ordercode,String2OrderIdBJ(\"avengerform\"),WESTRING_UNITORDERNOTARG_SPHINXFORM\nOrderCodeReplenishLife=1,ordercode,String2OrderIdBJ(\"replenishlife\"),WESTRING_UNITORDERNOTARG_REPLENISHLIFE\nOrderCodeReplenishLifeOn=1,ordercode,String2OrderIdBJ(\"replenishlifeon\"),WESTRING_UNITORDERNOTARG_REPLENISHLIFEON\nOrderCodeReplenishLifeOff=1,ordercode,String2OrderIdBJ(\"replenishlifeoff\"),WESTRING_UNITORDERNOTARG_REPLENISHLIFEOFF\nOrderCodeReplenishMana=1,ordercode,String2OrderIdBJ(\"replenishmana\"),WESTRING_UNITORDERNOTARG_REPLENISHMANA\nOrderCodeReplenishManaOn=1,ordercode,String2OrderIdBJ(\"replenishmanaon\"),WESTRING_UNITORDERNOTARG_REPLENISHMANAON\nOrderCodeReplenishManaOff=1,ordercode,String2OrderIdBJ(\"replenishmanaoff\"),WESTRING_UNITORDERNOTARG_REPLENISHMANAOFF\nOrderCodeCarrionScarabsOn=1,ordercode,String2OrderIdBJ(\"carrionscarabson\"),WESTRING_UNITORDERNOTARG_CARRIONSCARABSON\nOrderCodeCarrionScarabsOff=1,ordercode,String2OrderIdBJ(\"carrionscarabsoff\"),WESTRING_UNITORDERNOTARG_CARRIONSCARABSOFF\nOrderCodeLocustSwarm=1,ordercode,String2OrderIdBJ(\"locustswarm\"),WESTRING_UNITORDERNOTARG_LOCUSTSWARM\nOrderCodeNagaBuild=1,unitordernotarg,String2OrderIdBJ(\"nagabuild\"),WESTRING_UNITORDERNOTARG_NAGABUILD\nOrderCodeBreathOfFrost=1,ordercode,String2OrderIdBJ(\"breathoffrost\"),WESTRING_UNITORDERPTARG_BREATHOFFROST\nOrderCodeMonsoon=1,ordercode,String2OrderIdBJ(\"monsoon\"),WESTRING_UNITORDERPTARG_MONSOON\nOrderCodeSelfDestruct=0,ordercode,String2OrderIdBJ(\"selfdestruct\"),WESTRING_UNITORDERPTARG_SELFDESTRUCT\nOrderCodeRevenge=0,ordercode,String2OrderIdBJ(\"revenge\"),WESTRING_UNITORDERNOTARG_REVENGE\nOrderCodeStampede=1,ordercode,String2OrderIdBJ(\"stampede\"),WESTRING_UNITORDERPTARG_STAMPEDE\nOrderCodeSilence=1,ordercode,String2OrderIdBJ(\"silence\"),WESTRING_UNITORDERPTARG_SILENCE\nOrderCodeTornado=1,ordercode,String2OrderIdBJ(\"tornado\"),WESTRING_UNITORDERPTARG_TORNADO\nOrderCodeBreathOfFire=1,ordercode,String2OrderIdBJ(\"breathoffire\"),WESTRING_UNITORDERPTARG_BREATHOFFIRE\nOrderCodeHeroRainOfFire=1,ordercode,String2OrderIdBJ(\"rainoffire\"),WESTRING_UNITORDERPTARG_HERORAINOFFIRE\nOrderCodeCreepDevour=1,ordercode,String2OrderIdBJ(\"creepdevour\"),WESTRING_UNITORDERUTARG_CREEPDEVOUR\nOrderCodeWateryMinion=1,ordercode,String2OrderIdBJ(\"wateryminion\"),WESTRING_UNITORDERNOTARG_WATERYMINION\nOrderCodeSelfDestructOn=1,ordercode,String2OrderIdBJ(\"selfdestructon\"),WESTRING_UNITORDERNOTARG_SELFDESTRUCTON\nOrderCodeSelfDestructOff=1,ordercode,String2OrderIdBJ(\"selfdestructoff\"),WESTRING_UNITORDERNOTARG_SELFDESTRUCTOFF\nOrderCodeSummonGrizzly=1,ordercode,String2OrderIdBJ(\"summongrizzly\"),WESTRING_UNITORDERNOTARG_SUMMONGRIZZLY\nOrderCodeSummonQuillbeast=1,ordercode,String2OrderIdBJ(\"summonquillbeast\"),WESTRING_UNITORDERNOTARG_SUMMONQUILLBEAST\nOrderCodeSummonWarEagle=1,ordercode,String2OrderIdBJ(\"summonwareagle\"),WESTRING_UNITORDERNOTARG_SUMMONWAREAGLE\nOrderCodeBlackArrow=1,ordercode,String2OrderIdBJ(\"blackarrow\"),WESTRING_UNITORDERUTARG_BLACKARROW\nOrderCodeBlackArrowOn=1,ordercode,String2OrderIdBJ(\"blackarrowon\"),WESTRING_UNITORDERNOTARG_BLACKARROWON\nOrderCodeBlackArrowOff=1,ordercode,String2OrderIdBJ(\"blackarrowoff\"),WESTRING_UNITORDERNOTARG_BLACKARROWOFF\nOrderCodeColdArrowOn=1,ordercode,String2OrderIdBJ(\"coldarrows\"),WESTRING_UNITORDERNOTARG_COLDARROWON\nOrderCodeColdArrowOff=1,ordercode,String2OrderIdBJ(\"uncoldarrows\"),WESTRING_UNITORDERNOTARG_COLDARROWOFF\nOrderCodeManaShieldOn=1,ordercode,String2OrderIdBJ(\"manashieldon\"),WESTRING_UNITORDERNOTARG_MANASHIELDON\nOrderCodeManaShieldOff=1,ordercode,String2OrderIdBJ(\"manashieldoff\"),WESTRING_UNITORDERNOTARG_MANASHIELDOFF\nOrderCodeElementalFury=1,ordercode,String2OrderIdBJ(\"elementalfury\"),WESTRING_UNITORDERNOTARG_ELEMENTALFURY\nOrderCodeHowlOfTerror=1,ordercode,String2OrderIdBJ(\"howlofterror\"),WESTRING_UNITORDERNOTARG_HOWLOFTERROR\nOrderCodeDoom=1,ordercode,String2OrderIdBJ(\"doom\"),WESTRING_UNITORDERUTARG_DOOM\nOrderCodeStrongDrink=1,ordercode,String2OrderIdBJ(\"strongdrink\"),WESTRING_UNITORDERUTARG_STRONGDRINK\nOrderCodeCharm=1,ordercode,String2OrderIdBJ(\"charm\"),WESTRING_UNITORDERUTARG_CHARM\nOrderCodeCreepThunderClap=0,ordercode,String2OrderIdBJ(\"creepthunderclap\"),WESTRING_UNITORDERNOTARG_CREEPTHUNDERCLAP\nOrderCodeCreepThunderBolt=0,ordercode,String2OrderIdBJ(\"creepthunderbolt\"),WESTRING_UNITORDERUTARG_CREEPTHUNDERBOLT\nOrderCodeForkedLightning=1,ordercode,String2OrderIdBJ(\"forkedlightning\"),WESTRING_UNITORDERUTARG_FORKEDLIGHTNING\nOrderCodeChannel=1,ordercode,String2OrderIdBJ(\"channel\"),WESTRING_UNITORDERNOTARG_CHANNEL\nOrderCodeFingerOfDeath=0,ordercode,String2OrderIdBJ(\"fingerofdeath\"),WESTRING_UNITORDERUTARG_FINGEROFDEATH\nOrderCodeDarkConversion=0,ordercode,String2OrderIdBJ(\"darkconversion\"),WESTRING_UNITORDERUTARG_DARKCONVERSION\nOrderCodeSoulPreservation=0,ordercode,String2OrderIdBJ(\"soulpreservation\"),WESTRING_UNITORDERUTARG_SOULPRESERVATION\nOrderCodeDarkConversionFast=0,ordercode,String2OrderIdBJ(\"darkconversion\"),WESTRING_UNITORDERUTARG_DARKCONVERSIONFAST\nOrderCodeDarkPortal=0,ordercode,String2OrderIdBJ(\"darkportal\"),WESTRING_UNITORDERPTARG_DARKPORTAL\nOrderCodeRainOfChaos=0,ordercode,String2OrderIdBJ(\"rainoffire\"),WESTRING_UNITORDERPTARG_RAINOFCHAOS\nOrderCodeRainOfFire=0,ordercode,String2OrderIdBJ(\"rainoffire\"),WESTRING_UNITORDERPTARG_RAINOFFIRE\nOrderCodeInferno=0,ordercode,String2OrderIdBJ(\"inferno\"),WESTRING_UNITORDERPTARG_INFERNO\nOrderCodeDarkSummoningOld=0,ordercode,String2OrderIdBJ(\"darksummoning\"),WESTRING_UNITORDERPTARG_DARKSUMMONINGOLD\nOrderCodeMedivhRavenForm=0,ordercode,String2OrderIdBJ(\"ravenform\"),WESTRING_UNITORDERNOTARG_MEDIVHRAVENFORM\nOrderCodeMedivhUnRavenForm=0,ordercode,String2OrderIdBJ(\"unravenform\"),WESTRING_UNITORDERNOTARG_MEDIVHUNRAVENFORM\nOrderCodeRexxarBattleRoar=1,ordercode,String2OrderIdBJ(\"battleroar\"),WESTRING_UNITORDERNOTARG_REXXARBATTLEROAR\nOrderCodeColdArrows=0,ordercode,String2OrderIdBJ(\"coldarrows\"),WESTRING_UNITORDERNOTARG_COLDARROWS\nOrderCodeUnColdArrows=0,ordercode,String2OrderIdBJ(\"uncoldarrows\"),WESTRING_UNITORDERNOTARG_UNCOLDARROWS\nUnitOrderDoCancel=0,unitordernotarg,851976,WESTRING_UNITORDERUTARG_CANCEL\nUnitOrderAttackUnit=0,unitorderutarg,`attack`,WESTRING_UNITORDERUTARG_ATTACK\nUnitOrderAttackUnitOnce=0,unitorderutarg,`attackonce`,WESTRING_UNITORDERUTARG_ATTACKONCE\nUnitOrderMoveUnit=0,unitorderutarg,`move`,WESTRING_UNITORDERUTARG_MOVE\nUnitOrderSmartUnit=1,unitorderutarg,`smart`,WESTRING_UNITORDERUTARG_SMART\nUnitOrderHarvest=0,unitorderutarg,`harvest`,WESTRING_UNITORDERUTARG_HARVEST\nUnitOrderRevive=0,unitorderutarg,`revive`,WESTRING_UNITORDERUTARG_REVIVE\nUnitOrderLoad=0,unitorderutarg,`load`,WESTRING_UNITORDERUTARG_LOAD\nUnitOrderUnload=0,unitorderutarg,`unload`,WESTRING_UNITORDERUTARG_UNLOAD\nUnitOrderBoard=0,unitorderutarg,`board`,WESTRING_UNITORDERUTARG_BOARD\nUnitOrderForceBoard=0,unitorderutarg,`forceboard`,WESTRING_UNITORDERUTARG_FORCEBOARD\nUnitOrderRepair=0,unitorderutarg,`repair`,WESTRING_UNITORDERUTARG_REPAIR\nUnitOrderInnerFire=0,unitorderutarg,`innerfire`,WESTRING_UNITORDERUTARG_INNERFIRE\nUnitOrderDispel=0,unitorderutarg,`dispel`,WESTRING_UNITORDERUTARG_DISPEL\nUnitOrderHeal=0,unitorderutarg,`heal`,WESTRING_UNITORDERUTARG_HEAL\nUnitOrderSlow=0,unitorderutarg,`slow`,WESTRING_UNITORDERUTARG_SLOW\nUnitOrderInvisibility=0,unitorderutarg,`invisibility`,WESTRING_UNITORDERUTARG_INVISIBILITY\nUnitOrderPolymorph=0,unitorderutarg,`polymorph`,WESTRING_UNITORDERUTARG_POLYMORPH\nUnitOrderControlMagic=1,unitorderutarg,`controlmagic`,WESTRING_UNITORDERUTARG_CONTROLMAGIC\nUnitOrderSpellSteal=1,unitorderutarg,`spellsteal`,WESTRING_UNITORDERUTARG_SPELLSTEAL\nUnitOrderAerialShackles=1,unitorderutarg,`magicleash`,WESTRING_UNITORDERUTARG_AERIALSHACKLES\nUnitOrderMassTeleport=0,unitorderutarg,`massteleport`,WESTRING_UNITORDERUTARG_MASSTELEPORT\nUnitOrderBanish=1,unitorderutarg,`banish`,WESTRING_UNITORDERUTARG_BANISH\nUnitOrderSiphonMana=1,unitorderutarg,`drain`,WESTRING_UNITORDERUTARG_SIPHONMANA\nUnitOrderThunderBolt=0,unitorderutarg,`thunderbolt`,WESTRING_UNITORDERUTARG_THUNDERBOLT\nUnitOrderHolyBolt=0,unitorderutarg,`holybolt`,WESTRING_UNITORDERUTARG_HOLYBOLT\nUnitOrderRepairO=0,unitorderutarg,`repair`,WESTRING_UNITORDERUTARG_REPAIRO\nUnitOrderEnsnare=0,unitorderutarg,`ensnare`,WESTRING_UNITORDERUTARG_ENSNARE\nUnitOrderUnstableConcoction=1,unitorderutarg,`unstableconcoction`,WESTRING_UNITORDERUTARG_UNSTABLECONCOCTION\nUnitOrderPurge=0,unitorderutarg,`purge`,WESTRING_UNITORDERUTARG_PURGE\nUnitOrderLightningShield=0,unitorderutarg,`lightningshield`,WESTRING_UNITORDERUTARG_LIGHTNINGSHIELD\nUnitOrderBloodlust=0,unitorderutarg,`bloodlust`,WESTRING_UNITORDERUTARG_BLOODLUST\nUnitOrderSpiritLink=1,unitorderutarg,`spiritlink`,WESTRING_UNITORDERUTARG_SPIRITLINK\nUnitOrderDevour=0,unitorderutarg,`devour`,WESTRING_UNITORDERUTARG_DEVOUR\nUnitOrderChainLightning=0,unitorderutarg,`chainlightning`,WESTRING_UNITORDERUTARG_CHAINLIGHTNING\nUnitOrderHealingWave=1,unitorderutarg,`healingwave`,WESTRING_UNITORDERUTARG_HEALINGWAVE\nUnitOrderHex=1,unitorderutarg,`hex`,WESTRING_UNITORDERUTARG_HEX\nUnitOrderAncestralSpiritTarg=1,unitorderutarg,`ancestralspirittarg`,WESTRING_UNITORDERUTARG_ANCESTRALSPIRIT\nUnitOrderRenew=0,unitorderutarg,`renew`,WESTRING_UNITORDERUTARG_RENEW\nUnitOrderEntangle=0,unitorderutarg,`entangle`,WESTRING_UNITORDERUTARG_ENTANGLE\nUnitOrderEntangleInstant=0,unitorderutarg,`entangleinstant`,WESTRING_UNITORDERUTARG_ENTANGLEINSTANT\nUnitOrderReplenish=0,unitorderutarg,`recharge`,WESTRING_UNITORDERUTARG_REPLENISH\nUnitOrderMountHippogryph=0,unitorderutarg,`mounthippogryph`,WESTRING_UNITORDERUTARG_MOUNTHIPPOGRYPH\nUnitOrderLoadArcher=0,unitorderutarg,`loadarcher`,WESTRING_UNITORDERUTARG_LOADARCHER\nUnitOrderAutoDispel=0,unitorderutarg,`autodispel`,WESTRING_UNITORDERUTARG_AUTODISPEL\nUnitOrderFaerieFire=0,unitorderutarg,`faeriefire`,WESTRING_UNITORDERUTARG_FAERIEFIRE\nUnitOrderCyclone=0,unitorderutarg,`cyclone`,WESTRING_UNITORDERUTARG_CYCLONE\nUnitOrderRejuvination=0,unitorderutarg,`rejuvination`,WESTRING_UNITORDERUTARG_REJUVINATION\nUnitOrderVengeance=1,unitorderutarg,`vengeance`,WESTRING_UNITORDERUTARG_VENGEANCE\nUnitOrderManaBurn=0,unitorderutarg,`manaburn`,WESTRING_UNITORDERUTARG_MANABURN\nUnitOrderEntanglingRoots=0,unitorderutarg,`entanglingroots`,WESTRING_UNITORDERUTARG_ENTANGLINGROOTS\nUnitOrderShadowStrike=1,unitorderutarg,`shadowstrike`,WESTRING_UNITORDERUTARG_SHADOWSTRIKE\nUnitOrderRestoration=0,unitorderutarg,`restoration`,WESTRING_UNITORDERUTARG_RESTORE\nUnitOrderSacrificeAcolyte=0,unitorderutarg,`sacrifice`,WESTRING_UNITORDERUTARG_SACRIFICEACOLYTE\nUnitOrderSacrifice=0,unitorderutarg,`requestsacrifice`,WESTRING_UNITORDERUTARG_SACRIFICE\nUnitOrderUnsummon=0,unitorderutarg,`unsummon`,WESTRING_UNITORDERUTARG_UNSUMMON\nUnitOrderWeb=0,unitorderutarg,`web`,WESTRING_UNITORDERUTARG_WEB\nUnitOrderRaiseDead=0,unitorderutarg,`raisedead`,WESTRING_UNITORDERUTARG_RAISEDEAD\nUnitOrderUnholyFrenzy=0,unitorderutarg,`unholyfrenzy`,WESTRING_UNITORDERUTARG_UNHOLYFRENZY\nUnitOrderCripple=0,unitorderutarg,`cripple`,WESTRING_UNITORDERUTARG_CRIPPLE\nUnitOrderCurse=0,unitorderutarg,`curse`,WESTRING_UNITORDERUTARG_CURSE\nUnitOrderAntiMagicShell=0,unitorderutarg,`antimagicshell`,WESTRING_UNITORDERUTARG_ANTIMAGICSHELL\nUnitOrderPossession=0,unitorderutarg,`possession`,WESTRING_UNITORDERUTARG_POSSESSION\nUnitOrderAbsorbMana=1,unitorderutarg,`absorb`,WESTRING_UNITORDERUTARG_ABSORBMANA\nUnitOrderFlamingAttack=1,unitorderutarg,`flamingattacktarg`,WESTRING_UNITORDERUTARG_FLAMINGATTACK\nUnitOrderImpale=1,unitorderutarg,`impale`,WESTRING_UNITORDERUTARG_IMPALE\nUnitOrderCarrionScarabs=1,unitorderutarg,`carrionscarabs`,WESTRING_UNITORDERUTARG_CARRIONSCARABS\nUnitOrderDeathCoil=0,unitorderutarg,`deathcoil`,WESTRING_UNITORDERUTARG_DEATHCOIL\nUnitOrderDeathPact=0,unitorderutarg,`deathpact`,WESTRING_UNITORDERUTARG_DEATHPACT\nUnitOrderSleep=0,unitorderutarg,`sleep`,WESTRING_UNITORDERUTARG_SLEEP\nUnitOrderFrostNova=0,unitorderutarg,`frostnova`,WESTRING_UNITORDERUTARG_FROSTNOVA\nUnitOrderFrostArmor=0,unitorderutarg,`frostarmor`,WESTRING_UNITORDERUTARG_FROSTARMOR\nUnitOrderDarkRitual=0,unitorderutarg,`darkritual`,WESTRING_UNITORDERUTARG_DARKRITUAL\nUnitOrderCreepDevour=1,unitorderutarg,`creepdevour`,WESTRING_UNITORDERUTARG_CREEPDEVOUR\nUnitOrderFirebolt=0,unitorderutarg,`firebolt`,WESTRING_UNITORDERUTARG_FIREBOLT\nUnitOrderCreepHeal=0,unitorderutarg,`creepheal`,WESTRING_UNITORDERUTARG_CREEPHEAL\nUnitOrderCreepThunderBolt=0,unitorderutarg,`creepthunderbolt`,WESTRING_UNITORDERUTARG_CREEPTHUNDERBOLT\nUnitOrderParasite=1,unitorderutarg,`parasite`,WESTRING_UNITORDERUTARG_PARASITE\nUnitOrderSelfDestructUnit=1,unitorderutarg,`selfdestruct`,WESTRING_UNITORDERUTARG_SELFDESTRUCT\nUnitOrderBlackArrow=1,unitorderutarg,`blackarrow`,WESTRING_UNITORDERUTARG_BLACKARROW\nUnitOrderCharm=1,unitorderutarg,`charm`,WESTRING_UNITORDERUTARG_CHARM\nUnitOrderLifeDrain=1,unitorderutarg,`drain`,WESTRING_UNITORDERUTARG_LIFEDRAIN\nUnitOrderColdArrow=1,unitorderutarg,`coldarrowstarg`,WESTRING_UNITORDERUTARG_COLDARROW\nUnitOrderForkedLightning=1,unitorderutarg,`forkedlightning`,WESTRING_UNITORDERUTARG_FORKEDLIGHTNING\nUnitOrderStrongDrink=1,unitorderutarg,`drunkenhaze`,WESTRING_UNITORDERUTARG_STRONGDRINK\nUnitOrderDoom=1,unitorderutarg,`doom`,WESTRING_UNITORDERUTARG_DOOM\nUnitOrderPoisonArrow=0,unitorderutarg,`poisonarrowstarg`,WESTRING_UNITORDERUTARG_POISONARROW\nUnitOrderIncinerateArrow=1,unitorderutarg,`incineratearrow`,WESTRING_UNITORDERUTARG_INCINERATEARROW\nUnitOrderFingerOfDeath=0,unitorderutarg,`fingerofdeath`,WESTRING_UNITORDERUTARG_FINGEROFDEATH\nUnitOrderDarkConversion=0,unitorderutarg,`darkconversion`,WESTRING_UNITORDERUTARG_DARKCONVERSION\nUnitOrderSoulPreservation=0,unitorderutarg,`soulpreservation`,WESTRING_UNITORDERUTARG_SOULPRESERVATION\nUnitOrderDarkConversionFast=0,unitorderutarg,`darkconversion`,WESTRING_UNITORDERUTARG_DARKCONVERSIONFAST\nUnitOrderAttack=0,unitorderptarg,`attack`,WESTRING_UNITORDERPTARG_ATTACK\nUnitOrderAttackGround=0,unitorderptarg,`attackground`,WESTRING_UNITORDERPTARG_ATTACKGROUND\nUnitOrderMove=0,unitorderptarg,`move`,WESTRING_UNITORDERPTARG_MOVE\nUnitOrderPatrol=0,unitorderptarg,`patrol`,WESTRING_UNITORDERPTARG_PATROL\nUnitOrderSmartPoint=1,unitorderptarg,`smart`,WESTRING_UNITORDERPTARG_SMART\nUnitOrderSetRally=0,unitorderptarg,`setrally`,WESTRING_UNITORDERPTARG_SETRALLY\nUnitOrderUnloadAll=0,unitorderptarg,`unloadall`,WESTRING_UNITORDERPTARG_UNLOADALL\nUnitOrderFlare=0,unitorderptarg,`flare`,WESTRING_UNITORDERPTARG_FLARE\nUnitOrderCloudOfFog=1,unitorderptarg,`cloudoffog`,WESTRING_UNITORDERPTARG_CLOUDOFFOG\nUnitOrderBlizzard=0,unitorderptarg,`blizzard`,WESTRING_UNITORDERPTARG_BLIZZARD\nUnitOrderFlameStrike=1,unitorderptarg,`flamestrike`,WESTRING_UNITORDERPTARG_FLAMESTRIKE\nUnitOrderSentryWard=0,unitorderptarg,`evileye`,WESTRING_UNITORDERPTARG_SENTRYWARD\nUnitOrderStasisTrap=0,unitorderptarg,`stasistrap`,WESTRING_UNITORDERPTARG_STASISTRAP\nUnitOrderHealingWard=0,unitorderptarg,`healingward`,WESTRING_UNITORDERPTARG_HEALINGWARD\nUnitOrderDisenchant=1,unitorderptarg,`disenchant`,WESTRING_UNITORDERPTARG_DISENCHANT\nUnitOrderFarSight=0,unitorderptarg,`farsight`,WESTRING_UNITORDERPTARG_FARSIGHT\nUnitOrderEarthquake=0,unitorderptarg,`earthquake`,WESTRING_UNITORDERPTARG_EARTHQUAKE\nUnitOrderSerpentWard=1,unitorderptarg,`ward`,WESTRING_UNITORDERPTARG_SERPENTWARD\nUnitOrderShockwave=0,unitorderptarg,`shockwave`,WESTRING_UNITORDERPTARG_SHOCKWAVE\nUnitOrderRoot=0,unitorderptarg,`root`,WESTRING_UNITORDERPTARG_ROOT\nUnitOrderDetonate=0,unitorderptarg,`detonate`,WESTRING_UNITORDERPTARG_DETONATE\nUnitOrderForceOfNature=0,unitorderptarg,`forceofnature`,WESTRING_UNITORDERPTARG_FORCEOFNATURE\nUnitOrderStarfall=0,unitorderptarg,`obsolete`,WESTRING_UNITORDERPTARG_STARFALL\nUnitOrderBlink=1,unitorderptarg,`blink`,WESTRING_UNITORDERPTARG_BLINK\nUnitOrderDevourMagic=1,unitorderptarg,`devourmagic`,WESTRING_UNITORDERPTARG_DEVOURMAGIC\nUnitOrderImpalePoint=1,unitorderptarg,`impale`,WESTRING_UNITORDERPTARG_IMPALE\nUnitOrderCarrionSwarm=0,unitorderptarg,`carrionswarm`,WESTRING_UNITORDERPTARG_CARRIONSWARM\nUnitOrderDarkSummoning=0,unitorderptarg,`dreadlordinferno`,WESTRING_UNITORDERPTARG_DARKSUMMONING\nUnitOrderDeathAndDecay=0,unitorderptarg,`deathanddecay`,WESTRING_UNITORDERPTARG_DEATHANDDECAY\nUnitOrderBreathOfFrost=1,unitorderptarg,`breathoffrost`,WESTRING_UNITORDERPTARG_BREATHOFFROST\nUnitOrderMonsoon=1,unitorderptarg,`monsoon`,WESTRING_UNITORDERPTARG_MONSOON\nUnitOrderSelfDestruct=0,unitorderptarg,`selfdestruct`,WESTRING_UNITORDERPTARG_SELFDESTRUCT\nUnitOrderStampede=1,unitorderptarg,`stampede`,WESTRING_UNITORDERPTARG_STAMPEDE\nUnitOrderSilence=1,unitorderptarg,`silence`,WESTRING_UNITORDERPTARG_SILENCE\nUnitOrderTornado=1,unitorderptarg,`tornado`,WESTRING_UNITORDERPTARG_TORNADO\nUnitOrderBreathOfFire=1,unitorderptarg,`breathoffire`,WESTRING_UNITORDERPTARG_BREATHOFFIRE\nUnitOrderHeroRainOfFire=1,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_HERORAINOFFIRE\nUnitOrderDarkPortal=0,unitorderptarg,`darkportal`,WESTRING_UNITORDERPTARG_DARKPORTAL\nUnitOrderRainOfChaos=0,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_RAINOFCHAOS\nUnitOrderRainOfFire=0,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_RAINOFFIRE\nUnitOrderInferno=0,unitorderptarg,`inferno`,WESTRING_UNITORDERPTARG_INFERNO\nUnitOrderDarkSummoningOld=0,unitorderptarg,`darksummoning`,WESTRING_UNITORDERPTARG_DARKSUMMONINGOLD\nUnitOrderAttackDestructible=0,unitorderdtarg,`attack`,WESTRING_UNITORDERDTARG_ATTACK\nUnitOrderSmartDestructible=1,unitorderdtarg,`smart`,WESTRING_UNITORDERDTARG_SMART\nUnitOrderHarvestDestructible=0,unitorderdtarg,`harvest`,WESTRING_UNITORDERDTARG_HARVEST\nUnitOrderConsumeTree=0,unitorderdtarg,`eattree`,WESTRING_UNITORDERDTARG_CONSUMETREE\nUnitOrderSentinel=0,unitorderdtarg,`sentinel`,WESTRING_UNITORDERDTARG_SENTINEL\nUnitOrderGrabTree=1,unitorderdtarg,`grabtree`,WESTRING_UNITORDERDTARG_GRABTREE\nUnitOrderStop=0,unitordernotarg,`stop`,WESTRING_UNITORDERNOTARG_STOP\nUnitOrderHoldPosition=0,unitordernotarg,`holdposition`,WESTRING_UNITORDERNOTARG_HOLDPOSITION\nUnitOrderAutoHarvestGold=0,unitordernotarg,`autoharvestgold`,WESTRING_UNITORDERNOTARG_AUTOHARVESTGOLD\nUnitOrderAutoHarvestLumber=0,unitordernotarg,`autoharvestlumber`,WESTRING_UNITORDERNOTARG_AUTOHARVESTLUMBER\nUnitOrderReturnResources=0,unitordernotarg,`returnresources`,WESTRING_UNITORDERNOTARG_RETURNRESOURCES\nUnitOrderBuild=1,unitordernotarg,`build`,WESTRING_UNITORDERNOTARG_BUILD\nUnitOrderLevelup=1,unitordernotarg,`levelup`,WESTRING_UNITORDERNOTARG_LEVELUP\nUnitOrderHumanBuild=1,unitordernotarg,`humanbuild`,WESTRING_UNITORDERNOTARG_HUMANBUILD\nUnitOrderTownBellOn=0,unitordernotarg,`townbellon`,WESTRING_UNITORDERNOTARG_TOWNBELLON\nUnitOrderTownBellOff=0,unitordernotarg,`townbelloff`,WESTRING_UNITORDERNOTARG_TOWNBELLOFF\nUnitOrderMilitia=0,unitordernotarg,`militia`,WESTRING_UNITORDERNOTARG_MILITIA\nUnitOrderMilitiaOff=0,unitordernotarg,`militiaoff`,WESTRING_UNITORDERNOTARG_MILITIAOFF\nUnitOrderRepairOn=0,unitordernotarg,`repairon`,WESTRING_UNITORDERNOTARG_REPAIRON\nUnitOrderRepairOff=0,unitordernotarg,`repairoff`,WESTRING_UNITORDERNOTARG_REPAIROFF\nUnitOrderDefend=0,unitordernotarg,`defend`,WESTRING_UNITORDERNOTARG_DEFEND\nUnitOrderUnDefend=0,unitordernotarg,`undefend`,WESTRING_UNITORDERNOTARG_UNDEFEND\nUnitOrderHealOn=0,unitordernotarg,`healon`,WESTRING_UNITORDERNOTARG_HEALON\nUnitOrderHealOff=0,unitordernotarg,`healoff`,WESTRING_UNITORDERNOTARG_HEALOFF\nUnitOrderInnerFireOn=0,unitordernotarg,`innerfireon`,WESTRING_UNITORDERNOTARG_INNERFIREON\nUnitOrderInnerFireOff=0,unitordernotarg,`innerfireoff`,WESTRING_UNITORDERNOTARG_INNERFIREOFF\nUnitOrderSlowOn=0,unitordernotarg,`slowon`,WESTRING_UNITORDERNOTARG_SLOWON\nUnitOrderSlowOff=0,unitordernotarg,`slowoff`,WESTRING_UNITORDERNOTARG_SLOWOFF\nUnitOrderSpellStealOn=1,unitordernotarg,`spellstealon`,WESTRING_UNITORDERNOTARG_SPELLSTEALON\nUnitOrderSpellStealOff=1,unitordernotarg,`spellstealoff`,WESTRING_UNITORDERNOTARG_SPELLSTEALOFF\nUnitOrderWaterElemental=0,unitordernotarg,`waterelemental`,WESTRING_UNITORDERNOTARG_WATERELEMENTAL\nUnitOrderPhoenix=1,unitordernotarg,`phoenix`,WESTRING_UNITORDERNOTARG_PHOENIX\nUnitOrderThunderClap=0,unitordernotarg,`thunderclap`,WESTRING_UNITORDERNOTARG_THUNDERCLAP\nUnitOrderAvatar=0,unitordernotarg,`avatar`,WESTRING_UNITORDERNOTARG_AVATAR\nUnitOrderDivineShield=0,unitordernotarg,`divineshield`,WESTRING_UNITORDERNOTARG_DIVINESHIELD\nUnitOrderUnDivineShield=0,unitordernotarg,`undivineshield`,WESTRING_UNITORDERNOTARG_UNDIVINESHIELD\nUnitOrderResurrection=0,unitordernotarg,`resurrection`,WESTRING_UNITORDERNOTARG_RESURRECTION\nUnitOrderOrcBuild=1,unitordernotarg,`orcbuild`,WESTRING_UNITORDERNOTARG_ORCBUILD\nUnitOrderBattleStations=0,unitordernotarg,`battlestations`,WESTRING_UNITORDERNOTARG_BATTLESTATIONS\nUnitOrderStandDown=0,unitordernotarg,`standdown`,WESTRING_UNITORDERNOTARG_STANDDOWN\nUnitOrderRepairOOn=0,unitordernotarg,`repairon`,WESTRING_UNITORDERNOTARG_REPAIROON\nUnitOrderRepairOOff=0,unitordernotarg,`repairoff`,WESTRING_UNITORDERNOTARG_REPAIROOFF\nUnitOrderBerserk=1,unitordernotarg,`berserk`,WESTRING_UNITORDERNOTARG_BERSERK\nUnitOrderBloodlustOn=0,unitordernotarg,`bloodluston`,WESTRING_UNITORDERNOTARG_BLOODLUSTON\nUnitOrderBloodlustOff=0,unitordernotarg,`bloodlustoff`,WESTRING_UNITORDERNOTARG_BLOODLUSTOFF\nUnitOrderAncestralSpirit=1,unitordernotarg,`ancestralspirit`,WESTRING_UNITORDERNOTARG_ANCESTRALSPIRIT\nUnitOrderEtherealForm=1,unitordernotarg,`uncorporealform`,WESTRING_UNITORDERNOTARG_ETHEREALFORM\nUnitOrderCorporealForm=1,unitordernotarg,`corporealform`,WESTRING_UNITORDERNOTARG_CORPOREALFORM\nUnitOrderWindWalk=0,unitordernotarg,`windwalk`,WESTRING_UNITORDERNOTARG_WINDWALK\nUnitOrderMirrorImage=0,unitordernotarg,`mirrorimage`,WESTRING_UNITORDERNOTARG_MIRRORIMAGE\nUnitOrderWhirlWind=0,unitordernotarg,`whirlwind`,WESTRING_UNITORDERNOTARG_BLADESTORM\nUnitOrderSpiritWolf=0,unitordernotarg,`spiritwolf`,WESTRING_UNITORDERNOTARG_FERALSPIRIT\nUnitOrderVoodoo=1,unitordernotarg,`voodoo`,WESTRING_UNITORDERNOTARG_VOODOO\nUnitOrderStomp=0,unitordernotarg,`stomp`,WESTRING_UNITORDERNOTARG_WARSTOMP\nUnitOrderNightElfBuild=1,unitordernotarg,`nightelfbuild`,WESTRING_UNITORDERNOTARG_NIGHTELFBUILD\nUnitOrderUnRoot=0,unitordernotarg,`unroot`,WESTRING_UNITORDERNOTARG_UNROOT\nUnitOrderAutoEntangle=1,unitordernotarg,`autoentangle`,WESTRING_UNITORDERNOTARG_AUTOENTANGLE\nUnitOrderAutoEntangleInstant=1,unitordernotarg,`autoentangleinstant`,WESTRING_UNITORDERNOTARG_AUTOENTANGLEINSTANT\nUnitOrderReplenishOn=1,unitordernotarg,`rechargeon`,WESTRING_UNITORDERNOTARG_REPLENISHON\nUnitOrderReplenishOff=1,unitordernotarg,`rechargeoff`,WESTRING_UNITORDERNOTARG_REPLENISHOFF\nUnitOrderAmbush=0,unitordernotarg,`ambush`,WESTRING_UNITORDERNOTARG_HIDE\nUnitOrderRenewOn=0,unitordernotarg,`renewon`,WESTRING_UNITORDERNOTARG_RENEWON\nUnitOrderRenewOff=0,unitordernotarg,`renewoff`,WESTRING_UNITORDERNOTARG_RENEWOFF\nUnitOrderCoupleInstant1=1,unitordernotarg,`coupleinstant`,WESTRING_UNITORDERNOTARG_COUPLEINSTANT1\nUnitOrderCoupleInstant2=1,unitordernotarg,`coupleinstant`,WESTRING_UNITORDERNOTARG_COUPLEINSTANT2\nUnitOrderDecouple=1,unitordernotarg,`decouple`,WESTRING_UNITORDERNOTARG_DECOUPLE\nUnitOrderAutoDispelOn=0,unitordernotarg,`autodispelon`,WESTRING_UNITORDERNOTARG_AUTODISPELON\nUnitOrderAutoDispelOff=0,unitordernotarg,`autodispeloff`,WESTRING_UNITORDERNOTARG_AUTODISPELOFF\nUnitOrderFaerieFireOn=0,unitordernotarg,`faeriefireon`,WESTRING_UNITORDERNOTARG_FAERIEFIREON\nUnitOrderFaerieFireOff=0,unitordernotarg,`faeriefireoff`,WESTRING_UNITORDERNOTARG_FAERIEFIREOFF\nUnitOrderRavenForm=0,unitordernotarg,`ravenform`,WESTRING_UNITORDERNOTARG_RAVENFORM\nUnitOrderUnRavenForm=0,unitordernotarg,`unravenform`,WESTRING_UNITORDERNOTARG_UNRAVENFORM\nUnitOrderRoar=0,unitordernotarg,`roar`,WESTRING_UNITORDERNOTARG_ROAR\nUnitOrderBearForm=0,unitordernotarg,`bearform`,WESTRING_UNITORDERNOTARG_BEARFORM\nUnitOrderUnBearForm=0,unitordernotarg,`unbearform`,WESTRING_UNITORDERNOTARG_UNBEARFORM\nUnitOrderTaunt=1,unitordernotarg,`taunt`,WESTRING_UNITORDERNOTARG_TAUNT\nUnitOrderManaFlareOn=1,unitordernotarg,`manaflareon`,WESTRING_UNITORDERNOTARG_MANAFLAREON\nUnitOrderManaFlareOff=1,unitordernotarg,`manaflareoff`,WESTRING_UNITORDERNOTARG_MANAFLAREOFF\nUnitOrderPhaseShift=1,unitordernotarg,`phaseshift`,WESTRING_UNITORDERNOTARG_PHASESHIFT\nUnitOrderPhaseShiftOn=1,unitordernotarg,`phaseshifton`,WESTRING_UNITORDERNOTARG_PHASESHIFTON\nUnitOrderPhaseShiftOff=1,unitordernotarg,`phaseshiftoff`,WESTRING_UNITORDERNOTARG_PHASESHIFTOFF\nUnitOrderVengeanceInstant=1,unitordernotarg,`vengeanceinstant`,WESTRING_UNITORDERNOTARG_VENGEANCEINSTANT\nUnitOrderVengeanceOn=1,unitordernotarg,`vengeanceon`,WESTRING_UNITORDERNOTARG_VENGEANCEON\nUnitOrderVengeanceOff=1,unitordernotarg,`vengeanceoff`,WESTRING_UNITORDERNOTARG_VENGEANCEOFF\nUnitOrderImmolation=0,unitordernotarg,`immolation`,WESTRING_UNITORDERNOTARG_IMMOLATION\nUnitOrderUnImmolation=0,unitordernotarg,`unimmolation`,WESTRING_UNITORDERNOTARG_UNIMMOLATION\nUnitOrderMetamorphosis=0,unitordernotarg,`metamorphosis`,WESTRING_UNITORDERNOTARG_METAMORPHOSIS\nUnitOrderTranquility=0,unitordernotarg,`tranquility`,WESTRING_UNITORDERNOTARG_TRANQUILITY\nUnitOrderSearingArrows=0,unitordernotarg,`flamingarrows`,WESTRING_UNITORDERNOTARG_SEARINGARROWS\nUnitOrderUnSearingArrows=0,unitordernotarg,`unflamingarrows`,WESTRING_UNITORDERNOTARG_UNSEARINGARROWS\nUnitOrderScout=0,unitordernotarg,`scout`,WESTRING_UNITORDERNOTARG_SCOUT\nUnitOrderStarfall2=0,unitordernotarg,`starfall`,WESTRING_UNITORDERNOTARG_STARFALL\nUnitOrderFanOfKnives=1,unitordernotarg,`fanofknives`,WESTRING_UNITORDERNOTARG_FANOFKNIVES\nUnitOrderSpiritOfVengeance=1,unitordernotarg,`spiritofvengeance`,WESTRING_UNITORDERNOTARG_SPIRITOFVENGEANCE\nUnitOrderUndeadBuild=1,unitordernotarg,`undeadbuild`,WESTRING_UNITORDERNOTARG_UNDEADBUILD\nUnitOrderRestorationOn=0,unitordernotarg,`restorationon`,WESTRING_UNITORDERNOTARG_RESTOREON\nUnitOrderRestorationOff=0,unitordernotarg,`restorationoff`,WESTRING_UNITORDERNOTARG_RESTOREOFF\nUnitOrderCannibalize=0,unitordernotarg,`cannibalize`,WESTRING_UNITORDERNOTARG_CANNIBALIZE\nUnitOrderWebOn=0,unitordernotarg,`webon`,WESTRING_UNITORDERNOTARG_WEBON\nUnitOrderWebOff=0,unitordernotarg,`weboff`,WESTRING_UNITORDERNOTARG_WEBOFF\nUnitOrderBurrow=1,unitordernotarg,`burrow`,WESTRING_UNITORDERNOTARG_BURROW\nUnitOrderUnBurrow=1,unitordernotarg,`unburrow`,WESTRING_UNITORDERNOTARG_UNBURROW\nUnitOrderLoadCorpse=0,unitordernotarg,`loadcorpse`,WESTRING_UNITORDERNOTARG_LOADCORPSE\nUnitOrderUnloadAllCorpses=0,unitordernotarg,`unloadallcorpses`,WESTRING_UNITORDERNOTARG_UNLOADALLCORPSES\nUnitOrderStoneForm=0,unitordernotarg,`stoneform`,WESTRING_UNITORDERNOTARG_STONEFORM\nUnitOrderUnStoneForm=0,unitordernotarg,`unstoneform`,WESTRING_UNITORDERNOTARG_UNSTONEFORM\nUnitOrderRaiseDeadInstant=1,unitordernotarg,`instant`,WESTRING_UNITORDERNOTARG_RAISEDEAD\nUnitOrderRaiseDeadOn=0,unitordernotarg,`raisedeadon`,WESTRING_UNITORDERNOTARG_RAISEDEADON\nUnitOrderRaiseDeadOff=0,unitordernotarg,`raisedeadoff`,WESTRING_UNITORDERNOTARG_RAISEDEADOFF\nUnitOrderCurseOn=0,unitordernotarg,`curseon`,WESTRING_UNITORDERNOTARG_CURSEON\nUnitOrderCurseOff=0,unitordernotarg,`curseoff`,WESTRING_UNITORDERNOTARG_CURSEOFF\nUnitOrderFlamingAttackOn=1,unitordernotarg,`flamingattack`,WESTRING_UNITORDERNOTARG_FLAMINGATTACKON\nUnitOrderFlamingAttackOff=1,unitordernotarg,`unflamingattack`,WESTRING_UNITORDERNOTARG_FLAMINGATTACKOFF\nUnitOrderSphinxForm=1,unitordernotarg,`avengerform`,WESTRING_UNITORDERNOTARG_SPHINXFORM\nUnitOrderReplenishLife=1,unitordernotarg,`replenishlife`,WESTRING_UNITORDERNOTARG_REPLENISHLIFE\nUnitOrderReplenishLifeOn=1,unitordernotarg,`replenishlifeon`,WESTRING_UNITORDERNOTARG_REPLENISHLIFEON\nUnitOrderReplenishLifeOff=1,unitordernotarg,`replenishlifeoff`,WESTRING_UNITORDERNOTARG_REPLENISHLIFEOFF\nUnitOrderReplenishMana=1,unitordernotarg,`replenishmana`,WESTRING_UNITORDERNOTARG_REPLENISHMANA\nUnitOrderReplenishManaOn=1,unitordernotarg,`replenishmanaon`,WESTRING_UNITORDERNOTARG_REPLENISHMANAON\nUnitOrderReplenishManaOff=1,unitordernotarg,`replenishmanaoff`,WESTRING_UNITORDERNOTARG_REPLENISHMANAOFF\nUnitOrderCarrionScarabsOn=1,unitordernotarg,`carrionscarabson`,WESTRING_UNITORDERNOTARG_CARRIONSCARABSON\nUnitOrderCarrionScarabsOff=1,unitordernotarg,`carrionscarabsoff`,WESTRING_UNITORDERNOTARG_CARRIONSCARABSOFF\nUnitOrderCarrionScarabsInstant=1,unitordernotarg,`carrionscarabsinstant`,WESTRING_UNITORDERNOTARG_CARRIONSCARABS\nUnitOrderLocustSwarm=1,unitordernotarg,`locustswarm`,WESTRING_UNITORDERNOTARG_LOCUSTSWARM\nUnitOrderAnimateDead=0,unitordernotarg,`animatedead`,WESTRING_UNITORDERNOTARG_ANIMATEDEAD\nUnitOrderFrostArmorOn=0,unitordernotarg,`frostarmoron`,WESTRING_UNITORDERNOTARG_FROSTARMORON\nUnitOrderFrostArmorOff=0,unitordernotarg,`frostarmoroff`,WESTRING_UNITORDERNOTARG_FROSTARMOROFF\nUnitOrderNagaBuild=1,unitordernotarg,`nagabuild`,WESTRING_UNITORDERNOTARG_NAGABUILD\nUnitOrderCreepAnimateDead=0,unitordernotarg,`creepanimatedead`,WESTRING_UNITORDERNOTARG_CREEPANIMATEDEAD\nUnitOrderCreepHealOn=0,unitordernotarg,`creephealon`,WESTRING_UNITORDERNOTARG_CREEPHEALON\nUnitOrderCreepHealOff=0,unitordernotarg,`creephealoff`,WESTRING_UNITORDERNOTARG_CREEPHEALOFF\nUnitOrderRevenge=0,unitordernotarg,`revenge`,WESTRING_UNITORDERNOTARG_REVENGE\nUnitOrderCreepThunderClap=0,unitordernotarg,`creepthunderclap`,WESTRING_UNITORDERNOTARG_CREEPTHUNDERCLAP\nUnitOrderWateryMinion=1,unitordernotarg,`wateryminion`,WESTRING_UNITORDERNOTARG_WATERYMINION\nUnitOrderSelfDestructOn=1,unitordernotarg,`selfdestructon`,WESTRING_UNITORDERNOTARG_SELFDESTRUCTON\nUnitOrderSelfDestructOff=1,unitordernotarg,`selfdestructoff`,WESTRING_UNITORDERNOTARG_SELFDESTRUCTOFF\nUnitOrderSummonGrizzly=1,unitordernotarg,`summongrizzly`,WESTRING_UNITORDERNOTARG_SUMMONGRIZZLY\nUnitOrderSummonQuillbeast=1,unitordernotarg,`summonquillbeast`,WESTRING_UNITORDERNOTARG_SUMMONQUILLBEAST\nUnitOrderSummonWarEagle=1,unitordernotarg,`summonwareagle`,WESTRING_UNITORDERNOTARG_SUMMONWAREAGLE\nUnitOrderBlackArrowOn=1,unitordernotarg,`blackarrowon`,WESTRING_UNITORDERNOTARG_BLACKARROWON\nUnitOrderBlackArrowOff=1,unitordernotarg,`blackarrowoff`,WESTRING_UNITORDERNOTARG_BLACKARROWOFF\nUnitOrderColdArrowOn=1,unitordernotarg,`coldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWON\nUnitOrderColdArrowOff=1,unitordernotarg,`uncoldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWOFF\nUnitOrderManaShieldOn=1,unitordernotarg,`manashieldon`,WESTRING_UNITORDERNOTARG_MANASHIELDON\nUnitOrderManaShieldOff=1,unitordernotarg,`manashieldoff`,WESTRING_UNITORDERNOTARG_MANASHIELDOFF\nUnitOrderElementalFury=1,unitordernotarg,`elementalfury`,WESTRING_UNITORDERNOTARG_ELEMENTALFURY\nUnitOrderHowlOfTerror=1,unitordernotarg,`howlofterror`,WESTRING_UNITORDERNOTARG_HOWLOFTERROR\nUnitOrderPoisonArrows=0,unitordernotarg,`poisonarrows`,WESTRING_UNITORDERNOTARG_POISONARROWON\nUnitOrderUnPoisonArrows=0,unitordernotarg,`unpoisonarrows`,WESTRING_UNITORDERNOTARG_POISONARROWOFF\nUnitOrderChannel=1,unitordernotarg,`channel`,WESTRING_UNITORDERNOTARG_CHANNEL\nUnitOrderMedivhRavenForm=0,unitordernotarg,`ravenform`,WESTRING_UNITORDERNOTARG_MEDIVHRAVENFORM\nUnitOrderMedivhUnRavenForm=0,unitordernotarg,`unravenform`,WESTRING_UNITORDERNOTARG_MEDIVHUNRAVENFORM\nUnitOrderRexxarBattleRoar=1,unitordernotarg,`battleroar`,WESTRING_UNITORDERNOTARG_REXXARBATTLEROAR\nUnitOrderColdArrows=0,unitordernotarg,`coldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWS\nUnitOrderUnColdArrows=0,unitordernotarg,`uncoldarrows`,WESTRING_UNITORDERNOTARG_UNCOLDARROWS\nHeroSkillBlizzard=0,heroskillcode,'AHbz',WESTRING_HEROSKILL_BLIZZARD\nHeroSkillWaterElemental=0,heroskillcode,'AHwe',WESTRING_HEROSKILL_WATERELEMENTAL\nHeroSkillBrillianceAura=0,heroskillcode,'AHab',WESTRING_HEROSKILL_BRILLIANCEAURA\nHeroSkillMassTeleport=0,heroskillcode,'AHmt',WESTRING_HEROSKILL_MASSTELEPORT\nHeroSkillFlameStrike=1,heroskillcode,'AHfs',WESTRING_HEROSKILL_FLAMESTRIKE\nHeroSkillBanish=1,heroskillcode,'AHbn',WESTRING_HEROSKILL_BANISH\nHeroSkillSiphonMana=1,heroskillcode,'AHdr',WESTRING_HEROSKILL_SIPHONMANA\nHeroSkillPhoenix=1,heroskillcode,'AHpx',WESTRING_HEROSKILL_PHOENIX\nHeroSkillStormBolt=0,heroskillcode,'AHtb',WESTRING_HEROSKILL_STORMBOLT\nHeroSkillThunderClap=0,heroskillcode,'AHtc',WESTRING_HEROSKILL_THUNDERCLAP\nHeroSkillBash=0,heroskillcode,'AHbh',WESTRING_HEROSKILL_BASH\nHeroSkillAvatar=0,heroskillcode,'AHav',WESTRING_HEROSKILL_AVATAR\nHeroSkillDivineShield=0,heroskillcode,'AHds',WESTRING_HEROSKILL_DIVINESHIELD\nHeroSkillHolyBolt=0,heroskillcode,'AHhb',WESTRING_HEROSKILL_HOLYBOLT\nHeroSkillDevotionAura=0,heroskillcode,'AHad',WESTRING_HEROSKILL_DEVOTIONAURA\nHeroSkillResurrection=0,heroskillcode,'AHre',WESTRING_HEROSKILL_RESURRECTION\nHeroSkillWindWalk=0,heroskillcode,'AOwk',WESTRING_HEROSKILL_WINDWALK\nHeroSkillMirrorImage=0,heroskillcode,'AOmi',WESTRING_HEROSKILL_MIRRORIMAGE\nHeroSkillCriticalStrike=0,heroskillcode,'AOcr',WESTRING_HEROSKILL_CRITICALSTRIKE\nHeroSkillWhirlwind=0,heroskillcode,'AOww',WESTRING_HEROSKILL_WHIRLWIND\nHeroSkillChainLightning=0,heroskillcode,'AOcl',WESTRING_HEROSKILL_CHAINLIGHTNING\nHeroSkillFarSight=0,heroskillcode,'AOfs',WESTRING_HEROSKILL_FARSIGHT\nHeroSkillSpiritWolf=0,heroskillcode,'AOsf',WESTRING_HEROSKILL_SPIRITWOLF\nHeroSkillEarthquake=0,heroskillcode,'AOeq',WESTRING_HEROSKILL_EARTHQUAKE\nHeroSkillHealingWave=1,heroskillcode,'AOhw',WESTRING_HEROSKILL_HEALINGWAVE\nHeroSkillHex=1,heroskillcode,'AOhx',WESTRING_HEROSKILL_HEX\nHeroSkillSerpentWard=1,heroskillcode,'AOsw',WESTRING_HEROSKILL_SERPENTWARD\nHeroSkillVoodoo=1,heroskillcode,'AOvd',WESTRING_HEROSKILL_VOODOO\nHeroSkillShockwave=0,heroskillcode,'AOsh',WESTRING_HEROSKILL_SHOCKWAVE\nHeroSkillWarStomp=0,heroskillcode,'AOws',WESTRING_HEROSKILL_WARSTOMP\nHeroSkillEnduranceAura=0,heroskillcode,'AOae',WESTRING_HEROSKILL_ENDURANCEAURA\nHeroSkillReincarnation=0,heroskillcode,'AOre',WESTRING_HEROSKILL_REINCARNATION\nHeroSkillImpale=1,heroskillcode,'AUim',WESTRING_HEROSKILL_IMPALE\nHeroSkillThornyShield=1,heroskillcode,'AUts',WESTRING_HEROSKILL_THORNYSHIELD\nHeroSkillCarrionScarabs=1,heroskillcode,'AUcb',WESTRING_HEROSKILL_CARRIONSCARABS\nHeroSkillLocustSwarm=1,heroskillcode,'AUls',WESTRING_HEROSKILL_LOCUSTSWARM\nHeroSkillDeathCoil=0,heroskillcode,'AUdc',WESTRING_HEROSKILL_DEATHCOIL\nHeroSkillDeathPact=0,heroskillcode,'AUdp',WESTRING_HEROSKILL_DEATHPACT\nHeroSkillUnholyAura=0,heroskillcode,'AUau',WESTRING_HEROSKILL_UNHOLYAURA\nHeroSkillAnimateDead=0,heroskillcode,'AUan',WESTRING_HEROSKILL_ANIMATEDEAD\nHeroSkillCarrionSwarm=0,heroskillcode,'AUcs',WESTRING_HEROSKILL_CARRIONSWARM\nHeroSkillSleep=0,heroskillcode,'AUsl',WESTRING_HEROSKILL_SLEEP\nHeroSkillVampiricAura=0,heroskillcode,'AUav',WESTRING_HEROSKILL_VAMPIRICAURA\nHeroSkillDarkSummoning=0,heroskillcode,'AUin',WESTRING_HEROSKILL_DARKSUMMONING\nHeroSkillFrostNova=0,heroskillcode,'AUfn',WESTRING_HEROSKILL_FROSTNOVA\nHeroSkillFrostArmor=0,heroskillcode,'AUfa',WESTRING_HEROSKILL_FROSTARMOR\nHeroSkillDarkRitual=0,heroskillcode,'AUdr',WESTRING_HEROSKILL_DARKRITUAL\nHeroSkillDeathAndDecay=0,heroskillcode,'AUdd',WESTRING_HEROSKILL_DEATHANDDECAY\nHeroSkillManaBurn=0,heroskillcode,'AEmb',WESTRING_HEROSKILL_MANABURN\nHeroSkillImmolation=0,heroskillcode,'AEim',WESTRING_HEROSKILL_IMMOLATION\nHeroSkillEvasion=0,heroskillcode,'AEev',WESTRING_HEROSKILL_EVASION\nHeroSkillMetamorphosis=0,heroskillcode,'AEme',WESTRING_HEROSKILL_METAMORPHOSIS\nHeroSkillEntanglingRoots=0,heroskillcode,'AEer',WESTRING_HEROSKILL_ENTANGLINGROOTS\nHeroSkillForceOfNature=0,heroskillcode,'AEfn',WESTRING_HEROSKILL_FORCEOFNATURE\nHeroSkillThornsAura=0,heroskillcode,'AEah',WESTRING_HEROSKILL_THORNSAURA\nHeroSkillTranquility=0,heroskillcode,'AEtq',WESTRING_HEROSKILL_TRANQUILITY\nHeroSkillScout=0,heroskillcode,'AEst',WESTRING_HEROSKILL_SCOUT\nHeroSkillSearingArrows=0,heroskillcode,'AHfa',WESTRING_HEROSKILL_SEARINGARROWS\nHeroSkillTrueshotAura=0,heroskillcode,'AEar',WESTRING_HEROSKILL_TRUESHOTAURA\nHeroSkillStarfall=0,heroskillcode,'AEsf',WESTRING_HEROSKILL_STARFALL\nHeroSkillFanOfKnives=1,heroskillcode,'AEfk',WESTRING_HEROSKILL_FANOFKNIVES\nHeroSkillBlink=1,heroskillcode,'AEbl',WESTRING_HEROSKILL_BLINK\nHeroSkillShadowTouch=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_SHADOWTOUCH\nHeroSkillSpiritOfVengeance=1,heroskillcode,'AEsv',WESTRING_HEROSKILL_SPIRITOFVENGEANCE\nHeroSkillGrizzly=1,heroskillcode,'ANsg',WESTRING_HEROSKILL_GRIZZLY\nHeroSkillQuillbeast=1,heroskillcode,'ANsq',WESTRING_HEROSKILL_QUILLBEAST\nHeroSkillWarEagle=1,heroskillcode,'ANsw',WESTRING_HEROSKILL_WAREAGLE\nHeroSkillStampede=1,heroskillcode,'ANst',WESTRING_HEROSKILL_STAMPEDE\nHeroSkillSilence=1,heroskillcode,'ANsi',WESTRING_HEROSKILL_SILENCE\nHeroSkillBlackArrow=1,heroskillcode,'ANba',WESTRING_HEROSKILL_BLACKARROW\nHeroSkillLifeDrain=1,heroskillcode,'ANdr',WESTRING_HEROSKILL_LIFEDRAIN\nHeroSkillCharm=1,heroskillcode,'ANch',WESTRING_HEROSKILL_CHARM\nHeroSkillForkedLightning=1,heroskillcode,'ANfl',WESTRING_HEROSKILL_FORKEDLIGHTNING\nHeroSkillColdArrow=1,heroskillcode,'ANfa',WESTRING_HEROSKILL_COLDARROW\nHeroSkillManaShield=1,heroskillcode,'ANms',WESTRING_HEROSKILL_MANASHIELD\nHeroSkillTornado=1,heroskillcode,'ANto',WESTRING_HEROSKILL_TORNADO\nHeroSkillBreathOfFire=1,heroskillcode,'ANbf',WESTRING_HEROSKILL_BREATHOFFIRE\nHeroSkillStrongDrink=1,heroskillcode,'ANdh',WESTRING_HEROSKILL_STRONGDRINK\nHeroSkillDrunkenBrawler=1,heroskillcode,'ANdb',WESTRING_HEROSKILL_DRUNKENBRAWLER\nHeroSkillElementalFury=1,heroskillcode,'ANef',WESTRING_HEROSKILL_ELEMENTALFURY\nHeroSkillRainOfFire=1,heroskillcode,'ANrf',WESTRING_HEROSKILL_RAINOFFIRE\nHeroSkillHowlOfTerror=1,heroskillcode,'ANht',WESTRING_HEROSKILL_HOWLOFTERROR\nHeroSkillCleavingAttack=1,heroskillcode,'ANca',WESTRING_HEROSKILL_CLEAVINGATTACK\nHeroSkillDoom=1,heroskillcode,'ANdo',WESTRING_HEROSKILL_DOOM\nHeroSkillChainLightning2=1,heroskillcode,'AOcl',WESTRING_HEROSKILL_AKAMA_CHAINLIGHTNING\nHeroSkillSpiritBeast=1,heroskillcode,'ACs7',WESTRING_HEROSKILL_AKAMA_FERALSPIRIT\nHeroSkillShadowTouch2=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_AKAMA_SHADOWTOUCH\nHeroSkillReincarnation2=1,heroskillcode,'ANr2',WESTRING_HEROSKILL_AKAMA_REINCARNATION\nHeroSkillDarkPortal=0,heroskillcode,'ANdp',WESTRING_HEROSKILL_DARKPORTAL\nHeroSkillRainOfChaos=0,heroskillcode,'ANrc',WESTRING_HEROSKILL_RAINOFCHAOS\nHeroSkillArchiBash=0,heroskillcode,'AHah',WESTRING_HEROSKILL_ARCHIBASH\nHeroSkillFingerOfDeath=0,heroskillcode,'ANfd',WESTRING_HEROSKILL_FINGEROFDEATH\nHeroSkillBalnaSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_BALNA_SLEEP\nHeroSkillBalnaVampiricAura=1,heroskillcode,'AUav',WESTRING_HEROSKILL_BALNA_VAMPIRICAURA\nHeroSkillBalnaRainOfChaos=1,heroskillcode,'ANr3',WESTRING_HEROSKILL_BALNA_RAINOFCHAOS\nHeroSkillBalnaFingerOfPain=1,heroskillcode,'ACf3',WESTRING_HEROSKILL_BALNA_FINGEROFPAIN\nHeroSkillBalnaEarthquake=1,heroskillcode,'AOeq',WESTRING_HEROSKILL_BALNA_EARTHQUAKE\nHeroSkillChenBreathOfFire=1,heroskillcode,'ANcf',WESTRING_HEROSKILL_CHEN_BREATHOFFIRE\nHeroSkillChenStrongDrink=1,heroskillcode,'Acdh',WESTRING_HEROSKILL_CHEN_STRONGDRINK\nHeroSkillChenDrunkenBrawler=1,heroskillcode,'Acdb',WESTRING_HEROSKILL_CHEN_DRUNKENBRAWLER\nHeroSkillChenElementalFury=1,heroskillcode,'Acef',WESTRING_HEROSKILL_CHEN_ELEMENTALFURY\nHeroSkillChenAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_CHEN_ATTRIBUTEBONUS\nHeroSkillDetheSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_DETHE_SLEEP\nHeroSkillDetheShadowTouch=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_DETHE_SHADOWTOUCH\nHeroSkillDetheCarrionSwarm=1,heroskillcode,'AUcs',WESTRING_HEROSKILL_DETHE_CARRIONSWARM\nHeroSkillDetheDeathAndDecay=1,heroskillcode,'AUdd',WESTRING_HEROSKILL_DETHE_DEATHANDDECAY\nHeroSkillGaritShockwave=1,heroskillcode,'ANsh',WESTRING_HEROSKILL_GARIT_SHOCKWAVE\nHeroSkillGaritHolyLight=1,heroskillcode,'AHhb',WESTRING_HEROSKILL_GARIT_HOLYLIGHT\nHeroSkillGaritDevotionAura=1,heroskillcode,'AHad',WESTRING_HEROSKILL_GARIT_DEVOTIONAURA\nHeroSkillGaritAvatar=1,heroskillcode,'ANav',WESTRING_HEROSKILL_GARIT_AVATAR\nHeroSkillIllimorphosis=0,heroskillcode,'AEIl',WESTRING_HEROSKILL_ILLIMORPHOSIS\nHeroSkillEvilIllimorphosis=0,heroskillcode,'AEvi',WESTRING_HEROSKILL_EVILILLIMORPHOSIS\nHeroSkillMalganisSleep=0,heroskillcode,'ANdc',WESTRING_HEROSKILL_DARKCONVERSION\nHeroSkillSoulPreservation=0,heroskillcode,'ANsl',WESTRING_HEROSKILL_SOULPRESERVATION\nHeroSkillManarothReincarnation=0,heroskillcode,'ANrn',WESTRING_HEROSKILL_MANAROTHREINCARNATION\nHeroSkillRexxarGrizzly=1,heroskillcode,'Arsg',WESTRING_HEROSKILL_REXXAR_GRIZZLY\nHeroSkillRexxarQuillbeast=1,heroskillcode,'Arsq',WESTRING_HEROSKILL_REXXAR_QUILLBEAST\nHeroSkillRexxarStormBolt=1,heroskillcode,'ANsb',WESTRING_HEROSKILL_REXXAR_STORMBOLT\nHeroSkillRexxarStampede=1,heroskillcode,'Arsp',WESTRING_HEROSKILL_REXXAR_STAMPEDE\nHeroSkillRexxarAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_REXXAR_ATTRIBUTEBONUS\nHeroSkillRokhanHealingWave=1,heroskillcode,'ANhw',WESTRING_HEROSKILL_ROKHAN_HEALINGWAVE\nHeroSkillRokhanHex=1,heroskillcode,'ANhx',WESTRING_HEROSKILL_ROKHAN_HEX\nHeroSkillRokhanSerpentWard=1,heroskillcode,'Arsw',WESTRING_HEROSKILL_ROKHAN_SERPENTWARD\nHeroSkillRokhanVoodooSpirits=1,heroskillcode,'AOls',WESTRING_HEROSKILL_ROKHAN_VOODOOSPIRITS\nHeroSkillRokhanAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_ROKHAN_ATTRIBUTEBONUS\nHeroSkillColdArrows=0,heroskillcode,'AHca',WESTRING_HEROSKILL_COLDARROWS\nHeroSkillTichondriusInferno=0,heroskillcode,'SNin',WESTRING_HEROSKILL_TICHONDRIUSINFERNO\nHeroSkillVarimSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_VARIM_SLEEP\nHeroSkillVarimVampiricAura=1,heroskillcode,'AUav',WESTRING_HEROSKILL_VARIM_VAMPIRICAURA\nHeroSkillVarimRainOfFire=1,heroskillcode,'ANrf',WESTRING_HEROSKILL_VARIM_RAINOFFIRE\nHeroSkillVarimDoom=1,heroskillcode,'ANdo',WESTRING_HEROSKILL_VARIM_DOOM\nHeroSkillInfernal=0,heroskillcode,'ANin',WESTRING_HEROSKILL_INFERNAL\nHeroSkillMalganisSleepFast=0,heroskillcode,'SNdc',WESTRING_HEROSKILL_DARKCONVERSIONFAST\nHeroSkillDarkSummoningOld=0,heroskillcode,'AUds',WESTRING_HEROSKILL_DARKSUMMONINGOLD\nWeatherAshenvaleHeavyRain=0,weathereffectcode,'RAhr',WESTRING_WEATHER_ASHENVALEHEAVYRAIN\nWeatherAshenvaleLightRain=0,weathereffectcode,'RAlr',WESTRING_WEATHER_ASHENVALELIGHTRAIN\nWeatherDalaranShield=0,weathereffectcode,'MEds',WESTRING_WEATHER_DALARANSHIELD\nWeatherDungeonHeavyBlueFog=0,weathereffectcode,'FDbh',WESTRING_WEATHER_DUNGEONHEAVYBLUEFOG\nWeatherDungeonLightBlueFog=0,weathereffectcode,'FDbl',WESTRING_WEATHER_DUNGEONBLUEFOG\nWeatherDungeonHeavyGreenFog=0,weathereffectcode,'FDgh',WESTRING_WEATHER_DUNGEONHEAVYGREENFOG\nWeatherDungeonLightGreenFog=0,weathereffectcode,'FDgl',WESTRING_WEATHER_DUNGEONGREENFOG\nWeatherDungeonHeavyRedFog=0,weathereffectcode,'FDrh',WESTRING_WEATHER_DUNGEONHEAVYREDFOG\nWeatherDungeonLightRedFog=0,weathereffectcode,'FDrl',WESTRING_WEATHER_DUNGEONREDFOG\nWeatherDungeonHeavyWhiteFog=0,weathereffectcode,'FDwh',WESTRING_WEATHER_DUNGEONHEAVYWHITEFOG\nWeatherDungeonLightWhiteFog=0,weathereffectcode,'FDwl',WESTRING_WEATHER_DUNGEONWHITEFOG\nWeatherLordaeronHeavyRain=0,weathereffectcode,'RLhr',WESTRING_WEATHER_LORDAERONHEAVYRAIN\nWeatherLordaeronLightRain=0,weathereffectcode,'RLlr',WESTRING_WEATHER_LORDAERONLIGHTRAIN\nWeatherNorthrendBlizzard=0,weathereffectcode,'SNbs',WESTRING_WEATHER_NORTHRENDBLIZZARD\nWeatherNorthrendHeavySnow=0,weathereffectcode,'SNhs',WESTRING_WEATHER_NORTHRENDHEAVYSNOW\nWeatherNorthrendLightSnow=0,weathereffectcode,'SNls',WESTRING_WEATHER_NORTHRENDLIGHTSNOW\nWeatherOutlandWind=1,weathereffectcode,'WOcw',WESTRING_WEATHER_OUTLANDWIND\nWeatherOutlandWindLight=1,weathereffectcode,'WOlw',WESTRING_WEATHER_OUTLANDWINDLIGHT\nWeatherRaysOfLight=0,weathereffectcode,'LRaa',WESTRING_WEATHER_RAYSOFLIGHT\nWeatherRaysOfMoonlight=0,weathereffectcode,'LRma',WESTRING_WEATHER_RAYSOFMOONLIGHT\nWeatherHeavyWind=0,weathereffectcode,'WNcw',WESTRING_WEATHER_WIND\nAttackTypeNormal=1,attacktype,ATTACK_TYPE_NORMAL,WESTRING_UE_ATTACKTYPE_SPELLS\nAttackTypeMelee=1,attacktype,ATTACK_TYPE_MELEE,WESTRING_UE_ATTACKTYPE_NORMAL\nAttackTypePierce=1,attacktype,ATTACK_TYPE_PIERCE,WESTRING_UE_ATTACKTYPE_PIERCE\nAttackTypeSiege=1,attacktype,ATTACK_TYPE_SIEGE,WESTRING_UE_ATTACKTYPE_SIEGE\nAttackTypeMagic=1,attacktype,ATTACK_TYPE_MAGIC,WESTRING_UE_ATTACKTYPE_MAGIC\nAttackTypeChaos=1,attacktype,ATTACK_TYPE_CHAOS,WESTRING_UE_ATTACKTYPE_CHAOS\nAttackTypeHero=1,attacktype,ATTACK_TYPE_HERO,WESTRING_UE_ATTACKTYPE_HERO\nDamageTypeUnknown=1,damagetype,DAMAGE_TYPE_UNKNOWN,WESTRING_DAMAGE_TYPE_UNKNOWN\nDamageTypeNormal=1,damagetype,DAMAGE_TYPE_NORMAL,WESTRING_DAMAGE_TYPE_NORMAL\nDamageTypeEnhanced=1,damagetype,DAMAGE_TYPE_ENHANCED,WESTRING_DAMAGE_TYPE_ENHANCED\nDamageTypeFire=1,damagetype,DAMAGE_TYPE_FIRE,WESTRING_DAMAGE_TYPE_FIRE\nDamageTypeCold=1,damagetype,DAMAGE_TYPE_COLD,WESTRING_DAMAGE_TYPE_COLD\nDamageTypeLightning=1,damagetype,DAMAGE_TYPE_LIGHTNING,WESTRING_DAMAGE_TYPE_LIGHTNING\nDamageTypePoison=1,damagetype,DAMAGE_TYPE_POISON,WESTRING_DAMAGE_TYPE_POISON\nDamageTypeDisease=1,damagetype,DAMAGE_TYPE_DISEASE,WESTRING_DAMAGE_TYPE_DISEASE\nDamageTypeDivine=1,damagetype,DAMAGE_TYPE_DIVINE,WESTRING_DAMAGE_TYPE_DIVINE\nDamageTypeMagic=1,damagetype,DAMAGE_TYPE_MAGIC,WESTRING_DAMAGE_TYPE_MAGIC\nDamageTypeSonic=1,damagetype,DAMAGE_TYPE_SONIC,WESTRING_DAMAGE_TYPE_SONIC\nDamageTypeAcid=1,damagetype,DAMAGE_TYPE_ACID,WESTRING_DAMAGE_TYPE_ACID\nDamageTypeForce=1,damagetype,DAMAGE_TYPE_FORCE,WESTRING_DAMAGE_TYPE_FORCE\nDamageTypeDeath=1,damagetype,DAMAGE_TYPE_DEATH,WESTRING_DAMAGE_TYPE_DEATH\nDamageTypeMind=1,damagetype,DAMAGE_TYPE_MIND,WESTRING_DAMAGE_TYPE_MIND\nDamageTypePlant=1,damagetype,DAMAGE_TYPE_PLANT,WESTRING_DAMAGE_TYPE_PLANT\nDamageTypeDefensive=1,damagetype,DAMAGE_TYPE_DEFENSIVE,WESTRING_DAMAGE_TYPE_DEFENSIVE\nDamageTypeDemolition=1,damagetype,DAMAGE_TYPE_DEMOLITION,WESTRING_DAMAGE_TYPE_DEMOLITION\nDamageTypeSlowPoison=1,damagetype,DAMAGE_TYPE_SLOW_POISON,WESTRING_DAMAGE_TYPE_SLOW_POISON\nDamageTypeSpiritLink=1,damagetype,DAMAGE_TYPE_SPIRIT_LINK,WESTRING_DAMAGE_TYPE_SPIRIT_LINK\nDamageTypeShadowStrike=1,damagetype,DAMAGE_TYPE_SHADOW_STRIKE,WESTRING_DAMAGE_TYPE_SHADOW_STRIKE\nDamageTypeUniversal=1,damagetype,DAMAGE_TYPE_UNIVERSAL,WESTRING_DAMAGE_TYPE_UNIVERSAL\nWeaponTypeMetalLightChop=1,weapontype,WEAPON_TYPE_METAL_LIGHT_CHOP,WESTRING_UE_COMBATSOUND_METALLIGHTCHOP\nWeaponTypeMetalMediumChop=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_CHOP,WESTRING_UE_COMBATSOUND_METALMEDIUMCHOP\nWeaponTypeMetalHeavyChop=1,weapontype,WEAPON_TYPE_METAL_HEAVY_CHOP,WESTRING_UE_COMBATSOUND_METALHEAVYCHOP\nWeaponTypeMetalLightSlice=1,weapontype,WEAPON_TYPE_METAL_LIGHT_SLICE,WESTRING_UE_COMBATSOUND_METALLIGHTSLICE\nWeaponTypeMetalMediumSlice=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_SLICE,WESTRING_UE_COMBATSOUND_METALMEDIUMSLICE\nWeaponTypeMetalHeavySlice=1,weapontype,WEAPON_TYPE_METAL_HEAVY_SLICE,WESTRING_UE_COMBATSOUND_METALHEAVYSLICE\nWeaponTypeMetalMediumBash=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_BASH,WESTRING_UE_COMBATSOUND_METALMEDIUMBASH\nWeaponTypeMetalHeavyBash=1,weapontype,WEAPON_TYPE_METAL_HEAVY_BASH,WESTRING_UE_COMBATSOUND_METALHEAVYBASH\nWeaponTypeWoodLightBash=1,weapontype,WEAPON_TYPE_WOOD_LIGHT_BASH,WESTRING_UE_COMBATSOUND_WOODLIGHTBASH\nWeaponTypeWoodMediumBash=1,weapontype,WEAPON_TYPE_WOOD_MEDIUM_BASH,WESTRING_UE_COMBATSOUND_WOODMEDIUMBASH\nWeaponTypeWoodHeavyBash=1,weapontype,WEAPON_TYPE_WOOD_HEAVY_BASH,WESTRING_UE_COMBATSOUND_WOODHEAVYBASH\nWeaponTypeAxeMediumChop=1,weapontype,WEAPON_TYPE_AXE_MEDIUM_CHOP,WESTRING_UE_COMBATSOUND_AXEMEDIUMCHOP\nWeaponTypeRockHeavyBash=1,weapontype,WEAPON_TYPE_ROCK_HEAVY_BASH,WESTRING_UE_COMBATSOUND_ROCKHEAVYBASH\nPathingTypeAny=0,pathingtype,PATHING_TYPE_ANY,WESTRING_PATHINGTYPE_ANY\nPathingTypeWalkability=0,pathingtype,PATHING_TYPE_WALKABILITY,WESTRING_PATHINGTYPE_WALKABILITY\nPathingTypeFlyability=0,pathingtype,PATHING_TYPE_FLYABILITY,WESTRING_PATHINGTYPE_FLYABILITY\nPathingTypeBuildability=0,pathingtype,PATHING_TYPE_BUILDABILITY,WESTRING_PATHINGTYPE_BUILDABILITY\nPathingTypePeonHarvestPathing=0,pathingtype,PATHING_TYPE_PEONHARVESTPATHING,WESTRING_PATHINGTYPE_PEONHARVESTPATHING\nPathingTypeBlightPathing=0,pathingtype,PATHING_TYPE_BLIGHTPATHING,WESTRING_PATHINGTYPE_BLIGHTPATHING\nPathingTypeFloatability=0,pathingtype,PATHING_TYPE_FLOATABILITY,WESTRING_PATHINGTYPE_FLOATABILITY\nPathingTypeAmphibiousPathing=0,pathingtype,PATHING_TYPE_AMPHIBIOUSPATHING,WESTRING_PATHINGTYPE_AMPHIBIOUSPATHING\nEffectTypeEffect=1,effecttype,EFFECT_TYPE_EFFECT,WESTRING_EFFECT_TYPE_EFFECT\nEffectTypeTarget=1,effecttype,EFFECT_TYPE_TARGET,WESTRING_EFFECT_TYPE_TARGET\nEffectTypeCaster=1,effecttype,EFFECT_TYPE_CASTER,WESTRING_EFFECT_TYPE_CASTER\nEffectTypeSpecial=1,effecttype,EFFECT_TYPE_SPECIAL,WESTRING_EFFECT_TYPE_SPECIAL\nEffectTypeAreaEffect=1,effecttype,EFFECT_TYPE_AREA_EFFECT,WESTRING_EFFECT_TYPE_AREA_EFFECT\nEffectTypeAOE=1,effecttype,EFFECT_TYPE_AREA_EFFECT,WESTRING_EFFECTTYPEOPTION_AREA_EFFECT\nEffectTypeMissile=1,effecttype,EFFECT_TYPE_MISSILE,WESTRING_EFFECT_TYPE_MISSILE\nEffectTypeLightning=1,effecttype,EFFECT_TYPE_LIGHTNING,WESTRING_EFFECT_TYPE_LIGHTNING\nSoundTypeEffect=1,soundtype,SOUND_TYPE_EFFECT,WESTRING_SOUND_TYPE_EFFECT\nSoundTypeEffectLooped=1,soundtype,SOUND_TYPE_EFFECT_LOOPED,WESTRING_SOUND_TYPE_EFFECT_LOOPED\nLightningCodeInit=1,lightningcode,\"`INIT`\",WESTRING_LIGHTNING_INIT\nLightningCodeClpb=1,lightningcode,\"`CLPB`\",WESTRING_LIGHTNING_CLPB\nLightningCodeClsb=1,lightningcode,\"`CLSB`\",WESTRING_LIGHTNING_CLSB\nLightningCodeMbur=1,lightningcode,\"`MBUR`\",WESTRING_LIGHTNING_MBUR\nLightningCodeChim=1,lightningcode,\"`CHIM`\",WESTRING_LIGHTNING_CHIM\nLightningCodeAfod=1,lightningcode,\"`AFOD`\",WESTRING_LIGHTNING_AFOD\nLightningCodeHwpb=1,lightningcode,\"`HWPB`\",WESTRING_LIGHTNING_HWPB\nLightningCodeHwsb=1,lightningcode,\"`HWSB`\",WESTRING_LIGHTNING_HWSB\nLightningCodeMfpb=1,lightningcode,\"`MFPB`\",WESTRING_LIGHTNING_MFPB\nLightningCodeDrab=1,lightningcode,\"`DRAB`\",WESTRING_LIGHTNING_DRAB\nLightningCodeDral=1,lightningcode,\"`DRAL`\",WESTRING_LIGHTNING_DRAL\nLightningCodeDram=1,lightningcode,\"`DRAM`\",WESTRING_LIGHTNING_DRAM\nLightningCodeFork=1,lightningcode,\"`FORK`\",WESTRING_LIGHTNING_FORK\nLightningCodeSplk=1,lightningcode,\"`SPLK`\",WESTRING_LIGHTNING_SPLK\nLightningCodeLeas=1,lightningcode,\"`LEAS`\",WESTRING_LIGHTNING_LEAS\nTerrainTypeLdrt=0,terraintype,'Ldrt',WESTRING_TERRAINTYPE_Ldrt\nTerrainTypeLdro=0,terraintype,'Ldro',WESTRING_TERRAINTYPE_Ldro\nTerrainTypeLdrg=0,terraintype,'Ldrg',WESTRING_TERRAINTYPE_Ldrg\nTerrainTypeLrok=0,terraintype,'Lrok',WESTRING_TERRAINTYPE_Lrok\nTerrainTypeLgrs=0,terraintype,'Lgrs',WESTRING_TERRAINTYPE_Lgrs\nTerrainTypeLgrd=0,terraintype,'Lgrd',WESTRING_TERRAINTYPE_Lgrd\nTerrainTypeFdrt=0,terraintype,'Fdrt',WESTRING_TERRAINTYPE_Fdrt\nTerrainTypeFdro=0,terraintype,'Fdro',WESTRING_TERRAINTYPE_Fdro\nTerrainTypeFdrg=0,terraintype,'Fdrg',WESTRING_TERRAINTYPE_Fdrg\nTerrainTypeFrok=0,terraintype,'Frok',WESTRING_TERRAINTYPE_Frok\nTerrainTypeFgrs=0,terraintype,'Fgrs',WESTRING_TERRAINTYPE_Fgrs\nTerrainTypeFgrd=0,terraintype,'Fgrd',WESTRING_TERRAINTYPE_Fgrd\nTerrainTypeWdrt=0,terraintype,'Wdrt',WESTRING_TERRAINTYPE_Wdrt\nTerrainTypeWdro=0,terraintype,'Wdro',WESTRING_TERRAINTYPE_Wdro\nTerrainTypeWsng=0,terraintype,'Wsng',WESTRING_TERRAINTYPE_Wsng\nTerrainTypeWrok=0,terraintype,'Wrok',WESTRING_TERRAINTYPE_Wrok\nTerrainTypeWgrs=0,terraintype,'Wgrs',WESTRING_TERRAINTYPE_Wgrs\nTerrainTypeWsnw=0,terraintype,'Wsnw',WESTRING_TERRAINTYPE_Wsnw\nTerrainTypeBdrt=0,terraintype,'Bdrt',WESTRING_TERRAINTYPE_Bdrt\nTerrainTypeBdrh=0,terraintype,'Bdrh',WESTRING_TERRAINTYPE_Bdrh\nTerrainTypeBdrr=0,terraintype,'Bdrr',WESTRING_TERRAINTYPE_Bdrr\nTerrainTypeBdrg=0,terraintype,'Bdrg',WESTRING_TERRAINTYPE_Bdrg\nTerrainTypeBdsr=0,terraintype,'Bdsr',WESTRING_TERRAINTYPE_Bdsr\nTerrainTypeBdsd=0,terraintype,'Bdsd',WESTRING_TERRAINTYPE_Bdsd\nTerrainTypeBflr=0,terraintype,'Bflr',WESTRING_TERRAINTYPE_Bflr\nTerrainTypeBgrr=0,terraintype,'Bgrr',WESTRING_TERRAINTYPE_Bgrr\nTerrainTypeAdrt=0,terraintype,'Adrt',WESTRING_TERRAINTYPE_Adrt\nTerrainTypeAdrd=0,terraintype,'Adrd',WESTRING_TERRAINTYPE_Adrd\nTerrainTypeAgrs=0,terraintype,'Agrs',WESTRING_TERRAINTYPE_Agrs\nTerrainTypeArck=0,terraintype,'Arck',WESTRING_TERRAINTYPE_Arck\nTerrainTypeAgrd=0,terraintype,'Agrd',WESTRING_TERRAINTYPE_Agrd\nTerrainTypeAvin=0,terraintype,'Avin',WESTRING_TERRAINTYPE_Avin\nTerrainTypeAdrg=0,terraintype,'Adrg',WESTRING_TERRAINTYPE_Adrg\nTerrainTypeAlvd=0,terraintype,'Alvd',WESTRING_TERRAINTYPE_Alvd\nTerrainTypeCdrt=0,terraintype,'Cdrt',WESTRING_TERRAINTYPE_Cdrt\nTerrainTypeCdrd=0,terraintype,'Cdrd',WESTRING_TERRAINTYPE_Cdrd\nTerrainTypeCpos=0,terraintype,'Cpos',WESTRING_TERRAINTYPE_Cpos\nTerrainTypeCrck=0,terraintype,'Crck',WESTRING_TERRAINTYPE_Crck\nTerrainTypeCvin=0,terraintype,'Cvin',WESTRING_TERRAINTYPE_Cvin\nTerrainTypeCgrs=0,terraintype,'Cgrs',WESTRING_TERRAINTYPE_Cgrs\nTerrainTypeClvg=0,terraintype,'Clvg',WESTRING_TERRAINTYPE_Clvg\nTerrainTypeNdrt=0,terraintype,'Ndrt',WESTRING_TERRAINTYPE_Ndrt\nTerrainTypeNdrd=0,terraintype,'Ndrd',WESTRING_TERRAINTYPE_Ndrd\nTerrainTypeNrck=0,terraintype,'Nrck',WESTRING_TERRAINTYPE_Nrck\nTerrainTypeNgrs=0,terraintype,'Ngrs',WESTRING_TERRAINTYPE_Ngrs\nTerrainTypeNice=0,terraintype,'Nice',WESTRING_TERRAINTYPE_Nice\nTerrainTypeNsnw=0,terraintype,'Nsnw',WESTRING_TERRAINTYPE_Nsnw\nTerrainTypeNsnr=0,terraintype,'Nsnr',WESTRING_TERRAINTYPE_Nsnr\nTerrainTypeYdrt=0,terraintype,'Ydrt',WESTRING_TERRAINTYPE_Ydrt\nTerrainTypeYdtr=0,terraintype,'Ydtr',WESTRING_TERRAINTYPE_Ydtr\nTerrainTypeYblm=0,terraintype,'Yblm',WESTRING_TERRAINTYPE_Yblm\nTerrainTypeYbtl=0,terraintype,'Ybtl',WESTRING_TERRAINTYPE_Ybtl\nTerrainTypeYsqd=0,terraintype,'Ysqd',WESTRING_TERRAINTYPE_Ysqd\nTerrainTypeYrtl=0,terraintype,'Yrtl',WESTRING_TERRAINTYPE_Yrtl\nTerrainTypeYgsb=0,terraintype,'Ygsb',WESTRING_TERRAINTYPE_Ygsb\nTerrainTypeYhdg=0,terraintype,'Yhdg',WESTRING_TERRAINTYPE_Yhdg\nTerrainTypeYwmb=0,terraintype,'Ywmb',WESTRING_TERRAINTYPE_Ywmb\nTerrainTypeVdrt=0,terraintype,'Vdrt',WESTRING_TERRAINTYPE_Vdrt\nTerrainTypeVdrr=0,terraintype,'Vdrr',WESTRING_TERRAINTYPE_Vdrr\nTerrainTypeVcrp=0,terraintype,'Vcrp',WESTRING_TERRAINTYPE_Vcrp\nTerrainTypeVcbp=0,terraintype,'Vcbp',WESTRING_TERRAINTYPE_Vcbp\nTerrainTypeVstp=0,terraintype,'Vstp',WESTRING_TERRAINTYPE_Vstp\nTerrainTypeVgrs=0,terraintype,'Vgrs',WESTRING_TERRAINTYPE_Vgrs\nTerrainTypeVrck=0,terraintype,'Vrck',WESTRING_TERRAINTYPE_Vrck\nTerrainTypeVgrt=0,terraintype,'Vgrt',WESTRING_TERRAINTYPE_Vgrt\nTerrainTypeQdrt=0,terraintype,'Qdrt',WESTRING_TERRAINTYPE_Qdrt\nTerrainTypeQdrr=0,terraintype,'Qdrr',WESTRING_TERRAINTYPE_Qdrr\nTerrainTypeQcrp=0,terraintype,'Qcrp',WESTRING_TERRAINTYPE_Qcrp\nTerrainTypeQcbp=0,terraintype,'Qcbp',WESTRING_TERRAINTYPE_Qcbp\nTerrainTypeQstp=0,terraintype,'Qstp',WESTRING_TERRAINTYPE_Qstp\nTerrainTypeQgrs=0,terraintype,'Qgrs',WESTRING_TERRAINTYPE_Qgrs\nTerrainTypeQrck=0,terraintype,'Qrck',WESTRING_TERRAINTYPE_Qrck\nTerrainTypeQgrt=0,terraintype,'Qgrt',WESTRING_TERRAINTYPE_Qgrt\nTerrainTypeXdrt=0,terraintype,'Xdrt',WESTRING_TERRAINTYPE_Xdrt\nTerrainTypeXdtr=0,terraintype,'Xdtr',WESTRING_TERRAINTYPE_Xdtr\nTerrainTypeXblm=0,terraintype,'Xblm',WESTRING_TERRAINTYPE_Xblm\nTerrainTypeXbtl=0,terraintype,'Xbtl',WESTRING_TERRAINTYPE_Xbtl\nTerrainTypeXsqd=0,terraintype,'Xsqd',WESTRING_TERRAINTYPE_Xsqd\nTerrainTypeXrtl=0,terraintype,'Xrtl',WESTRING_TERRAINTYPE_Xrtl\nTerrainTypeXgsb=0,terraintype,'Xgsb',WESTRING_TERRAINTYPE_Xgsb\nTerrainTypeXhdg=0,terraintype,'Xhdg',WESTRING_TERRAINTYPE_Xhdg\nTerrainTypeXwmb=0,terraintype,'Xwmb',WESTRING_TERRAINTYPE_Xwmb\nTerrainTypeDdrt=0,terraintype,'Ddrt',WESTRING_TERRAINTYPE_Ddrt\nTerrainTypeDbrk=0,terraintype,'Dbrk',WESTRING_TERRAINTYPE_Dbrk\nTerrainTypeDrds=0,terraintype,'Drds',WESTRING_TERRAINTYPE_Drds\nTerrainTypeDlvc=0,terraintype,'Dlvc',WESTRING_TERRAINTYPE_Dlvc\nTerrainTypeDlav=0,terraintype,'Dlav',WESTRING_TERRAINTYPE_Dlav\nTerrainTypeDdkr=0,terraintype,'Ddkr',WESTRING_TERRAINTYPE_Ddkr\nTerrainTypeDgrs=0,terraintype,'Dgrs',WESTRING_TERRAINTYPE_Dgrs\nTerrainTypeDsqd=0,terraintype,'Dsqd',WESTRING_TERRAINTYPE_Dsqd\nTerrainTypeGdrt=0,terraintype,'Gdrt',WESTRING_TERRAINTYPE_Gdrt\nTerrainTypeGbrk=0,terraintype,'Gbrk',WESTRING_TERRAINTYPE_Gbrk\nTerrainTypeGrds=0,terraintype,'Grds',WESTRING_TERRAINTYPE_Grds\nTerrainTypeGlvc=0,terraintype,'Glvc',WESTRING_TERRAINTYPE_Glvc\nTerrainTypeGlav=0,terraintype,'Glav',WESTRING_TERRAINTYPE_Glav\nTerrainTypeGdkr=0,terraintype,'Gdkr',WESTRING_TERRAINTYPE_Gdkr\nTerrainTypeGgrs=0,terraintype,'Ggrs',WESTRING_TERRAINTYPE_Ggrs\nTerrainTypeGsqd=0,terraintype,'Gsqd',WESTRING_TERRAINTYPE_Gsqd\nTerrainTypeZdrt=0,terraintype,'Zdrt',WESTRING_TERRAINTYPE_Zdrt\nTerrainTypeZdtr=0,terraintype,'Zdtr',WESTRING_TERRAINTYPE_Zdtr\nTerrainTypeZdrg=0,terraintype,'Zdrg',WESTRING_TERRAINTYPE_Zdrg\nTerrainTypeZbks=0,terraintype,'Zbks',WESTRING_TERRAINTYPE_Zbks\nTerrainTypeZsan=0,terraintype,'Zsan',WESTRING_TERRAINTYPE_Zsan\nTerrainTypeZbkl=0,terraintype,'Zbkl',WESTRING_TERRAINTYPE_Zbkl\nTerrainTypeZtil=0,terraintype,'Ztil',WESTRING_TERRAINTYPE_Ztil\nTerrainTypeZgrs=0,terraintype,'Zgrs',WESTRING_TERRAINTYPE_Zgrs\nTerrainTypeZvin=0,terraintype,'Zvin',WESTRING_TERRAINTYPE_Zvin\nTerrainTypeIdrt=0,terraintype,'Idrt',WESTRING_TERRAINTYPE_Idrt\nTerrainTypeIdtr=0,terraintype,'Idtr',WESTRING_TERRAINTYPE_Idtr\nTerrainTypeIdki=0,terraintype,'Idki',WESTRING_TERRAINTYPE_Idki\nTerrainTypeIbkb=0,terraintype,'Ibkb',WESTRING_TERRAINTYPE_Ibkb\nTerrainTypeIrbk=0,terraintype,'Irbk',WESTRING_TERRAINTYPE_Irbk\nTerrainTypeItbk=0,terraintype,'Itbk',WESTRING_TERRAINTYPE_Itbk\nTerrainTypeIice=0,terraintype,'Iice',WESTRING_TERRAINTYPE_Iice\nTerrainTypeIbsq=0,terraintype,'Ibsq',WESTRING_TERRAINTYPE_Ibsq\nTerrainTypeIsnw=0,terraintype,'Isnw',WESTRING_TERRAINTYPE_Isnw\nTerrainTypeOdrt=0,terraintype,'Odrt',WESTRING_TERRAINTYPE_Odrt\nTerrainTypeOdtr=0,terraintype,'Odtr',WESTRING_TERRAINTYPE_Odtr\nTerrainTypeOsmb=0,terraintype,'Osmb',WESTRING_TERRAINTYPE_Osmb\nTerrainTypeOfst=0,terraintype,'Ofst',WESTRING_TERRAINTYPE_Ofst\nTerrainTypeOlgb=0,terraintype,'Olgb',WESTRING_TERRAINTYPE_Olgb\nTerrainTypeOrok=0,terraintype,'Orok',WESTRING_TERRAINTYPE_Orok\nTerrainTypeOfsl=0,terraintype,'Ofsl',WESTRING_TERRAINTYPE_Ofsl\nTerrainTypeOaby=0,terraintype,'Oaby',WESTRING_TERRAINTYPE_Oaby\nTerrainTypeKdrt=0,terraintype,'Kdrt',WESTRING_TERRAINTYPE_Kdrt\nTerrainTypeKfsl=0,terraintype,'Kfsl',WESTRING_TERRAINTYPE_Kfsl\nTerrainTypeKdtr=0,terraintype,'Kdtr',WESTRING_TERRAINTYPE_Kdtr\nTerrainTypeKfst=0,terraintype,'Kfst',WESTRING_TERRAINTYPE_Kfst\nTerrainTypeKsmb=0,terraintype,'Ksmb',WESTRING_TERRAINTYPE_Ksmb\nTerrainTypeKlgb=0,terraintype,'Klgb',WESTRING_TERRAINTYPE_Klgb\nTerrainTypeKsqt=0,terraintype,'Ksqt',WESTRING_TERRAINTYPE_Ksqt\nTerrainTypeKdkt=0,terraintype,'Kdkt',WESTRING_TERRAINTYPE_Kdkt\nTerrainTypeJdrt=0,terraintype,'Jdrt',WESTRING_TERRAINTYPE_Jdrt\nTerrainTypeJdtr=0,terraintype,'Jdtr',WESTRING_TERRAINTYPE_Jdtr\nTerrainTypeJblm=0,terraintype,'Jblm',WESTRING_TERRAINTYPE_Jblm\nTerrainTypeJbtl=0,terraintype,'Jbtl',WESTRING_TERRAINTYPE_Jbtl\nTerrainTypeJsqd=0,terraintype,'Jsqd',WESTRING_TERRAINTYPE_Jsqd\nTerrainTypeJrtl=0,terraintype,'Jrtl',WESTRING_TERRAINTYPE_Jrtl\nTerrainTypeJgsb=0,terraintype,'Jgsb',WESTRING_TERRAINTYPE_Jgsb\nTerrainTypeJhdg=0,terraintype,'Jhdg',WESTRING_TERRAINTYPE_Jhdg\nTerrainTypeJwmb=0,terraintype,'Jwmb',WESTRING_TERRAINTYPE_Jwmb\nTerrainTypecAc2=0,terraintype,'cAc2',WESTRING_TERRAINTYPE_cAc2\nTerrainTypecAc1=0,terraintype,'cAc1',WESTRING_TERRAINTYPE_cAc1\nTerrainTypecBc2=0,terraintype,'cBc2',WESTRING_TERRAINTYPE_cBc2\nTerrainTypecBc1=0,terraintype,'cBc1',WESTRING_TERRAINTYPE_cBc1\nTerrainTypecKc1=0,terraintype,'cKc1',WESTRING_TERRAINTYPE_cKc1\nTerrainTypecKc2=0,terraintype,'cKc2',WESTRING_TERRAINTYPE_cKc2\nTerrainTypecYc2=0,terraintype,'cYc2',WESTRING_TERRAINTYPE_cYc2\nTerrainTypecYc1=0,terraintype,'cYc1',WESTRING_TERRAINTYPE_cYc1\nTerrainTypecXc2=0,terraintype,'cXc2',WESTRING_TERRAINTYPE_cXc2\nTerrainTypecXc1=0,terraintype,'cXc1',WESTRING_TERRAINTYPE_cXc1\nTerrainTypecJc2=0,terraintype,'cJc2',WESTRING_TERRAINTYPE_cJc2\nTerrainTypecJc1=0,terraintype,'cJc1',WESTRING_TERRAINTYPE_cJc1\nTerrainTypecDc2=0,terraintype,'cDc2',WESTRING_TERRAINTYPE_cDc2\nTerrainTypecDc1=0,terraintype,'cDc1',WESTRING_TERRAINTYPE_cDc1\nTerrainTypecCc2=0,terraintype,'cCc2',WESTRING_TERRAINTYPE_cCc2\nTerrainTypecCc1=0,terraintype,'cCc1',WESTRING_TERRAINTYPE_cCc1\nTerrainTypecIc2=0,terraintype,'cIc2',WESTRING_TERRAINTYPE_cIc2\nTerrainTypecIc1=0,terraintype,'cIc1',WESTRING_TERRAINTYPE_cIc1\nTerrainTypecFc2=0,terraintype,'cFc2',WESTRING_TERRAINTYPE_cFc2\nTerrainTypecFc1=0,terraintype,'cFc1',WESTRING_TERRAINTYPE_cFc1\nTerrainTypecLc2=0,terraintype,'cLc2',WESTRING_TERRAINTYPE_cLc2\nTerrainTypecLc1=0,terraintype,'cLc1',WESTRING_TERRAINTYPE_cLc1\nTerrainTypecWc2=0,terraintype,'cWc2',WESTRING_TERRAINTYPE_cWc2\nTerrainTypecWc1=0,terraintype,'cWc1',WESTRING_TERRAINTYPE_cWc1\nTerrainTypecNc2=0,terraintype,'cNc2',WESTRING_TERRAINTYPE_cNc2\nTerrainTypecNc1=0,terraintype,'cNc1',WESTRING_TERRAINTYPE_cNc1\nTerrainTypecOc1=0,terraintype,'cOc1',WESTRING_TERRAINTYPE_cOc1\nTerrainTypecOc2=0,terraintype,'cOc2',WESTRING_TERRAINTYPE_cOc2\nTerrainTypecZc2=0,terraintype,'cZc2',WESTRING_TERRAINTYPE_cZc2\nTerrainTypecZc1=0,terraintype,'cZc1',WESTRING_TERRAINTYPE_cZc1\nTerrainTypecGc2=0,terraintype,'cGc2',WESTRING_TERRAINTYPE_cGc2\nTerrainTypecGc1=0,terraintype,'cGc1',WESTRING_TERRAINTYPE_cGc1\nTerrainTypecVc2=0,terraintype,'cVc2',WESTRING_TERRAINTYPE_cVc2\nTerrainTypecVc1=0,terraintype,'cVc1',WESTRING_TERRAINTYPE_cVc1\nTerrainTypecQc2=0,terraintype,'cQc2',WESTRING_TERRAINTYPE_cQc2\nTerrainTypecQc1=0,terraintype,'cQc1',WESTRING_TERRAINTYPE_cQc1\nTerrainShapeCircle=0,terrainshape,0,WESTRING_TERRAINSHAPE_CIRCLE\nTerrainShapeSquare=0,terrainshape,1,WESTRING_TERRAINSHAPE_SQUARE\nLightningTypeCLPB=0,lightningtype,`CLPB`,WESTRING_LIGHTNINGTYPE_CLPB\nLightningTypeCLSB=0,lightningtype,`CLSB`,WESTRING_LIGHTNINGTYPE_CLSB\nLightningTypeMBUR=0,lightningtype,`MBUR`,WESTRING_LIGHTNINGTYPE_MBUR\nLightningTypeCHIM=0,lightningtype,`CHIM`,WESTRING_LIGHTNINGTYPE_CHIM\nLightningTypeAFOD=0,lightningtype,`AFOD`,WESTRING_LIGHTNINGTYPE_AFOD\nLightningTypeHWPB=0,lightningtype,`HWPB`,WESTRING_LIGHTNINGTYPE_HWPB\nLightningTypeHWSB=0,lightningtype,`HWSB`,WESTRING_LIGHTNINGTYPE_HWSB\nLightningTypeMFPB=0,lightningtype,`MFPB`,WESTRING_LIGHTNINGTYPE_MFPB\nLightningTypeDRAB=0,lightningtype,`DRAB`,WESTRING_LIGHTNINGTYPE_DRAB\nLightningTypeDRAL=0,lightningtype,`DRAL`,WESTRING_LIGHTNINGTYPE_DRAL\nLightningTypeDRAM=0,lightningtype,`DRAM`,WESTRING_LIGHTNINGTYPE_DRAM\nLightningTypeFORK=0,lightningtype,`FORK`,WESTRING_LIGHTNINGTYPE_FORK\nLightningTypeSPLK=0,lightningtype,`SPLK`,WESTRING_LIGHTNINGTYPE_SPLK\nLightningTypeLEAS=0,lightningtype,`LEAS`,WESTRING_LIGHTNINGTYPE_LEAS\nImageTypeShadow=0,imagetype,0,WESTRING_IMAGETYPE_SHADOW\nImageTypeSelection=0,imagetype,1,WESTRING_IMAGETYPE_SELECTION\nImageTypeIndicator=0,imagetype,2,WESTRING_IMAGETYPE_INDICATOR\nImageTypeOcclusionMark=0,imagetype,3,WESTRING_IMAGETYPE_OCCLUSIONMARK\nImageTypeUbersplat=0,imagetype,4,WESTRING_IMAGETYPE_UBERSPLAT\nImageTypeLast=0,imagetype,5,WESTRING_IMAGETYPE_LAST\nUbersplatTypeTEST=0,ubersplattype,`TEST`,WESTRING_UBERSPLAT_TEST\nUbersplatTypeLSDS=0,ubersplattype,`LSDS`,WESTRING_UBERSPLAT_LSDS\nUbersplatTypeLSDM=0,ubersplattype,`LSDM`,WESTRING_UBERSPLAT_LSDM\nUbersplatTypeLSDL=0,ubersplattype,`LSDL`,WESTRING_UBERSPLAT_LSDL\nUbersplatTypeHCRT=0,ubersplattype,`HCRT`,WESTRING_UBERSPLAT_HCRT\nUbersplatTypeUDSU=0,ubersplattype,`UDSU`,WESTRING_UBERSPLAT_UDSU\nUbersplatTypeDNCS=0,ubersplattype,`DNCS`,WESTRING_UBERSPLAT_DNCS\nUbersplatTypeHMTP=0,ubersplattype,`HMTP`,WESTRING_UBERSPLAT_HMTP\nUbersplatTypeSCTP=0,ubersplattype,`SCTP`,WESTRING_UBERSPLAT_SCTP\nUbersplatTypeAMRC=0,ubersplattype,`AMRC`,WESTRING_UBERSPLAT_AMRC\nUbersplatTypeDRKC=0,ubersplattype,`DRKC`,WESTRING_UBERSPLAT_DRKC\nUbersplatTypeDOSB=0,ubersplattype,`DOSB`,WESTRING_UBERSPLAT_DOSB\nUbersplatTypeDOMB=0,ubersplattype,`DOMB`,WESTRING_UBERSPLAT_DOMB\nUbersplatTypeDOLB=0,ubersplattype,`DOLB`,WESTRING_UBERSPLAT_DOLB\nUbersplatTypeDHSB=0,ubersplattype,`DHSB`,WESTRING_UBERSPLAT_DHSB\nUbersplatTypeDHMB=0,ubersplattype,`DHMB`,WESTRING_UBERSPLAT_DHMB\nUbersplatTypeDHLB=0,ubersplattype,`DHLB`,WESTRING_UBERSPLAT_DHLB\nUbersplatTypeDUSB=0,ubersplattype,`DUSB`,WESTRING_UBERSPLAT_DUSB\nUbersplatTypeDUMB=0,ubersplattype,`DUMB`,WESTRING_UBERSPLAT_DUMB\nUbersplatTypeDULB=0,ubersplattype,`DULB`,WESTRING_UBERSPLAT_DULB\nUbersplatTypeDNSB=0,ubersplattype,`DNSB`,WESTRING_UBERSPLAT_DNSB\nUbersplatTypeDNMB=0,ubersplattype,`DNMB`,WESTRING_UBERSPLAT_DNMB\nUbersplatTypeDNSA=0,ubersplattype,`DNSA`,WESTRING_UBERSPLAT_DNSA\nUbersplatTypeDNMA=0,ubersplattype,`DNMA`,WESTRING_UBERSPLAT_DNMA\nUbersplatTypeHSMA=0,ubersplattype,`HSMA`,WESTRING_UBERSPLAT_HSMA\nUbersplatTypeHMED=0,ubersplattype,`HMED`,WESTRING_UBERSPLAT_HMED\nUbersplatTypeHLAR=0,ubersplattype,`HLAR`,WESTRING_UBERSPLAT_HLAR\nUbersplatTypeOSMA=0,ubersplattype,`OSMA`,WESTRING_UBERSPLAT_OSMA\nUbersplatTypeOMED=0,ubersplattype,`OMED`,WESTRING_UBERSPLAT_OMED\nUbersplatTypeOLAR=0,ubersplattype,`OLAR`,WESTRING_UBERSPLAT_OLAR\nUbersplatTypeUSMA=0,ubersplattype,`USMA`,WESTRING_UBERSPLAT_USMA\nUbersplatTypeUMED=0,ubersplattype,`UMED`,WESTRING_UBERSPLAT_UMED\nUbersplatTypeULAR=0,ubersplattype,`ULAR`,WESTRING_UBERSPLAT_ULAR\nUbersplatTypeESMA=0,ubersplattype,`ESMA`,WESTRING_UBERSPLAT_ESMA\nUbersplatTypeEMDA=0,ubersplattype,`EMDA`,WESTRING_UBERSPLAT_EMDA\nUbersplatTypeESMB=0,ubersplattype,`ESMB`,WESTRING_UBERSPLAT_ESMB\nUbersplatTypeEMDB=0,ubersplattype,`EMDB`,WESTRING_UBERSPLAT_EMDB\nUbersplatTypeHTOW=0,ubersplattype,`HTOW`,WESTRING_UBERSPLAT_HTOW\nUbersplatTypeHCAS=0,ubersplattype,`HCAS`,WESTRING_UBERSPLAT_HCAS\nUbersplatTypeNGOL=0,ubersplattype,`NGOL`,WESTRING_UBERSPLAT_NGOL\nUbersplatTypeTHND=0,ubersplattype,`THND`,WESTRING_UBERSPLAT_THND\nUbersplatTypeNDGS=0,ubersplattype,`NDGS`,WESTRING_UBERSPLAT_NDGS\nUbersplatTypeCLTS=0,ubersplattype,`CLTS`,WESTRING_UBERSPLAT_CLTS\nUbersplatTypeHFS1=0,ubersplattype,`HFS1`,WESTRING_UBERSPLAT_HFS1\nUbersplatTypeHFS2=0,ubersplattype,`HFS2`,WESTRING_UBERSPLAT_HFS2\nUbersplatTypeUSBR=0,ubersplattype,`USBR`,WESTRING_UBERSPLAT_USBR\nUbersplatTypeNLAR=0,ubersplattype,`NLAR`,WESTRING_UBERSPLAT_NLAR\nUbersplatTypeNMED=0,ubersplattype,`NMED`,WESTRING_UBERSPLAT_NMED\nUbersplatTypeDPSW=0,ubersplattype,`DPSW`,WESTRING_UBERSPLAT_DPSW\nUbersplatTypeDPSE=0,ubersplattype,`DPSE`,WESTRING_UBERSPLAT_DPSE\nUbersplatTypeNVOL=0,ubersplattype,`NVOL`,WESTRING_UBERSPLAT_NVOL\nUbersplatTypeNVCR=0,ubersplattype,`NVCR`,WESTRING_UBERSPLAT_NVCR\n[TriggerEvents]\nMapInitializationEvent=0,nothing\n_MapInitializationEvent_Defaults=\n_MapInitializationEvent_Category=TC_NOTHING\nTriggerRegisterDeathEvent=0,destructable\n_TriggerRegisterDeathEvent_Defaults=_\n_TriggerRegisterDeathEvent_Category=TC_DESTRUCT\nTriggerRegisterDestDeathInRegionEvent=1,rect\n_TriggerRegisterDestDeathInRegionEvent_Defaults=_\n_TriggerRegisterDestDeathInRegionEvent_Category=TC_DESTRUCT\nTriggerRegisterDialogEventBJ=0,dialog\n_TriggerRegisterDialogEventBJ_Defaults=_\n_TriggerRegisterDialogEventBJ_Category=TC_DIALOG\nTriggerRegisterGameStateEventTimeOfDay=0,limitop,real\n_TriggerRegisterGameStateEventTimeOfDay_Defaults=LimitOpEqual,12\n_TriggerRegisterGameStateEventTimeOfDay_Limits=_,_,0,24\n_TriggerRegisterGameStateEventTimeOfDay_Category=TC_GAME\nTriggerRegisterVariableEvent=0,VarAsString_Real,limitop,real\n_TriggerRegisterVariableEvent_Defaults=_,LimitOpEqual,0\n_TriggerRegisterVariableEvent_Category=TC_GAME\nTriggerRegisterGameLoadedEventBJ=1,nothing\n_TriggerRegisterGameLoadedEventBJ_Defaults=\n_TriggerRegisterGameLoadedEventBJ_Category=TC_GAME\nTriggerRegisterGameSavedEventBJ=1,nothing\n_TriggerRegisterGameSavedEventBJ_Defaults=\n_TriggerRegisterGameSavedEventBJ_Category=TC_GAME\nTriggerRegisterShowSkillEventBJ=0,nothing\n_TriggerRegisterShowSkillEventBJ_Defaults=\n_TriggerRegisterShowSkillEventBJ_Category=TC_GAME\nTriggerRegisterBuildSubmenuEventBJ=0,nothing\n_TriggerRegisterBuildSubmenuEventBJ_Defaults=\n_TriggerRegisterBuildSubmenuEventBJ_Category=TC_GAME\nTriggerRegisterGameEvent=1,gameevent\n_TriggerRegisterGameEvent_Defaults=GameEventTourneyNow\n_TriggerRegisterGameEvent_Category=TC_GAME\nTriggerRegisterGameStateEvent=0,igamestate,limitop,integer\n_TriggerRegisterGameStateEvent_Defaults=IGamestateDisconnected,LimitOpEqual,1\n_TriggerRegisterGameStateEvent_Category=TC_GAME\nTriggerRegisterPlayerChatEvent=0,player,string,chatmatchtype\n_TriggerRegisterPlayerChatEvent_Defaults=Player00,_,ChatMatchTypeExact\n_TriggerRegisterPlayerChatEvent_Category=TC_PLAYER\nTriggerRegisterPlayerEventEndCinematic=0,player\n_TriggerRegisterPlayerEventEndCinematic_Defaults=Player00\n_TriggerRegisterPlayerEventEndCinematic_Category=TC_PLAYER\nTriggerRegisterPlayerSelectionEventBJ=0,player,seldeseloption\n_TriggerRegisterPlayerSelectionEventBJ_Defaults=Player00,SelDeselOptionSel\n_TriggerRegisterPlayerSelectionEventBJ_Category=TC_PLAYER\nTriggerRegisterPlayerKeyEventBJ=1,player,keyeventtype,keyeventkey\n_TriggerRegisterPlayerKeyEventBJ_Defaults=Player00,KeyEventTypeDepress,KeyEventKeyLeft\n_TriggerRegisterPlayerKeyEventBJ_Category=TC_PLAYER\nTriggerRegisterPlayerStateEvent=0,player,playerstate,limitop,real\n_TriggerRegisterPlayerStateEvent_Defaults=Player00,PlayerStateGold,LimitOpGreaterThanOrEqual,1000\n_TriggerRegisterPlayerStateEvent_Category=TC_PLAYER\nTriggerRegisterPlayerEventAllianceChanged=0,player\n_TriggerRegisterPlayerEventAllianceChanged_Defaults=Player00\n_TriggerRegisterPlayerEventAllianceChanged_Category=TC_PLAYER\nTriggerRegisterPlayerAllianceChange=0,player,alliancetype\n_TriggerRegisterPlayerAllianceChange_Defaults=Player00,AllianceTypePassive\n_TriggerRegisterPlayerAllianceChange_Category=TC_PLAYER\nTriggerRegisterPlayerEventVictory=0,player\n_TriggerRegisterPlayerEventVictory_Defaults=Player00\n_TriggerRegisterPlayerEventVictory_Category=TC_PLAYER\nTriggerRegisterPlayerEventDefeat=0,player\n_TriggerRegisterPlayerEventDefeat_Defaults=Player00\n_TriggerRegisterPlayerEventDefeat_Category=TC_PLAYER\nTriggerRegisterPlayerEventLeave=1,player\n_TriggerRegisterPlayerEventLeave_Defaults=Player00\n_TriggerRegisterPlayerEventLeave_Category=TC_PLAYER\nTriggerRegisterPlayerEvent=0,player,playereventoption\n_TriggerRegisterPlayerEvent_Defaults=Player00,PlayerEventLeave\n_TriggerRegisterPlayerEvent_Category=TC_PLAYER\nTriggerRegisterTimerEventSingle=0,real\n_TriggerRegisterTimerEventSingle_Defaults=5\n_TriggerRegisterTimerEventSingle_Limits=0,_\n_TriggerRegisterTimerEventSingle_Category=TC_TIME\nTriggerRegisterTimerEventPeriodic=0,real\n_TriggerRegisterTimerEventPeriodic_Defaults=2\n_TriggerRegisterTimerEventPeriodic_Limits=0,_\n_TriggerRegisterTimerEventPeriodic_Category=TC_TIME\nTriggerRegisterTimerExpireEventBJ=0,timer\n_TriggerRegisterTimerExpireEventBJ_Defaults=_\n_TriggerRegisterTimerExpireEventBJ_Category=TC_TIME\nTriggerRegisterTrackableHitEvent=0,trackable\n_TriggerRegisterTrackableHitEvent_Defaults=_\n_TriggerRegisterTrackableHitEvent_Category=TC_TRACKABLE\nTriggerRegisterTrackableTrackEvent=0,trackable\n_TriggerRegisterTrackableTrackEvent_Defaults=_\n_TriggerRegisterTrackableTrackEvent_Category=TC_TRACKABLE\nTriggerRegisterUnitEvent=0,unit,unitevent\n_TriggerRegisterUnitEvent_Defaults=_,UnitEventDeath\n_TriggerRegisterUnitEvent_Category=TC_UNIT\nTriggerRegisterPlayerUnitEventSimple=0,player,playerunitevent\n_TriggerRegisterPlayerUnitEventSimple_Defaults=Player00,PlayerUnitEventDeath\n_TriggerRegisterPlayerUnitEventSimple_Category=TC_UNIT\nTriggerRegisterAnyUnitEventBJ=1,playerunitevent\n_TriggerRegisterAnyUnitEventBJ_Defaults=PlayerUnitEventDeath\n_TriggerRegisterAnyUnitEventBJ_Category=TC_UNIT\nTriggerRegisterEnterRectSimple=0,rect\n_TriggerRegisterEnterRectSimple_Defaults=_\n_TriggerRegisterEnterRectSimple_Category=TC_UNIT\nTriggerRegisterLeaveRectSimple=0,rect\n_TriggerRegisterLeaveRectSimple_Defaults=_\n_TriggerRegisterLeaveRectSimple_Category=TC_UNIT\nTriggerRegisterUnitInRangeSimple=0,real,unit\n_TriggerRegisterUnitInRangeSimple_Defaults=256,_\n_TriggerRegisterUnitInRangeSimple_Defaults=0,_,_,_\n_TriggerRegisterUnitInRangeSimple_Category=TC_UNIT\nTriggerRegisterUnitLifeEvent=0,unit,limitop,real\n_TriggerRegisterUnitLifeEvent_Defaults=_,LimitOpLessThan,50\n_TriggerRegisterUnitLifeEvent_Category=TC_UNIT\nTriggerRegisterUnitManaEvent=0,unit,limitop,real\n_TriggerRegisterUnitManaEvent_Defaults=_,LimitOpLessThan,50\n_TriggerRegisterUnitManaEvent_Category=TC_UNIT\nTriggerRegisterEnterRegionSimple=0,region\n_TriggerRegisterEnterRegionSimple_Defaults=_\n_TriggerRegisterEnterRegionSimple_Category=TC_UNIT\nTriggerRegisterLeaveRegionSimple=0,region\n_TriggerRegisterLeaveRegionSimple_Defaults=_\n_TriggerRegisterLeaveRegionSimple_Category=TC_UNIT\nTriggerRegisterEnterRegion=1,region,boolexpr\n_TriggerRegisterEnterRegion_Defaults=_,_\n_TriggerRegisterEnterRegion_Category=TC_UNIT\nTriggerRegisterLeaveRegion=1,region,boolexpr\n_TriggerRegisterLeaveRegion_Defaults=_,_\n_TriggerRegisterLeaveRegion_Category=TC_UNIT\nTriggerRegisterUnitStateEvent=0,unit,unitstate,limitop,real\n_TriggerRegisterUnitStateEvent_Defaults=_,UnitStateLife,LimitOpGreaterThanOrEqual,100\n_TriggerRegisterUnitStateEvent_Category=TC_UNIT\n[TriggerConditions]\nOperatorCompareBoolean=0,boolean,EqualNotEqualOperator,boolean\n_OperatorCompareBoolean_Defaults=IsUnitType,OperatorEqualENE,true\n_OperatorCompareBoolean_Category=TC_CONDITION\n_OperatorCompareBoolean_UseWithAI=1\n_OperatorCompareBoolean_AIDefaults=true,OperatorEqualENE,true\nOperatorCompareAbilityId=1,abilcode,EqualNotEqualOperator,abilcode\n_OperatorCompareAbilityId_Defaults=GetSpellAbilityId,OperatorEqualENE,AUan\n_OperatorCompareAbilityId_Category=TC_CONDITION\nOperatorCompareBuffId=1,buffcode,EqualNotEqualOperator,buffcode\n_OperatorCompareBuffId_Defaults=_,OperatorEqualENE,_\n_OperatorCompareBuffId_Category=TC_CONDITION\nOperatorCompareDestructible=0,destructable,EqualNotEqualOperator,destructable\n_OperatorCompareDestructible_Defaults=_,OperatorEqualENE,_\n_OperatorCompareDestructible_Category=TC_CONDITION\nOperatorCompareDestructableCode=0,destructablecode,EqualNotEqualOperator,destructablecode\n_OperatorCompareDestructableCode_Defaults=GetDestructableTypeId,OperatorEqualENE,LTlt\n_OperatorCompareDestructableCode_Category=TC_CONDITION\nOperatorCompareButton=0,button,EqualNotEqualOperator,button\n_OperatorCompareButton_Defaults=GetClickedButtonBJ,OperatorEqualENE,_\n_OperatorCompareButton_Category=TC_CONDITION\nOperatorCompareGameDifficulty=0,gamedifficulty,EqualNotEqualOperator,gamedifficulty\n_OperatorCompareGameDifficulty_Defaults=GetGameDifficulty,OperatorEqualENE,GameDifficultyNormal\n_OperatorCompareGameDifficulty_Category=TC_CONDITION\nOperatorCompareGameSpeed=0,gamespeed,EqualNotEqualOperator,gamespeed\n_OperatorCompareGameSpeed_Defaults=GetGameSpeed,OperatorEqualENE,GameSpeedNormal\n_OperatorCompareGameSpeed_Category=TC_CONDITION\nOperatorCompareGameState=0,gamestate,EqualNotEqualOperator,gamestate\n_OperatorCompareGameState_Defaults=GetEventGameState,OperatorEqualENE,GamestateDisconnected\n_OperatorCompareGameState_Category=TC_CONDITION\nOperatorCompareHeroSkill=0,heroskillcode,EqualNotEqualOperator,heroskillcode\n_OperatorCompareHeroSkill_Defaults=GetLearnedSkillBJ,OperatorEqualENE,HeroSkillBlizzard\n_OperatorCompareHeroSkill_Category=TC_CONDITION\nOperatorCompareInteger=0,integer,ComparisonOperator,integer\n_OperatorCompareInteger_Defaults=CountUnitsInGroup,OperatorEqual,0\n_OperatorCompareInteger_Category=TC_CONDITION\n_OperatorCompareInteger_UseWithAI=1\n_OperatorCompareInteger_AIDefaults=0,OperatorEqual,0\nOperatorCompareItem=0,item,EqualNotEqualOperator,item\n_OperatorCompareItem_Defaults=_,OperatorEqualENE,_\n_OperatorCompareItem_Category=TC_CONDITION\nOperatorCompareItemType=1,itemtype,EqualNotEqualOperator,itemtype\n_OperatorCompareItemType_Defaults=GetItemType,OperatorEqualENE,ItemTypePowerup\n_OperatorCompareItemType_Category=TC_CONDITION\nOperatorCompareItemCode=0,itemcode,EqualNotEqualOperator,itemcode\n_OperatorCompareItemCode_Defaults=GetItemTypeId,OperatorEqualENE,texp\n_OperatorCompareItemCode_Category=TC_CONDITION\nOperatorCompareMeleeDifficulty=1,aidifficulty,EqualNotEqualOperator,aidifficulty\n_OperatorCompareMeleeDifficulty_Defaults=GetAIDifficulty,OperatorEqualENE,AIDifficultyNormal\n_OperatorCompareMeleeDifficulty_Category=TC_CONDITION\nOperatorCompareOrderCode=0,ordercode,EqualNotEqualOperator,ordercode\n_OperatorCompareOrderCode_Defaults=GetIssuedOrderIdBJ,OperatorEqualENE,String2OrderIdBJ\n_OperatorCompareOrderCode_Category=TC_CONDITION\nOperatorComparePlayer=0,player,EqualNotEqualOperator,player\n_OperatorComparePlayer_Defaults=GetOwningPlayer,OperatorEqualENE,Player00\n_OperatorComparePlayer_Category=TC_CONDITION\nOperatorComparePlayerColor=0,playercolor,EqualNotEqualOperator,playercolor\n_OperatorComparePlayerColor_Defaults=GetPlayerColor,OperatorEqualENE,Color00\n_OperatorComparePlayerColor_Category=TC_CONDITION\nOperatorComparePlayerControl=0,mapcontrol,EqualNotEqualOperator,mapcontrol\n_OperatorComparePlayerControl_Defaults=GetPlayerController,OperatorEqualENE,MapControlUser\n_OperatorComparePlayerControl_Category=TC_CONDITION\nOperatorComparePlayerSlotStatus=0,playerslotstate,EqualNotEqualOperator,playerslotstate\n_OperatorComparePlayerSlotStatus_Defaults=GetPlayerSlotState,OperatorEqualENE,PlayerSlotStatePlaying\n_OperatorComparePlayerSlotStatus_Category=TC_CONDITION\nOperatorCompareRace=0,race,EqualNotEqualOperator,race\n_OperatorCompareRace_Defaults=GetPlayerRace,OperatorEqualENE,RaceHuman\n_OperatorCompareRace_Category=TC_CONDITION\nOperatorCompareReal=0,real,ComparisonOperator,real\n_OperatorCompareReal_Defaults=GetUnitStateSwap,OperatorGreaterEq,10\n_OperatorCompareReal_Category=TC_CONDITION\nOperatorCompareString=0,string,EqualNotEqualOperator,string\n_OperatorCompareString_Defaults=GetEventPlayerChatString,OperatorEqualENE,_\n_OperatorCompareString_Category=TC_CONDITION\nOperatorCompareTechCode=0,techcode,EqualNotEqualOperator,techcode\n_OperatorCompareTechCode_Defaults=GetResearched,OperatorEqualENE,_\n_OperatorCompareTechCode_Category=TC_CONDITION\nOperatorCompareTerrainType=1,terraintype,EqualNotEqualOperator,terraintype\n_OperatorCompareTerrainType_Defaults=GetTerrainTypeBJ,OperatorEqualENE,TerrainTypeLdrt\n_OperatorCompareTerrainType_Category=TC_CONDITION\nOperatorCompareTrigger=0,trigger,EqualNotEqualOperator,trigger\n_OperatorCompareTrigger_Defaults=_,OperatorEqualENE,_\n_OperatorCompareTrigger_Category=TC_CONDITION\nOperatorCompareUnit=0,unit,EqualNotEqualOperator,unit\n_OperatorCompareUnit_Defaults=GetTriggerUnit,OperatorEqualENE,_\n_OperatorCompareUnit_Category=TC_CONDITION\nOperatorCompareUnitCode=0,unitcode,EqualNotEqualOperator,unitcode\n_OperatorCompareUnitCode_Defaults=GetUnitTypeId,OperatorEqualENE,hfoo\n_OperatorCompareUnitCode_Category=TC_CONDITION\nOperatorCompareEventId=0,eventid,EqualNotEqualOperator,eventid\n_OperatorCompareEventId_Defaults=GetTriggerEventId,OperatorEqualENE,_\n_OperatorCompareEventId_Category=TC_CONDITION\nOperatorCompareTrackable=0,trackable,EqualNotEqualOperator,trackable\n_OperatorCompareTrackable_Defaults=GetTriggeringTrackable,OperatorEqualENE,_\n_OperatorCompareTrackable_Category=TC_CONDITION\nOperatorCompareUbersplat=0,ubersplat,EqualNotEqualOperator,ubersplat\n_OperatorCompareUbersplat_Defaults=GetLastCreatedUbersplat,OperatorEqualENE,_\n_OperatorCompareUbersplat_Category=TC_CONDITION\nOperatorCompareImage=0,image,EqualNotEqualOperator,image\n_OperatorCompareImage_Defaults=GetLastCreatedImage,OperatorEqualENE,_\n_OperatorCompareImage_Category=TC_CONDITION\nOperatorCompareLightning=0,lightning,EqualNotEqualOperator,lightning\n_OperatorCompareLightning_Defaults=GetLastCreatedLightningBJ,OperatorEqualENE,_\n_OperatorCompareLightning_Category=TC_CONDITION\nOperatorCompareTriggerAction=0,triggeraction,EqualNotEqualOperator,triggeraction\n_OperatorCompareTriggerAction_Defaults=_,OperatorEqualENE,_\n_OperatorCompareTriggerAction_Category=TC_CONDITION\nOperatorCompareTriggerCondition=0,triggercondition,EqualNotEqualOperator,triggercondition\n_OperatorCompareTriggerCondition_Defaults=_,OperatorEqualENE,_\n_OperatorCompareTriggerCondition_Category=TC_CONDITION\nOperatorComparePlayerState=0,playerstate,EqualNotEqualOperator,playerstate\n_OperatorComparePlayerState_Defaults=_,OperatorEqualENE,_\n_OperatorComparePlayerState_Category=TC_CONDITION\nOperatorCompareUnitState=0,unitstate,EqualNotEqualOperator,unitstate\n_OperatorCompareUnitState_Defaults=_,OperatorEqualENE,_\n_OperatorCompareUnitState_Category=TC_CONDITION\nOperatorCompareRegion=1,region,EqualNotEqualOperator,region\n_OperatorCompareRegion_Defaults=_,OperatorEqualENE,_\n_OperatorCompareRegion_Category=TC_CONDITION\nGetBooleanAnd=0,boolcall,boolcall\n_GetBooleanAnd_Defaults=_,_\n_GetBooleanAnd_Category=TC_CONDITION\n_GetBooleanAnd_UseWithAI=1\nGetBooleanOr=0,boolcall,boolcall\n_GetBooleanOr_Defaults=_,_\n_GetBooleanOr_Category=TC_CONDITION\n_GetBooleanOr_UseWithAI=1\nAndMultiple=1,nothing\n_AndMultiple_Category=TC_CONDITION\nOrMultiple=1,nothing\n_OrMultiple_Category=TC_CONDITION\n =1,scriptcode\n_ _Defaults=true\n_ _Category=TC_CONDITION\n[TriggerActions]\nDoNothing=0,nothing\n_DoNothing_Defaults=\n_DoNothing_Category=TC_NOTHING\nCommentString=0,scriptcode\n_CommentString_Defaults=_\n_CommentString_Category=TC_COMMENT\nCustomScriptCode=1,scriptcode\n_CustomScriptCode_Defaults=_\n_CustomScriptCode_Category=TC_CUSTOM\nExecuteFunc=0,string\n_ExecuteFunc_Defaults=DoNothing\n_ExecuteFunc_Category=TC_NOTHING\nTriggerSleepAction=0,real\n_TriggerSleepAction_Defaults=2\n_TriggerSleepAction_Limits=0,_\n_TriggerSleepAction_Category=TC_WAIT\nPolledWait=1,real\n_PolledWait_Defaults=2\n_PolledWait_Limits=0,_\n_PolledWait_Category=TC_WAIT\nWaitForCondition=1,boolexpr,real\n_WaitForCondition_Defaults=_,1\n_WaitForCondition_Limits=_,_,0.1,_\n_WaitForCondition_Category=TC_WAIT\nWaitForSoundBJ=0,sound,real\n_WaitForSoundBJ_Defaults=GetLastPlayedSound,0\n_WaitForSoundBJ_Category=TC_WAIT\nSetVariable=0,AnyGlobal,Null\n_SetVariable_Defaults=_,_\n_SetVariable_Category=TC_SETVARIABLE\nReturnAction=0,nothing\n_ReturnAction_Defaults=\n_ReturnAction_Category=TC_SKIPACTIONS\nIfThenElseMultiple=1,nothing\n_IfThenElseMultiple_Category=TC_LOGIC\nIfThenElse=0,boolexpr,code,code\n_IfThenElse_Defaults=_,DoNothing,DoNothing\n_IfThenElse_Category=TC_LOGIC\nForLoopAMultiple=1,integer,integer\n_ForLoopAMultiple_Defaults=1,10\n_ForLoopAMultiple_Category=TC_FORLOOP\nForLoopBMultiple=1,integer,integer\n_ForLoopBMultiple_Defaults=1,10\n_ForLoopBMultiple_Category=TC_FORLOOP\nForLoopVarMultiple=1,integervar,integer,integer\n_ForLoopVarMultiple_Defaults=_,1,10\n_ForLoopVarMultiple_Category=TC_FORLOOP\nForLoopA=0,integer,integer,code\n_ForLoopA_Defaults=1,10,DoNothing\n_ForLoopA_Category=TC_FORLOOP\nForLoopB=0,integer,integer,code\n_ForLoopB_Defaults=1,10,DoNothing\n_ForLoopB_Category=TC_FORLOOP\nForLoopVar=1,integervar,integer,integer,code\n_ForLoopVar_Defaults=_,1,10,DoNothing\n_ForLoopVar_Category=TC_FORLOOP\nStartMeleeAI=0,player,aiscript\n_StartMeleeAI_Defaults=Player00,\"map.ai\"\n_StartMeleeAI_Category=TC_AI\nStartCampaignAI=0,player,aiscript\n_StartCampaignAI_Defaults=Player00,\"map.ai\"\n_StartCampaignAI_Category=TC_AI\nCommandAI=0,player,integer,integer\n_CommandAI_Defaults=Player00,_,_\n_CommandAI_Category=TC_AI\nRemoveGuardPosition=0,unit\n_RemoveGuardPosition_Defaults=_\n_RemoveGuardPosition_Category=TC_AI\nRemoveAllGuardPositions=0,player\n_RemoveAllGuardPositions_Defaults=Player00\n_RemoveAllGuardPositions_Category=TC_AI\nRecycleGuardPosition=0,unit\n_RecycleGuardPosition_Defaults=_\n_RecycleGuardPosition_Category=TC_AI\nLockGuardPosition=1,unit\n_LockGuardPosition_Defaults=_\n_LockGuardPosition_Category=TC_AI\nSetUnitAnimation=0,unit,string\n_SetUnitAnimation_Defaults=_,\"stand\"\n_SetUnitAnimation_Category=TC_ANIMATION\nSetUnitAnimationWithRarity=0,unit,string,raritycontrol\n_SetUnitAnimationWithRarity_Defaults=_,\"stand\",RarityControlFrequent\n_SetUnitAnimationWithRarity_Category=TC_ANIMATION\nQueueUnitAnimationBJ=0,unit,string\n_QueueUnitAnimationBJ_Defaults=_,\"stand\"\n_QueueUnitAnimationBJ_Category=TC_ANIMATION\nResetUnitAnimation=0,unit\n_ResetUnitAnimation_Defaults=_\n_ResetUnitAnimation_Category=TC_ANIMATION\nAddUnitAnimationPropertiesBJ=0,addremoveoption,string,unit\n_AddUnitAnimationPropertiesBJ_Defaults=AddRemoveAdd,\"gold\",_\n_AddUnitAnimationPropertiesBJ_Category=TC_ANIMATION\nSetUnitLookAt=0,unit,unitfacingbone,unit,real,real,real\n_SetUnitLookAt_Defaults=_,UnitFacingBoneHead,_,0,0,90\n_SetUnitLookAt_Category=TC_ANIMATION\nResetUnitLookAt=0,unit\n_ResetUnitLookAt_Defaults=_\n_ResetUnitLookAt_Category=TC_ANIMATION\nSetUnitScalePercent=0,unit,real,real,real\n_SetUnitScalePercent_Defaults=_,100,100,100\n_SetUnitScalePercent_Limits=_,_,0,_,0,_,0,_\n_SetUnitScalePercent_Category=TC_ANIMATION\nSetUnitVertexColorBJ=0,unit,real,real,real,real\n_SetUnitVertexColorBJ_Defaults=_,100,100,100,0\n_SetUnitVertexColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_SetUnitVertexColorBJ_Category=TC_ANIMATION\nSetUnitTimeScalePercent=0,unit,real\n_SetUnitTimeScalePercent_Defaults=_,100\n_SetUnitTimeScalePercent_Limits=_,_,0,_\n_SetUnitTimeScalePercent_Category=TC_ANIMATION\nSetUnitTurnSpeedBJ=0,unit,real\n_SetUnitTurnSpeedBJ_Defaults=GetTriggerUnit,0.5\n_SetUnitTurnSpeedBJ_Limits=_,_,0,1\n_SetUnitTurnSpeedBJ_Category=TC_ANIMATION\nSetUnitBlendTimeBJ=0,unit,real\n_SetUnitBlendTimeBJ_Defaults=GetTriggerUnit,_\n_SetUnitBlendTimeBJ_Category=TC_ANIMATION\nSetUnitFlyHeightBJ=0,unit,real,real\n_SetUnitFlyHeightBJ_Defaults=GetTriggerUnit,_,_\n_SetUnitFlyHeightBJ_Category=TC_ANIMATION\nSetUnitPropWindowBJ=0,unit,real\n_SetUnitPropWindowBJ_Defaults=GetTriggerUnit,_\n_SetUnitPropWindowBJ_Category=TC_ANIMATION\nSetDestructableAnimationBJ=0,destructable,string\n_SetDestructableAnimationBJ_Defaults=_,\"stand\"\n_SetDestructableAnimationBJ_Category=TC_ANIMATION\nQueueDestructableAnimationBJ=0,destructable,string\n_QueueDestructableAnimationBJ_Defaults=_,\"stand\"\n_QueueDestructableAnimationBJ_Category=TC_ANIMATION\nSetDestAnimationSpeedPercent=1,destructable,real\n_SetDestAnimationSpeedPercent_Defaults=_,100\n_SetDestAnimationSpeedPercent_Category=TC_ANIMATION\nSetDoodadAnimationRectBJ=0,string,doodadcode,rect\n_SetDoodadAnimationRectBJ_Defaults=\"death\",_,GetPlayableMapRect\n_SetDoodadAnimationRectBJ_Category=TC_ANIMATION\nSetDoodadAnimationBJ=0,string,doodadcode,real,location\n_SetDoodadAnimationBJ_Defaults=\"death\",_,128,GetRectCenter\n_SetDoodadAnimationBJ_Category=TC_ANIMATION\nSetUnitAnimationByIndex=1,unit,integer\n_SetUnitAnimationByIndex_Defaults=GetTriggerUnit,1\n_SetUnitAnimationByIndex_Category=TC_ANIMATION\nCameraSetupApplyForPlayer=0,cameraapplyoption,camerasetup,player,real\n_CameraSetupApplyForPlayer_Defaults=CameraApply,_,Player00,0\n_CameraSetupApplyForPlayer_Limits=_,_,_,_,_,_,0,_\n_CameraSetupApplyForPlayer_Category=TC_CAMERA\nPanCameraToTimedLocForPlayer=0,player,location,real\n_PanCameraToTimedLocForPlayer_Defaults=Player00,GetRectCenter,0\n_PanCameraToTimedLocForPlayer_Limits=_,_,_,_,0,_\n_PanCameraToTimedLocForPlayer_Category=TC_CAMERA\nPanCameraToTimedLocWithZForPlayer=0,player,location,real,real\n_PanCameraToTimedLocWithZForPlayer_Defaults=Player00,GetRectCenter,0,0\n_PanCameraToTimedLocWithZForPlayer_Limits=_,_,_,_,_,_,0,_\n_PanCameraToTimedLocWithZForPlayer_Category=TC_CAMERA\nSmartCameraPanBJ=0,player,location,real\n_SmartCameraPanBJ_Defaults=Player00,GetRectCenter,0.5\n_SmartCameraPanBJ_Limits=_,_,_,_,0,_\n_SmartCameraPanBJ_Category=TC_CAMERA\nSetCameraFieldForPlayer=0,player,camerafield,real,real\n_SetCameraFieldForPlayer_Defaults=Player00,CameraFieldTargetDistance,CameraSetupGetFieldSwap,0\n_SetCameraFieldForPlayer_Limits=_,_,_,_,_,_,0,_\n_SetCameraFieldForPlayer_Category=TC_CAMERA\nRotateCameraAroundLocBJ=1,real,location,player,real\n_RotateCameraAroundLocBJ_Defaults=90,GetRectCenter,Player00,2\n_RotateCameraAroundLocBJ_Limits=_,_,_,_,_,_,0,_\n_RotateCameraAroundLocBJ_Category=TC_CAMERA\nSetCameraTargetControllerNoZForPlayer=0,player,unit,real,real,cameraorientationoption\n_SetCameraTargetControllerNoZForPlayer_Defaults=Player00,GetTriggerUnit,0,0,CameraOrientationNormal\n_SetCameraTargetControllerNoZForPlayer_Category=TC_CAMERA\nSetCameraOrientControllerForPlayerBJ=0,player,unit,real,real\n_SetCameraOrientControllerForPlayerBJ_Defaults=Player00,GetTriggerUnit,0,0\n_SetCameraOrientControllerForPlayerBJ_Category=TC_CAMERA\nSetCinematicCameraForPlayer=0,player,modelfile\n_SetCinematicCameraForPlayer_Defaults=Player00,\"cinematic.mdl\"\n_SetCinematicCameraForPlayer_Category=TC_CAMERA\nStopCameraForPlayerBJ=0,player\n_StopCameraForPlayerBJ_Defaults=Player00\n_StopCameraForPlayerBJ_Category=TC_CAMERA\nResetToGameCameraForPlayer=0,player,real\n_ResetToGameCameraForPlayer_Defaults=Player00,0\n_ResetToGameCameraForPlayer_Limits=_,_,0,_\n_ResetToGameCameraForPlayer_Category=TC_CAMERA\nCameraSetSmoothingFactorBJ=0,real\n_CameraSetSmoothingFactorBJ_Defaults=1\n_CameraSetSmoothingFactorBJ_Limits=0,_\n_CameraSetSmoothingFactorBJ_Category=TC_CAMERA\nCameraResetSmoothingFactorBJ=0,nothing\n_CameraResetSmoothingFactorBJ_Defaults=\n_CameraResetSmoothingFactorBJ_Category=TC_CAMERA\nCameraSetSourceNoiseForPlayer=0,player,real,real\n_CameraSetSourceNoiseForPlayer_Defaults=Player00,10,0.1\n_CameraSetSourceNoiseForPlayer_Category=TC_CAMERA\nCameraSetTargetNoiseForPlayer=0,player,real,real\n_CameraSetTargetNoiseForPlayer_Defaults=Player00,10,0.1\n_CameraSetTargetNoiseForPlayer_Category=TC_CAMERA\nCameraSetEQNoiseForPlayer=1,player,real\n_CameraSetEQNoiseForPlayer_Defaults=Player00,3\n_CameraSetEQNoiseForPlayer_Limits=_,_,0,_\n_CameraSetEQNoiseForPlayer_Category=TC_CAMERA\nCameraClearNoiseForPlayer=0,player\n_CameraClearNoiseForPlayer_Defaults=Player00\n_CameraClearNoiseForPlayer_Category=TC_CAMERA\nAdjustCameraBoundsForPlayerBJ=0,cameraboundsadjusttype,player,real,real,real,real\n_AdjustCameraBoundsForPlayerBJ_Defaults=CameraBoundsAdjustAdd,Player00,0,0,0,0\n_AdjustCameraBoundsForPlayerBJ_Category=TC_CAMERA\nSetCameraBoundsToRectForPlayerBJ=0,player,rect\n_SetCameraBoundsToRectForPlayerBJ_Defaults=Player00,_\n_SetCameraBoundsToRectForPlayerBJ_Category=TC_CAMERA\nSetCameraQuickPositionLocForPlayer=0,player,location\n_SetCameraQuickPositionLocForPlayer_Defaults=Player00,GetRectCenter\n_SetCameraQuickPositionLocForPlayer_Category=TC_CAMERA\nTransmissionFromUnitWithNameBJ=0,force,unit,StringExt,sound,StringExt,addsettooption,real,waitdontoption\n_TransmissionFromUnitWithNameBJ_Defaults=GetPlayersAll,_,_,SoundNull,_,AddSetToAdd,0,WaitDontWait\n_TransmissionFromUnitWithNameBJ_Category=TC_CINEMATIC\nTransmissionFromUnitTypeWithNameBJ=0,force,player,unitcode,StringExt,location,sound,StringExt,addsettooption,real,waitdontoption\n_TransmissionFromUnitTypeWithNameBJ_Defaults=GetPlayersAll,Player00,hfoo,_,GetRectCenter,SoundNull,_,AddSetToAdd,0,WaitDontWait\n_TransmissionFromUnitTypeWithNameBJ_Category=TC_CINEMATIC\nForceCinematicSubtitlesBJ=1,onoffoption\n_ForceCinematicSubtitlesBJ_Defaults=OnOffOn\n_ForceCinematicSubtitlesBJ_Category=TC_CINEMATIC\nCinematicModeBJ=0,onoffoption,force\n_CinematicModeBJ_Defaults=OnOffOn,GetPlayersAll\n_CinematicModeBJ_Category=TC_CINEMATIC\nCinematicModeExBJ=1,onoffoption,force,real\n_CinematicModeExBJ_Defaults=OnOffOn,GetPlayersAll,0.2\n_CinematicModeExBJ_Category=TC_CINEMATIC\nCinematicFadeBJ=0,fadetypeoption,real,cinefiltertexture,real,real,real,real\n_CinematicFadeBJ_Defaults=FadeTypeOptionFadeOutIn,2,CineFilterTextureWhite,0,0,0,0\n_CinematicFadeBJ_Limits=_,_,0,_,_,_,0,100,0,100,0,100,0,100\n_CinematicFadeBJ_Category=TC_CINEMATIC\nCinematicFilterGenericBJ=0,real,blendmode,cinefiltertexture,real,real,real,real,real,real,real,real\n_CinematicFilterGenericBJ_Defaults=2,BlendModeBlend,CineFilterTextureWhite,100,100,100,100,0,0,0,0\n_CinematicFilterGenericBJ_Limits=0,_,_,_,_,_,0,100,0,100,0,100,0,100,0,100,0,100,0,100,0,100\n_CinematicFilterGenericBJ_Category=TC_CINEMATIC\nDisplayCineFilterBJ=0,showhideoption\n_DisplayCineFilterBJ_Defaults=ShowHideHide\n_DisplayCineFilterBJ_Category=TC_CINEMATIC\nPingMinimapLocForForce=0,force,location,real\n_PingMinimapLocForForce_Defaults=GetPlayersAll,GetRectCenter,1\n_PingMinimapLocForForce_Limits=_,_,_,_,0,_\n_PingMinimapLocForForce_Category=TC_CINEMATIC\nPingMinimapLocForForceEx=1,force,location,real,minimappingstyle,real,real,real\n_PingMinimapLocForForceEx_Defaults=GetPlayersAll,GetRectCenter,1,MinimapPingStyleSimple,100,100,100\n_PingMinimapLocForForceEx_Limits=_,_,_,_,0,_,_,_,0,100,0,100,0,100\n_PingMinimapLocForForceEx_Category=TC_CINEMATIC\nUnitAddIndicatorBJ=0,unit,real,real,real,real\n_UnitAddIndicatorBJ_Defaults=_,100,100,100,0\n_UnitAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_UnitAddIndicatorBJ_Category=TC_CINEMATIC\nDestructableAddIndicatorBJ=0,destructable,real,real,real,real\n_DestructableAddIndicatorBJ_Defaults=_,100,100,100,0\n_DestructableAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_DestructableAddIndicatorBJ_Category=TC_CINEMATIC\nItemAddIndicatorBJ=0,item,real,real,real,real\n_ItemAddIndicatorBJ_Defaults=_,100,100,100,0\n_ItemAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_ItemAddIndicatorBJ_Category=TC_CINEMATIC\nClearTextMessagesBJ=0,force\n_ClearTextMessagesBJ_Defaults=GetPlayersAll\n_ClearTextMessagesBJ_Category=TC_CINEMATIC\nShowInterfaceForceOff=0,force,real\n_ShowInterfaceForceOff_Defaults=GetPlayersAll,2\n_ShowInterfaceForceOff_Limits=_,_,0,_\n_ShowInterfaceForceOff_Category=TC_CINEMATIC\nShowInterfaceForceOn=0,force,real\n_ShowInterfaceForceOn_Defaults=GetPlayersAll,2\n_ShowInterfaceForceOn_Limits=_,_,0,_\n_ShowInterfaceForceOn_Category=TC_CINEMATIC\nSetUserControlForceOff=0,force\n_SetUserControlForceOff_Defaults=GetPlayersAll\n_SetUserControlForceOff_Category=TC_CINEMATIC\nSetUserControlForceOn=0,force\n_SetUserControlForceOn_Defaults=GetPlayersAll\n_SetUserControlForceOn_Category=TC_CINEMATIC\nEnableOcclusionBJ=0,enabledisableoption,force\n_EnableOcclusionBJ_Defaults=EnableDisableDisable,GetPlayersAll\n_EnableOcclusionBJ_Category=TC_CINEMATIC\nEnableWorldFogBoundaryBJ=0,enabledisableoption,force\n_EnableWorldFogBoundaryBJ_Defaults=EnableDisableDisable,GetPlayersAll\n_EnableWorldFogBoundaryBJ_Category=TC_CINEMATIC\nPlayCinematic=1,string\n_PlayCinematic_Defaults=\"HumanEd\"\n_PlayCinematic_Category=TC_CINEMATIC\nStartTimerBJ=0,timer,periodicoption,real\n_StartTimerBJ_Defaults=_,PeriodicOptionOneTime,30\n_StartTimerBJ_Limits=_,_,_,_,0,_\n_StartTimerBJ_Category=TC_TIMER\nPauseTimerBJ=0,pauseresumeoption,timer\n_PauseTimerBJ_Defaults=PauseResumePause,GetLastCreatedTimerBJ\n_PauseTimerBJ_Category=TC_TIMER\nCreateTimerDialogBJ=0,timer,StringExt\n_CreateTimerDialogBJ_Defaults=GetLastCreatedTimerBJ,_\n_CreateTimerDialogBJ_Category=TC_TIMER\nDestroyTimerDialogBJ=0,timerdialog\n_DestroyTimerDialogBJ_Defaults=GetLastCreatedTimerDialogBJ\n_DestroyTimerDialogBJ_Category=TC_TIMER\nTimerDialogDisplayForPlayerBJ=1,showhideoption,timerdialog,player\n_TimerDialogDisplayForPlayerBJ_Defaults=ShowHideHide,GetLastCreatedTimerDialogBJ,Player00\n_TimerDialogDisplayForPlayerBJ_Category=TC_TIMER\nTimerDialogDisplayBJ=0,showhideoption,timerdialog\n_TimerDialogDisplayBJ_Defaults=ShowHideHide,GetLastCreatedTimerDialogBJ\n_TimerDialogDisplayBJ_Category=TC_TIMER\nTimerDialogSetTitleBJ=0,timerdialog,StringExt\n_TimerDialogSetTitleBJ_Defaults=GetLastCreatedTimerDialogBJ,_\n_TimerDialogSetTitleBJ_Category=TC_TIMER\nTimerDialogSetTitleColorBJ=0,timerdialog,real,real,real,real\n_TimerDialogSetTitleColorBJ_Defaults=GetLastCreatedTimerDialogBJ,100,80,20,0\n_TimerDialogSetTitleColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_TimerDialogSetTitleColorBJ_Category=TC_TIMER\nTimerDialogSetTimeColorBJ=0,timerdialog,real,real,real,real\n_TimerDialogSetTimeColorBJ_Defaults=GetLastCreatedTimerDialogBJ,100,80,20,0\n_TimerDialogSetTimeColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_TimerDialogSetTimeColorBJ_Category=TC_TIMER\nCreateDestructableLoc=0,destructablecode,location,real,real,integer\n_CreateDestructableLoc_Defaults=LTlt,GetRectCenter,GetRandomDirectionDeg,1,0\n_CreateDestructableLoc_Limits=_,_,_,_,_,_,0,_,0,_\n_CreateDestructableLoc_Category=TC_DESTRUCT\nCreateDeadDestructableLocBJ=0,destructablecode,location,real,real,integer\n_CreateDeadDestructableLocBJ_Defaults=LTlt,GetRectCenter,GetRandomDirectionDeg,1,0\n_CreateDeadDestructableLocBJ_Limits=_,_,_,_,_,_,0,_,0,_\n_CreateDeadDestructableLocBJ_Category=TC_DESTRUCT\nKillDestructable=0,destructable\n_KillDestructable_Defaults=GetLastCreatedDestructable\n_KillDestructable_Category=TC_DESTRUCT\nRemoveDestructable=0,destructable\n_RemoveDestructable_Defaults=GetLastCreatedDestructable\n_RemoveDestructable_Category=TC_DESTRUCT\nDestructableRestoreLife=0,destructable,real,showhideoption\n_DestructableRestoreLife_Defaults=GetLastCreatedDestructable,GetDestructableMaxLife,ShowHideShow\n_DestructableRestoreLife_Category=TC_DESTRUCT\nShowDestructableBJ=1,showhideoption,destructable\n_ShowDestructableBJ_Defaults=ShowHideHide,GetLastCreatedDestructable\n_ShowDestructableBJ_Category=TC_DESTRUCT\nSetDestructableLifePercentBJ=0,destructable,real\n_SetDestructableLifePercentBJ_Defaults=GetLastCreatedDestructable,100\n_SetDestructableLifePercentBJ_Limits=_,_,0,100\n_SetDestructableLifePercentBJ_Category=TC_DESTRUCT\nSetDestructableLife=0,destructable,real\n_SetDestructableLife_Defaults=GetLastCreatedDestructable,GetDestructableMaxLife\n_SetDestructableLife_Limits=_,_,0,_\n_SetDestructableLife_Category=TC_DESTRUCT\nSetDestructableMaxLifeBJ=0,destructable,real\n_SetDestructableMaxLifeBJ_Defaults=GetLastCreatedDestructable,100\n_SetDestructableMaxLifeBJ_Limits=_,_,0,_\n_SetDestructableMaxLifeBJ_Category=TC_DESTRUCT\nModifyGateBJ=0,gateoperation,destructable\n_ModifyGateBJ_Defaults=GateOperationOpen,_\n_ModifyGateBJ_Category=TC_DESTRUCT\nChangeElevatorWalls=1,elevatorwallop,elevatorwalltype,destructable\n_ChangeElevatorWalls_Defaults=ElevatorWallOpClose,ElevatorWallTypeAll,_\n_ChangeElevatorWalls_Category=TC_DESTRUCT\nChangeElevatorHeight=1,destructable,integer\n_ChangeElevatorHeight_Defaults=_,1\n_ChangeElevatorHeight_Limits=_,_,1,3\n_ChangeElevatorHeight_Category=TC_DESTRUCT\nSetDestructableInvulnerableBJ=0,destructable,invulnerableoption\n_SetDestructableInvulnerableBJ_Defaults=GetLastCreatedDestructable,InvulnerabilityInvulnerable\n_SetDestructableInvulnerableBJ_Category=TC_DESTRUCT\nSetDestructableOccluderHeight=1,destructable,real\n_SetDestructableOccluderHeight_Defaults=_,128\n_SetDestructableOccluderHeight_Category=TC_DESTRUCT\nEnumDestructablesInRectAllMultiple=1,rect\n_EnumDestructablesInRectAllMultiple_Defaults=GetPlayableMapRect\n_EnumDestructablesInRectAllMultiple_Category=TC_DESTRUCT\n_EnumDestructablesInRectAllMultiple_ScriptName=EnumDestructablesInRectAll\nEnumDestructablesInCircleBJMultiple=1,real,location\n_EnumDestructablesInCircleBJMultiple_Defaults=256,GetRectCenter\n_EnumDestructablesInCircleBJMultiple_Category=TC_DESTRUCT\n_EnumDestructablesInCircleBJMultiple_ScriptName=EnumDestructablesInCircleBJ\nEnumDestructablesInRectAll=0,rect,code\n_EnumDestructablesInRectAll_Defaults=GetPlayableMapRect,DoNothing\n_EnumDestructablesInRectAll_Category=TC_DESTRUCT\nEnumDestructablesInCircleBJ=0,real,location,code\n_EnumDestructablesInCircleBJ_Defaults=256,GetRectCenter,DoNothing\n_EnumDestructablesInCircleBJ_Category=TC_DESTRUCT\nDialogDisplayBJ=0,showhideoption,dialog,player\n_DialogDisplayBJ_Defaults=ShowHideShow,_,Player00\n_DialogDisplayBJ_Category=TC_DIALOG\nDialogSetMessageBJ=0,dialog,StringExt\n_DialogSetMessageBJ_Defaults=_,_\n_DialogSetMessageBJ_Category=TC_DIALOG\nDialogAddButtonBJ=0,dialog,StringExt\n_DialogAddButtonBJ_Defaults=_,_\n_DialogAddButtonBJ_Category=TC_DIALOG\nDialogAddButton=0,dialog,string,integer\n_DialogAddButton_Defaults=_,_,65\n_DialogAddButton_Category=TC_DIALOG\nDialogClearBJ=0,dialog\n_DialogClearBJ_Defaults=_\n_DialogClearBJ_Category=TC_DIALOG\nDialogAddQuitButton=1,dialog,showhideoption,string,integer\n_DialogAddQuitButton_Defaults=_,ShowHideHide,_,_\n_DialogAddQuitButton_Category=TC_DIALOG\nAddWeatherEffectSaveLast=0,rect,weathereffectcode\n_AddWeatherEffectSaveLast_Defaults=GetPlayableMapRect,WeatherAshenvaleHeavyRain\n_AddWeatherEffectSaveLast_Category=TC_ENVIRONMENT\nEnableWeatherEffect=0,weathereffect,onoffoption\n_EnableWeatherEffect_Defaults=GetLastCreatedWeatherEffect,OnOffOn\n_EnableWeatherEffect_Category=TC_ENVIRONMENT\nRemoveWeatherEffectBJ=0,weathereffect\n_RemoveWeatherEffectBJ_Defaults=GetLastCreatedWeatherEffect\n_RemoveWeatherEffectBJ_Category=TC_ENVIRONMENT\nTerrainDeformationCraterBJ=1,real,cratertype,location,real,real\n_TerrainDeformationCraterBJ_Defaults=0.5,CraterTypeTemporary,GetRectCenter,512,64\n_TerrainDeformationCraterBJ_Limits=0.01,_,_,_,_,_,1,_,_,_\n_TerrainDeformationCraterBJ_Category=TC_ENVIRONMENT\nTerrainDeformationRippleBJ=1,real,rippletype,location,real,real,real,real,real\n_TerrainDeformationRippleBJ_Defaults=4,RippleTypeNormal,GetRectCenter,1024,1024,64,1,512\n_TerrainDeformationRippleBJ_Limits=0.01,_,_,_,_,_,0,_,1,_,_,_,0.01,_,1,_\n_TerrainDeformationRippleBJ_Category=TC_ENVIRONMENT\nTerrainDeformationWaveBJ=1,real,location,location,real,real,real\n_TerrainDeformationWaveBJ_Defaults=0.5,GetRectCenter,GetRectCenter,256,96,0\n_TerrainDeformationWaveBJ_Limits=0.01,_,_,_,_,_,0,_,_,_,0,_\n_TerrainDeformationWaveBJ_Category=TC_ENVIRONMENT\nTerrainDeformationRandomBJ=1,real,location,real,real,real,real\n_TerrainDeformationRandomBJ_Defaults=4,GetRectCenter,512,-32,32,0.1\n_TerrainDeformationRandomBJ_Limits=0.01,_,_,_,0,_,_,_,_,_,0.01,_\n_TerrainDeformationRandomBJ_Category=TC_ENVIRONMENT\nTerrainDeformationStopBJ=1,terraindeformation,real\n_TerrainDeformationStopBJ_Defaults=GetLastCreatedTerrainDeformation,0\n_TerrainDeformationStopBJ_Limits=_,_,0,_\n_TerrainDeformationStopBJ_Category=TC_ENVIRONMENT\nTerrainDeformStopAll=1,nothing\n_TerrainDeformStopAll_Defaults=\n_TerrainDeformStopAll_Category=TC_ENVIRONMENT\nSetWaterDeforms=1,onoffoption\n_SetWaterDeforms_Defaults=OnOffOn\n_SetWaterDeforms_Category=TC_ENVIRONMENT\nSetTerrainTypeBJ=1,location,terraintype,integer,integer,terrainshape\n_SetTerrainTypeBJ_Defaults=GetRectCenter,TerrainTypeLdrt,-1,1,TerrainShapeCircle\n_SetTerrainTypeBJ_Category=TC_ENVIRONMENT\nSetTerrainPathableBJ=1,location,pathingtype,onoffoption\n_SetTerrainPathableBJ_Defaults=GetRectCenter,PathingTypeWalkability,OnOffOn\n_SetTerrainPathableBJ_Category=TC_ENVIRONMENT\nSetWaterBaseColorBJ=1,real,real,real,real\n_SetWaterBaseColorBJ_Defaults=100,100,100,0\n_SetWaterBaseColorBJ_Limits=0,100,0,100,0,100,0,100\n_SetWaterBaseColorBJ_Category=TC_ENVIRONMENT\nSetSkyModel=0,skymodelstring\n_SetSkyModel_Defaults=SkyModelNone\n_SetSkyModel_Category=TC_ENVIRONMENT\nSetTerrainFogExBJ=0,fogstyle,real,real,real,real,real,real\n_SetTerrainFogExBJ_Defaults=FogStyleLinear,1000,8000,0,100,100,100\n_SetTerrainFogExBJ_Limits=_,_,0,_,0,_,0,_,0,100,0,100,0,100\n_SetTerrainFogExBJ_Category=TC_ENVIRONMENT\nResetTerrainFogBJ=0,nothing\n_ResetTerrainFogBJ_Defaults=\n_ResetTerrainFogBJ_Category=TC_ENVIRONMENT\nSetBlightRectBJ=0,createremoveoption,player,rect\n_SetBlightRectBJ_Defaults=CreateRemoveCreate,Player00,GetPlayableMapRect\n_SetBlightRectBJ_Category=TC_ENVIRONMENT\nSetBlightRadiusLocBJ=0,createremoveoption,player,location,real\n_SetBlightRadiusLocBJ_Defaults=CreateRemoveCreate,Player00,GetRectCenter,512\n_SetBlightRadiusLocBJ_Limits=_,_,_,_,_,_,0,_\n_SetBlightRadiusLocBJ_Category=TC_ENVIRONMENT\nCreateImageBJ=1,string,real,location,real,imagetype\n_CreateImageBJ_Defaults=_,1,GetRectCenter,0,ImageTypeIndicator\n_CreateImageBJ_Category=TC_IMAGE\nDestroyImage=1,image\n_DestroyImage_Defaults=GetLastCreatedImage\n_DestroyImage_Category=TC_IMAGE\nShowImageBJ=1,showhideoption,image\n_ShowImageBJ_Defaults=ShowHideShow,GetLastCreatedImage\n_ShowImageBJ_Category=TC_IMAGE\nSetImageConstantHeight=1,image,enabledisableoption,real\n_SetImageConstantHeight_Defaults=GetLastCreatedImage,EnableDisableEnable,0\n_SetImageConstantHeight_Category=TC_IMAGE\nSetImagePositionBJ=1,image,location,real\n_SetImagePositionBJ_Defaults=GetLastCreatedImage,GetRectCenter,0\n_SetImagePositionBJ_Category=TC_IMAGE\nSetImageColorBJ=1,image,real,real,real,real\n_SetImageColorBJ_Defaults=GetLastCreatedImage,100,100,100,0\n_SetImageColorBJ_Category=TC_IMAGE\nSetImageRender=1,image,enabledisableoption\n_SetImageRender_Defaults=GetLastCreatedImage,EnableDisableEnable\n_SetImageRender_Category=TC_IMAGE\nSetImageRenderAlways=1,image,enabledisableoption\n_SetImageRenderAlways_Defaults=GetLastCreatedImage,EnableDisableEnable\n_SetImageRenderAlways_Category=TC_IMAGE\nSetImageAboveWater=1,image,enabledisableoption,enabledisableoption\n_SetImageAboveWater_Defaults=GetLastCreatedImage,EnableDisableEnable,EnableDisableEnable\n_SetImageAboveWater_Category=TC_IMAGE\nSetImageType=1,image,imagetype\n_SetImageType_Defaults=GetLastCreatedImage,ImageTypeIndicator\n_SetImageType_Category=TC_IMAGE\nCreateUbersplatBJ=1,location,ubersplattype,real,real,real,real,enabledisableoption,enabledisableoption\n_CreateUberSplatBJ_Defaults=GetRectCenter,UbersplatTypeTEST,100,100,100,0,EnableDisableDisable,EnableDisableDisable\n_CreateUberSplatBJ_Category=TC_UBERSPLAT\nDestroyUbersplat=1,ubersplat\n_DestroyUbersplat_Defaults=GetLastCreatedUbersplat\n_DestroyUbersplat_Category=TC_UBERSPLAT\nResetUbersplat=1,ubersplat\n_ResetUbersplat_Defaults=GetLastCreatedUbersplat\n_ResetUbersplat_Category=TC_UBERSPLAT\nFinishUbersplat=1,ubersplat\n_FinishUbersplat_Defaults=GetLastCreatedUbersplat\n_FinishUbersplat_Category=TC_UBERSPLAT\nShowUbersplatBJ=1,showhideoption,ubersplat\n_ShowUbersplatBJ_Defaults=ShowHideShow,GetLastCreatedUbersplat\n_ShowUbersplatBJ_Category=TC_UBERSPLAT\nSetUbersplatRender=1,ubersplat,enabledisableoption\n_SetUbersplatRender_Defaults=GetLastCreatedUbersplat,EnableDisableEnable\n_SetUbersplatRender_Category=TC_UBERSPLAT\nSetUbersplatRenderAlways=1,ubersplat,enabledisableoption\n_SetUbersplatRenderAlways_Defaults=GetLastCreatedUbersplat,EnableDisableEnable\n_SetUbersplatRenderAlways_Category=TC_UBERSPLAT\nCreateTextTagLocBJ=1,StringExt,location,real,real,real,real,real,real\n_CreateTextTagLocBJ_Defaults=_,GetRectCenter,0,10,100,100,100,0\n_CreateTextTagLocBJ_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100\n_CreateTextTagLocBJ_Category=TC_TEXTTAG\nCreateTextTagUnitBJ=1,StringExt,unit,real,real,real,real,real,real\n_CreateTextTagUnitBJ_Defaults=_,_,0,10,100,100,100,0\n_CreateTextTagUnitBJ_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100\n_CreateTextTagUnitBJ_Category=TC_TEXTTAG\nDestroyTextTagBJ=1,texttag\n_DestroyTextTagBJ_Defaults=GetLastCreatedTextTag\n_DestroyTextTagBJ_Category=TC_TEXTTAG\nShowTextTagForceBJ=1,showhideoption,texttag,force\n_ShowTextTagForceBJ_Defaults=ShowHideShow,GetLastCreatedTextTag,GetPlayersAll\n_ShowTextTagForceBJ_Category=TC_TEXTTAG\nSetTextTagVelocityBJ=1,texttag,real,real\n_SetTextTagVelocityBJ_Defaults=GetLastCreatedTextTag,64,90\n_SetTextTagVelocityBJ_Category=TC_TEXTTAG\nSetTextTagColorBJ=1,texttag,real,real,real,real\n_SetTextTagColorBJ_Defaults=GetLastCreatedTextTag,100,100,100,0\n_SetTextTagColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_SetTextTagColorBJ_Category=TC_TEXTTAG\nSetTextTagPosBJ=1,texttag,location,real\n_SetTextTagPosBJ_Defaults=GetLastCreatedTextTag,GetRectCenter,0\n_SetTextTagPosBJ_Category=TC_TEXTTAG\nSetTextTagPosUnitBJ=1,texttag,unit,real\n_SetTextTagPosUnitBJ_Defaults=GetLastCreatedTextTag,_,0\n_SetTextTagPosUnitBJ_Category=TC_TEXTTAG\nSetTextTagTextBJ=1,texttag,StringExt,real\n_SetTextTagTextBJ_Defaults=GetLastCreatedTextTag,_,10\n_SetTextTagTextBJ_Category=TC_TEXTTAG\nSetTextTagSuspendedBJ=1,texttag,enabledisableoption\n_SetTextTagSuspendedBJ_Defaults=GetLastCreatedTextTag,EnableDisableEnable\n_SetTextTagSuspendedBJ_Category=TC_TEXTTAG\nSetTextTagPermanentBJ=1,texttag,enabledisableoption\n_SetTextTagPermanentBJ_Defaults=GetLastCreatedTextTag,EnableDisableEnable\n_SetTextTagPermanentBJ_Category=TC_TEXTTAG\nSetTextTagAgeBJ=1,texttag,real\n_SetTextTagAgeBJ_Defaults=GetLastCreatedTextTag,0\n_SetTextTagAgeBJ_Category=TC_TEXTTAG\nSetTextTagLifespanBJ=1,texttag,real\n_SetTextTagLifespanBJ_Defaults=GetLastCreatedTextTag,5\n_SetTextTagLifespanBJ_Category=TC_TEXTTAG\nSetTextTagFadepointBJ=1,texttag,real\n_SetTextTagFadepointBJ_Defaults=GetLastCreatedTextTag,4\n_SetTextTagFadepointBJ_Category=TC_TEXTTAG\nDisplayTextToForce=0,force,StringExt\n_DisplayTextToForce_Defaults=GetPlayersAll,_\n_DisplayTextToForce_Category=TC_GAME\nDisplayTextToPlayer=0,player,real,real,StringExt\n_DisplayTextToPlayer_Defaults=Player00,0,0,_\n_DisplayTextToPlayer_Category=TC_GAME\nDisplayTimedTextToForce=0,force,real,StringExt\n_DisplayTimedTextToForce_Defaults=GetPlayersAll,30,_\n_DisplayTimedTextToForce_Limits=_,_,0,_,_,_\n_DisplayTimedTextToForce_Category=TC_GAME\nDisplayTimedTextToPlayer=0,player,real,real,real,StringExt\n_DisplayTimedTextToPlayer_Defaults=Player00,0,0,30,_\n_DisplayTimedTextToPlayer_Limits=_,_,_,_,_,_,0,_,_,_\n_DisplayTimedTextToPlayer_Category=TC_GAME\nPauseGameOn=0,nothing\n_PauseGameOn_Defaults=\n_PauseGameOn_Category=TC_GAME\nPauseGameOff=0,nothing\n_PauseGameOff_Defaults=\n_PauseGameOff_Category=TC_GAME\nSetGameSpeed=0,gamespeed\n_SetGameSpeed_Defaults=GameSpeedNormal\n_SetGameSpeed_Category=TC_GAME\nLockGameSpeedBJ=0,nothing\n_LockGameSpeedBJ_Defaults=\n_LockGameSpeedBJ_Category=TC_GAME\nUnlockGameSpeedBJ=0,nothing\n_UnlockGameSpeedBJ_Defaults=\n_UnlockGameSpeedBJ_Category=TC_GAME\nSetMapFlag=0,mapflag,onoffoption\n_SetMapFlag_Defaults=MapFlagUseHandicaps,OnOffOn\n_SetMapFlag_Category=TC_GAME\nSetTimeOfDay=0,real\n_SetTimeOfDay_Defaults=12\n_SetTimeOfDay_Limits=0,24\n_SetTimeOfDay_Category=TC_GAME\nSetTimeOfDayScalePercentBJ=0,real\n_SetTimeOfDayScalePercentBJ_Defaults=100\n_SetTimeOfDayScalePercentBJ_Defaults=0,_\n_SetTimeOfDayScalePercentBJ_Category=TC_GAME\nUseTimeOfDayBJ=0,onoffoption\n_UseTimeOfDayBJ_Defaults=OnOffOff\n_UseTimeOfDayBJ_Category=TC_GAME\nShareEverythingWithTeam=0,player\n_ShareEverythingWithTeam_Defaults=Player00\n_ShareEverythingWithTeam_Category=TC_GAME\nMakeUnitsPassiveForPlayer=0,player\n_MakeUnitsPassiveForPlayer_Defaults=Player00\n_MakeUnitsPassiveForPlayer_Category=TC_GAME\nSetNextLevelBJ=0,string\n_SetNextLevelBJ_Defaults=\"Maps\\MapName.w3m\"\n_SetNextLevelBJ_Category=TC_GAME\nCustomVictoryBJ=0,player,useskipoption,useskipoption\n_CustomVictoryBJ_Defaults=Player00,UseSkipOptionUse,UseSkipOptionUse\n_CustomVictoryBJ_Category=TC_GAME\nCustomDefeatBJ=0,player,StringExt\n_CustomDefeatBJ_Defaults=Player00,WESTRING_PEVENT_DEFEAT_MSG\n_CustomDefeatBJ_Category=TC_GAME\nLoadGameBJ=1,anyfile,useskipoption\n_LoadGameBJ_Defaults=\"LoadFile.w3z\",UseSkipOptionSkip\n_LoadGameBJ_Category=TC_GAME\nSaveAndLoadGameBJ=1,anyfile,anyfile,useskipoption\n_SaveAndLoadGameBJ_Defaults=\"SaveFile.w3z\",\"LoadFile.w3z\",UseSkipOptionSkip\n_SaveAndLoadGameBJ_Category=TC_GAME\nSaveAndChangeLevelBJ=1,anyfile,anyfile,useskipoption\n_SaveAndChangeLevelBJ_Defaults=\"SaveFile.w3z\",\"Maps\\MapName.w3x\",UseSkipOptionSkip\n_SaveAndChangeLevelBJ_Category=TC_GAME\nRenameSaveDirectoryBJ=1,anyfile,anyfile\n_RenameSaveDirectoryBJ_Defaults=_,_\n_RenameSaveDirectoryBJ_Category=TC_GAME\nRemoveSaveDirectoryBJ=1,anyfile\n_RemoveSaveDirectoryBJ_Defaults=_\n_RemoveSaveDirectoryBJ_Category=TC_GAME\nCopySaveGameBJ=1,anyfile,anyfile\n_CopySaveGameBJ_Defaults=_,_\n_CopySaveGameBJ_Category=TC_GAME\nSetCampaignMenuRaceBJ=0,campaignindex\n_SetCampaignMenuRaceBJ_Defaults=CampaignIndexH\n_SetCampaignMenuRaceBJ_Category=TC_GAME\nSetMissionAvailableBJ=0,enabledisableoption,missionindex\n_SetMissionAvailableBJ_Defaults=EnableDisableEnable,MissionIndexH01\n_SetMissionAvailableBJ_Category=TC_GAME\nSetCampaignAvailableBJ=0,enabledisableoption,campaignindex\n_SetCampaignAvailableBJ_Defaults=EnableDisableEnable,CampaignIndexH\n_SetCampaignAvailableBJ_Category=TC_GAME\nSetCinematicAvailableBJ=0,enabledisableoption,cinematicindex\n_SetCinematicAvailableBJ_Defaults=EnableDisableEnable,CinematicIndexHED\n_SetCinematicAvailableBJ_Category=TC_GAME\nShowCustomCampaignButton=1,showhideoption,integer\n_ShowCustomCampaignButton_Defaults=ShowHideShow,1\n_ShowCustomCampaignButton_Limits=_,_,1,_\n_ShowCustomCampaignButton_Category=TC_GAME\nSetAllyColorFilterState=1,integer\n_SetAllyColorFilterState_Defaults=0\n_SetAllyColorFilterState_Limits=0,2\n_SetAllyColorFilterState_Category=TC_GAME\nSetCreepCampFilterState=1,showhideoption\n_SetCreepCampFilterState_Defaults=ShowHideHide\n_SetCreepCampFilterState_Category=TC_GAME\nEnableMinimapFilterButtons=1,enabledisableoption,enabledisableoption\n_EnableMinimapFilterButtons_Defaults=EnableDisableDisable,EnableDisableDisable\n_EnableMinimapFilterButtons_Category=TC_GAME\nEnableDragSelect=0,enabledisableoption,enabledisableoption\n_EnableDragSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnableDragSelect_Category=TC_GAME\nEnablePreSelect=0,enabledisableoption,enabledisableoption\n_EnablePreSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnablePreSelect_Category=TC_GAME\nEnableSelect=0,enabledisableoption,enabledisableoption\n_EnableSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnableSelect_Category=TC_GAME\nForceUIKeyBJ=0,player,string\n_ForceUIKeyBJ_Defaults=Player00,\"A\"\n_ForceUIKeyBJ_Category=TC_GAME\nForceUICancelBJ=0,player\n_ForceUICancelBJ_Defaults=Player00\n_ForceUICancelBJ_Category=TC_GAME\nPreload=0,anyfile\n_Preload_Defaults=_\n_Preload_Category=TC_GAME\nPreloadEnd=0,real\n_PreloadEnd_Defaults=0.5\n_PreloadEnd_Category=TC_GAME\nPreloader=0,preloadfile\n_Preloader_Defaults=\n_Preloader_Category=TC_GAME\nEndGame=1,useskipoption\n_EndGame_Defaults=UseSkipOptionSkip\n_EndGame_Category=TC_GAME\nChangeLevel=1,string,useskipoption\n_ChangeLevel_Defaults=\"Maps\\MyMap.w3m\",UseSkipOptionSkip\n_ChangeLevel_Category=TC_GAME\nRestartGame=1,useskipoption\n_RestartGame_Defaults=UseSkipOptionSkip\n_RestartGame_Category=TC_GAME\nDisableRestartMission=1,boolean\n_DisableRestartMission_Defaults=true\n_DisableRestartMission_Category=TC_GAME\nDoNotSaveReplay=1,nothing\n_DoNotSaveReplay_Defaults=\n_DoNotSaveReplay_Category=TC_GAME\nEnableUserUI=0,enabledisableoption\n_EnableUserUI_Defaults=EnableDisableEnable\n_EnableUserUI_Category=TC_GAME\nSetIntegerGameState=0,igamestate,integer\n_SetIntegerGameState_Defaults=IGamestateDivineIntervention,1\n_SetIntegerGameState_Category=TC_GAME\nInitGameCacheBJ=0,string\n_InitGameCacheBJ_Defaults=\"MapName.w3v\"\n_InitGameCacheBJ_Category=TC_GAMECACHE\nSaveGameCacheBJ=0,gamecache\n_SaveGameCacheBJ_Defaults=GetLastCreatedGameCacheBJ\n_SaveGameCacheBJ_Category=TC_GAMECACHE\nStoreUnitBJ=0,unit,string,string,gamecache\n_StoreUnitBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreUnitBJ_Category=TC_GAMECACHE\nStoreRealBJ=0,real,string,string,gamecache\n_StoreRealBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreRealBJ_Category=TC_GAMECACHE\nStoreIntegerBJ=0,integer,string,string,gamecache\n_StoreIntegerBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreIntegerBJ_Category=TC_GAMECACHE\nStoreBooleanBJ=0,boolean,string,string,gamecache\n_StoreBooleanBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreBooleanBJ_Category=TC_GAMECACHE\nStoreStringBJ=1,string,string,string,gamecache\n_StoreStringBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreStringBJ_Category=TC_GAMECACHE\nRestoreUnitLocFacingAngleBJ=0,string,string,gamecache,player,location,real\n_RestoreUnitLocFacingAngleBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ,Player00,GetRectCenter,0\n_RestoreUnitLocFacingAngleBJ_Category=TC_GAMECACHE\nRestoreUnitLocFacingPointBJ=0,string,string,gamecache,player,location,location\n_RestoreUnitLocFacingPointBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ,Player00,GetRectCenter,GetUnitLoc\n_RestoreUnitLocFacingPointBJ_Category=TC_GAMECACHE\nReloadGameCachesFromDisk=1,nothing\n_ReloadGameCachesFromDisk_Defaults=\n_ReloadGameCachesFromDisk_Category=TC_GAMECACHE\nFlushGameCacheBJ=1,gamecache\n_FlushGameCacheBJ_Defaults=GetLastCreatedGameCacheBJ\n_FlushGameCacheBJ_Category=TC_GAMECACHE\nFlushStoredMissionBJ=1,string,gamecache\n_FlushStoredMissionBJ_Defaults=\"Category\",GetLastCreatedGameCacheBJ\n_FlushStoredMissionBJ_Category=TC_GAMECACHE\nFlushStoredInteger=1,gamecache,string,string\n_FlushStoredInteger_Defaults=_,_,_\n_FlushStoredInteger_Category=TC_GAMECACHE\nFlushStoredBoolean=1,gamecache,string,string\n_FlushStoredBoolean_Defaults=_,_,_\n_FlushStoredBoolean_Category=TC_GAMECACHE\nFlushStoredReal=1,gamecache,string,string\n_FlushStoredReal_Defaults=_,_,_\n_FlushStoredReal_Category=TC_GAMECACHE\nFlushStoredUnit=1,gamecache,string,string\n_FlushStoredUnit_Defaults=_,_,_\n_FlushStoredUnit_Category=TC_GAMECACHE\nFlushStoredString=1,gamecache,string,string\n_FlushStoredString_Defaults=_,_,_\n_FlushStoredString_Category=TC_GAMECACHE\nSelectHeroSkill=0,unit,heroskillcode\n_SelectHeroSkill_Defaults=GetTriggerUnit,HeroSkillBlizzard\n_SelectHeroSkill_Category=TC_HERO\nSelectHeroSkill2=0,unit,abilcode\n_SelectHeroSkill2_Defaults=GetTriggerUnit,_\n_SelectHeroSkill2_ScriptName=SelectHeroSkill\n_SelectHeroSkill2_Category=TC_HERO\nSetHeroLevel=0,unit,integer,showhideoption\n_SetHeroLevel_Defaults=GetTriggerUnit,2,ShowHideHide\n_SetHeroLevel_Limits=_,_,1,_,_,_\n_SetHeroLevel_Category=TC_HERO\n_SetHeroLevel_ScriptName=SetHeroLevelBJ\nSetHeroXP=0,unit,integer,showhideoption\n_SetHeroXP_Defaults=GetTriggerUnit,4000,ShowHideHide\n_SetHeroXP_Limits=_,_,0,_,_,_\n_SetHeroXP_Category=TC_HERO\nAddHeroXPSwapped=0,integer,unit,showhideoption\n_AddHeroXPSwapped_Defaults=1000,GetTriggerUnit,ShowHideHide\n_AddHeroXPSwapped_Category=TC_HERO\nSuspendHeroXPBJ=0,enabledisableoption,unit\n_SuspendHeroXPBJ_Defaults=EnableDisableDisable,GetTriggerUnit\n_SuspendHeroXPBJ_Category=TC_HERO\nSetPlayerHandicapXPBJ=0,player,real\n_SetPlayerHandicapXPBJ_Defaults=Player00,100\n_SetPlayerHandicapXPBJ_Limits=_,_,0,_\n_SetPlayerHandicapXPBJ_Category=TC_HERO\nReviveHeroLoc=0,unit,location,showhideoption\n_ReviveHeroLoc_Defaults=_,GetRectCenter,ShowHideHide\n_ReviveHeroLoc_Category=TC_HERO\nModifyHeroStat=1,herostat,unit,modifymethod,integer\n_ModifyHeroStat_Defaults=HeroStatStr,_,ModifyMethodAdd,10\n_ModifyHeroStat_Category=TC_HERO\nSetHeroAgi=0,unit,integer,permanentoption\n_SetHeroAgi_Defaults=GetTriggerUnit,0,PermanentPerm\n_SetHeroAgi_Category=TC_HERO\nSetHeroInt=0,unit,integer,permanentoption\n_SetHeroInt_Defaults=GetTriggerUnit,0,PermanentPerm\n_SetHeroInt_Category=TC_HERO\nSetHeroStr=0,unit,integer,permanentoption\n_SetHeroStr_Defaults=GetTriggerUnit,0,PermanentPerm\n_SetHeroStr_Category=TC_HERO\nModifyHeroSkillPoints=1,unit,modifymethod,integer\n_ModifyHeroSkillPoints_Defaults=_,ModifyMethodAdd,1\n_ModifyHeroSkillPoints_Category=TC_HERO\nSetReservedLocalHeroButtons=1,integer\n_SetReservedLocalHeroButtons_Defaults=3\n_SetReservedLocalHeroButtons_Limits=0,6\n_SetReservedLocalHeroButtons_Category=TC_HERO\nUnitAddItemSwapped=0,item,unit\n_UnitAddItemSwapped_Defaults=GetLastCreatedItem,GetTriggerUnit\n_UnitAddItemSwapped_Category=TC_HERO\nUnitAddItemByIdSwapped=0,itemcode,unit\n_UnitAddItemByIdSwapped_Defaults=texp,GetTriggerUnit\n_UnitAddItemByIdSwapped_Category=TC_HERO\nUnitRemoveItemSwapped=0,item,unit\n_UnitRemoveItemSwapped_Defaults=_,_\n_UnitRemoveItemSwapped_Category=TC_HERO\nUnitRemoveItemFromSlotSwapped=0,integer,unit\n_UnitRemoveItemFromSlotSwapped_Defaults=1,_\n_UnitRemoveItemFromSlotSwapped_Limits=1,6,_,_\n_UnitRemoveItemFromSlotSwapped_Category=TC_HERO\nUnitUseItemTarget=0,unit,item,unit\n_UnitUseItemTarget_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemTarget_Category=TC_HERO\nUnitUseItemPointLoc=0,unit,item,location\n_UnitUseItemPointLoc_Defaults=_,GetLastCreatedItem,GetRectCenter\n_UnitUseItemPointLoc_Category=TC_HERO\nUnitUseItemDestructable=0,unit,item,destructable\n_UnitUseItemDestructable_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemDestructable_Category=TC_HERO\nUnitUseItem=0,unit,item\n_UnitUseItem_Defaults=_,GetLastCreatedItem\n_UnitUseItem_Category=TC_HERO\nIssueInstantTargetOrder=1,unit,unitorderinstant,unit,item\n_IssueInstantTargetOrder_Defaults=GetTriggerUnit,InstantOrderGive,GetLastCreatedUnit,UnitItemInSlotBJ\n_IssueInstantTargetOrder_Category=TC_HERO\nCreateItemLoc=0,itemcode,location\n_CreateItemLoc_Defaults=texp,GetRectCenter\n_CreateItemLoc_Category=TC_ITEM\nRemoveItem=0,item\n_RemoveItem_Defaults=GetLastCreatedItem\n_RemoveItem_Category=TC_ITEM\nSetItemVisibleBJ=1,showhideoption,item\n_SetItemVisibleBJ_Defaults=ShowHideHide,GetLastCreatedItem\n_SetItemVisibleBJ_Category=TC_ITEM\nSetItemPositionLoc=0,item,location\n_SetItemPositionLoc_Defaults=GetLastCreatedItem,GetRectCenter\n_SetItemPositionLoc_Category=TC_ITEM\nSetItemLifeBJ=0,item,real\n_SetItemLifeBJ_Defaults=GetLastCreatedItem,50\n_SetItemLifeBJ_Limits=_,_,0,_\n_SetItemLifeBJ_Category=TC_ITEM\nSetItemCharges=1,item,integer\n_SetItemCharges_Defaults=GetLastCreatedItem,1\n_SetItemCharges_Limits=_,_,0,_\n_SetItemCharges_Category=TC_ITEM\nSetItemInvulnerableBJ=0,item,invulnerableoption\n_SetItemInvulnerableBJ_Defaults=GetLastCreatedItem,InvulnerabilityInvulnerable\n_SetItemInvulnerableBJ_Category=TC_ITEM\nSetItemPawnable=1,item,pawnableoption\n_SetItemPawnable_Defaults=GetLastCreatedItem,PawnableOptionPawnable\n_SetItemPawnable_Category=TC_ITEM\nSetItemDroppableBJ=0,item,dropnodropoption\n_SetItemDroppableBJ_Defaults=GetLastCreatedItem,DropNoDropOptionNoDrop\n_SetItemDroppableBJ_Category=TC_ITEM\nSetItemDropOnDeathBJ=0,item,droppableoption\n_SetItemDropOnDeathBJ_Defaults=GetLastCreatedItem,DroppableOptionDrop\n_SetItemDropOnDeathBJ_Category=TC_ITEM\nSetItemPlayerBJ=0,item,player,colorchangeoption\n_SetItemPlayerBJ_Defaults=GetLastCreatedItem,Player00,ChangeColorTrue\n_SetItemPlayerBJ_Category=TC_ITEM\nSetItemUserData=1,item,integer\n_SetItemUserData_Defaults=_,0\n_SetItemUserData_Category=TC_ITEM\nEnumItemsInRectBJMultiple=1,rect\n_EnumItemsInRectBJMultiple_Defaults=GetPlayableMapRect\n_EnumItemsInRectBJMultiple_Category=TC_ITEM\n_EnumItemsInRectBJMultiple_ScriptName=EnumItemsInRectBJ\nEnumItemsInRectBJ=1,rect,code\n_EnumItemsInRectBJ_Defaults=GetPlayableMapRect,DoNothing\n_EnumItemsInRectBJ_Category=TC_ITEM\nRandomDistAddItem=1,integer,integer\n_RandomDistAddItem_Defaults=_,_\n_RandomDistAddItem_Category=TC_ITEM\nRandomDistReset=1,nothing\n_RandomDistReset_Defaults=\n_RandomDistReset_Category=TC_ITEM\nCreateLeaderboardBJ=0,force,StringExt\n_CreateLeaderboardBJ_Defaults=GetPlayersAll,_\n_CreateLeaderboardBJ_Category=TC_LEADERBOARD\nDestroyLeaderboardBJ=0,leaderboard\n_DestroyLeaderboardBJ_Defaults=GetLastCreatedLeaderboard\n_DestroyLeaderboardBJ_Category=TC_LEADERBOARD\nLeaderboardSortItemsBJ=0,leaderboard,leaderboardsortoption,ascendingoption\n_LeaderboardSortItemsBJ_Defaults=GetLastCreatedLeaderboard,LeaderboardSortByValue,AscendingOptionDescending\n_LeaderboardSortItemsBJ_Category=TC_LEADERBOARD\nLeaderboardDisplayBJ=0,showhideoption,leaderboard\n_LeaderboardDisplayBJ_Defaults=ShowHideHide,GetLastCreatedLeaderboard\n_LeaderboardDisplayBJ_Category=TC_LEADERBOARD\nLeaderboardSetLabelBJ=0,leaderboard,StringExt\n_LeaderboardSetLabelBJ_Defaults=GetLastCreatedLeaderboard,_\n_LeaderboardSetLabelBJ_Category=TC_LEADERBOARD\nLeaderboardSetLabelColorBJ=0,leaderboard,real,real,real,real\n_LeaderboardSetLabelColorBJ_Defaults=GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetLabelColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetLabelColorBJ_Category=TC_LEADERBOARD\nLeaderboardSetValueColorBJ=0,leaderboard,real,real,real,real\n_LeaderboardSetValueColorBJ_Defaults=GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetValueColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetValueColorBJ_Category=TC_LEADERBOARD\nLeaderboardSetStyleBJ=0,leaderboard,showhideoption,showhideoption,showhideoption,showhideoption\n_LeaderboardSetStyleBJ_Defaults=GetLastCreatedLeaderboard,ShowHideShow,ShowHideShow,ShowHideShow,ShowHideShow\n_LeaderboardSetStyleBJ_Category=TC_LEADERBOARD\nLeaderboardAddItemBJ=0,player,leaderboard,StringExt,integer\n_LeaderboardAddItemBJ_Defaults=Player00,GetLastCreatedLeaderboard,_,0\n_LeaderboardAddItemBJ_Category=TC_LEADERBOARD\nLeaderboardRemovePlayerItemBJ=0,player,leaderboard\n_LeaderboardRemovePlayerItemBJ_Defaults=Player00,GetLastCreatedLeaderboard\n_LeaderboardRemovePlayerItemBJ_Category=TC_LEADERBOARD\nLeaderboardSetPlayerItemLabelBJ=0,player,leaderboard,StringExt\n_LeaderboardSetPlayerItemLabelBJ_Defaults=Player00,GetLastCreatedLeaderboard,_\n_LeaderboardSetPlayerItemLabelBJ_Category=TC_LEADERBOARD\nLeaderboardSetPlayerItemLabelColorBJ=0,player,leaderboard,real,real,real,real\n_LeaderboardSetPlayerItemLabelColorBJ_Defaults=Player00,GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetPlayerItemLabelColorBJ_Limits=_,_,_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetPlayerItemLabelColorBJ_Category=TC_LEADERBOARD\nLeaderboardSetPlayerItemValueBJ=0,player,leaderboard,integer\n_LeaderboardSetPlayerItemValueBJ_Defaults=Player00,GetLastCreatedLeaderboard,0\n_LeaderboardSetPlayerItemValueBJ_Category=TC_LEADERBOARD\nLeaderboardSetPlayerItemValueColorBJ=0,player,leaderboard,real,real,real,real\n_LeaderboardSetPlayerItemValueColorBJ_Defaults=Player00,GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetPlayerItemValueColorBJ_Limits=_,_,_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetPlayerItemValueColorBJ_Category=TC_LEADERBOARD\nLeaderboardSetPlayerItemStyleBJ=0,player,leaderboard,showhideoption,showhideoption,showhideoption\n_LeaderboardSetPlayerItemStyleBJ_Defaults=Player00,GetLastCreatedLeaderboard,ShowHideShow,ShowHideShow,ShowHideShow\n_LeaderboardSetPlayerItemStyleBJ_Category=TC_LEADERBOARD\nMoveLocation=0,location,real,real\n_MoveLocation_Defaults=_,GetLocationX,GetLocationY\n_MoveLocation_Category=TC_LOCATION\nRemoveLocation=0,location\n_RemoveLocation_Default=_\n_RemoveLocation_Category=TC_LOCATION\nMeleeStartingVisibility=0,nothing\n_MeleeStartingVisibility_Defaults=\n_MeleeStartingVisibility_Category=TC_MELEE\nMeleeStartingHeroLimit=0,nothing\n_MeleeStartingHeroLimit_Defaults=\n_MeleeStartingHeroLimit_Category=TC_MELEE\nMeleeGrantHeroItems=0,nothing\n_MeleeGrantHeroItems_Defaults=\n_MeleeGrantHeroItems_Category=TC_MELEE\nMeleeStartingResources=0,nothing\n_MeleeStartingResources_Defaults=\n_MeleeStartingResources_Category=TC_MELEE\nMeleeClearExcessUnits=0,nothing\n_MeleeClearExcessUnits_Defaults=\n_MeleeClearExcessUnits_Category=TC_MELEE\nMeleeStartingUnits=0,nothing\n_MeleeStartingUnits_Defaults=\n_MeleeStartingUnits_Category=TC_MELEE\nMeleeStartingAI=0,nothing\n_MeleeStartingAI_Defaults=\n_MeleeStartingAI_Category=TC_MELEE\nMeleeInitVictoryDefeat=0,nothing\n_MeleeInitVictoryDefeat_Defaults=\n_MeleeInitVictoryDefeat_Category=TC_MELEE\nMeleeStartingUnitsForPlayer=1,race,player,location,includeoption\n_MeleeStartingUnitsForPlayer_Defaults=RaceHuman,Player00,GetPlayerStartLocationLoc,InclusionInclude\n_MeleeStartingUnitsForPlayer_Category=TC_MELEE\nCreateMultiboardBJ=1,integer,integer,StringExt\n_CreateMultiboardBJ_Defaults=1,1,_\n_CreateMultiboardBJ_Limits=1,_,1,_,_,512\n_CreateMultiboardBJ_Category=TC_MULTIBOARD\nDestroyMultiboardBJ=1,multiboard\n_DestroyMultiboardBJ_Defaults=GetLastCreatedMultiboard\n_DestroyMultiboardBJ_Category=TC_MULTIBOARD\n_DestroyMultiboardBJ_ScriptName=DestroyMultiboard\nMultiboardDisplayBJ=1,showhideoption,multiboard\n_MultiboardDisplayBJ_Defaults=ShowHideHide,GetLastCreatedMultiboard\n_MultiboardDisplayBJ_Category=TC_MULTIBOARD\nMultiboardAllowDisplayBJ=1,showhideoption\n_MultiboardAllowDisplayBJ_Defaults=ShowHideHide\n_MultiboardAllowDisplayBJ_Category=TC_MULTIBOARD\nMultiboardMinimizeBJ=1,minimizeoption,multiboard\n_MultiboardMinimizeBJ_Defaults=Minimize,GetLastCreatedMultiboard\n_MultiboardMinimizeBJ_Category=TC_MULTIBOARD\nMultiboardClear=1,multiboard\n_MultiboardClear_Defaults=GetLastCreatedMultiboard\n_MultiboardClear_Category=TC_MULTIBOARD\nMultiboardSetTitleText=1,multiboard,StringExt\n_MultiboardSetTitleText_Defaults=GetLastCreatedMultiboard,_\n_MultiboardSetTitleText_Limits=_,_,_,512\n_MultiboardSetTitleText_Category=TC_MULTIBOARD\nMultiboardSetTitleTextColorBJ=1,multiboard,real,real,real,real\n_MultiboardSetTitleTextColorBJ_Defaults=GetLastCreatedMultiboard,100,80,20,0\n_MultiboardSetTitleTextColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_MultiboardSetTitleTextColorBJ_Category=TC_MULTIBOARD\nMultiboardSetRowCount=1,multiboard,integer\n_MultiboardSetRowCount_Defaults=GetLastCreatedMultiboard,1\n_MultiboardSetRowCount_Limits=_,_,1,_\n_MultiboardSetRowCount_Category=TC_MULTIBOARD\nMultiboardSetColumnCount=1,multiboard,integer\n_MultiboardSetColumnCount_Defaults=GetLastCreatedMultiboard,1\n_MultiboardSetColumnCount_Limits=_,_,1,_\n_MultiboardSetColumnCount_Category=TC_MULTIBOARD\nMultiboardSetItemStyleBJ=1,multiboard,integer,integer,showhideoption,showhideoption\n_MultiboardSetItemStyleBJ_Defaults=GetLastCreatedMultiboard,1,1,ShowHideShow,ShowHideShow\n_MultiboardSetItemStyleBJ_Limits=_,_,0,_,0,_,_,_,_,_\n_MultiboardSetItemStyleBJ_Category=TC_MULTIBOARD\nMultiboardSetItemValueBJ=1,multiboard,integer,integer,StringExt\n_MultiboardSetItemValueBJ_Defaults=GetLastCreatedMultiboard,1,1,_\n_MultiboardSetItemValueBJ_Limits=_,_,0,_,0,_,_,128\n_MultiboardSetItemValueBJ_Category=TC_MULTIBOARD\nMultiboardSetItemColorBJ=1,multiboard,integer,integer,real,real,real,real\n_MultiboardSetItemColorBJ_Defaults=GetLastCreatedMultiboard,1,1,100,80,20,0\n_MultiboardSetItemColorBJ_Limits=_,_,0,_,0,_,0,100,0,100,0,100,0,100\n_MultiboardSetItemColorBJ_Category=TC_MULTIBOARD\nMultiboardSetItemWidthBJ=1,multiboard,integer,integer,real\n_MultiboardSetItemWidthBJ_Defaults=GetLastCreatedMultiboard,1,1,3\n_MultiboardSetItemWidthBJ_Limits=_,_,0,_,0,_,0,100\n_MultiboardSetItemWidthBJ_Category=TC_MULTIBOARD\nMultiboardSetItemIconBJ=1,multiboard,integer,integer,imagefile\n_MultiboardSetItemIconBJ_Defaults=GetLastCreatedMultiboard,1,1,\"UI\\Feedback\\Resources\\ResourceGold.blp\"\n_MultiboardSetItemIconBJ_Limits=_,_,0,_,0,_,_,_\n_MultiboardSetItemIconBJ_Category=TC_MULTIBOARD\nMultiboardSetItemsValueColor=1,multiboard,integer,integer,integer,integer\n_MultiboardSetItemsValueColor_Defaults=_,100,100,100,0\n_MultiboardSetItemsValueColor_Category=TC_MULTIBOARD\nMultiboardSetItemValueColor=1,multiboarditem,integer,integer,integer,integer\n_MultiboardSetItemValueColor_Defaults=_,100,100,100,0\n_MultiboardSetItemValueColor_Category=TC_MULTIBOARD\nAddResourceAmountBJ=0,integer,unit\n_AddResourceAmountBJ_Defaults=5000,_\n_AddResourceAmountBJ_Category=TC_NEUTRALBUILDING\nSetResourceAmount=0,unit,integer\n_SetResourceAmount_Defaults=_,12500\n_SetResourceAmount_Limits=_,_,0,_\n_SetResourceAmount_Category=TC_NEUTRALBUILDING\nBlightGoldMineForPlayer=0,unit,player\n_BlightGoldMineForPlayer_Defaults=_,Player00\n_BlightGoldMineForPlayer_Category=TC_NEUTRALBUILDING\nWaygateActivateBJ=0,enabledisableoption,unit\n_WaygateActivateBJ_Defaults=EnableDisableEnable,_\n_WaygateActivateBJ_Category=TC_NEUTRALBUILDING\nWaygateSetDestinationLocBJ=0,unit,location\n_WaygateSetDestinationLocBJ_Defaults=_,GetRectCenter\n_WaygateSetDestinationLocBJ_Category=TC_NEUTRALBUILDING\nSetAltMinimapIcon=1,imagefile\n_SetAltMinimapIcon_Defaults=\"UI\\Minimap\\Minimap-Tower\"\n_SetAltMinimapIcon_Category=TC_NEUTRALBUILDING\nUnitSetUsesAltIconBJ=1,onoffoption,unit\n_UnitSetUsesAltIconBJ_Defaults=OnOffOn,_\n_UnitSetUsesAltIconBJ_Category=TC_NEUTRALBUILDING\nAddItemToStockBJ=1,itemcode,unit,integer,integer\n_AddItemToStockBJ_Defaults=texp,GetTriggerUnit,0,1\n_AddItemToStockBJ_Category=TC_NEUTRALBUILDING\nAddItemToAllStock=1,itemcode,integer,integer\n_AddItemToAllStock_Defaults=texp,0,1\n_AddItemToAllStock_Category=TC_NEUTRALBUILDING\nAddUnitToStockBJ=1,unitcode,unit,integer,integer\n_AddUnitToStockBJ_Defaults=hfoo,GetTriggerUnit,0,1\n_AddUnitToStockBJ_Category=TC_NEUTRALBUILDING\nAddUnitToAllStock=1,unitcode,integer,integer\n_AddUnitToAllStock_Defaults=hfoo,0,1\n_AddUnitToAllStock_Category=TC_NEUTRALBUILDING\nRemoveItemFromStockBJ=1,itemcode,unit\n_RemoveItemFromStockBJ_Defaults=texp,GetTriggerUnit\n_RemoveItemFromStockBJ_Category=TC_NEUTRALBUILDING\nRemoveItemFromAllStock=1,itemcode\n_RemoveItemFromAllStock_Defaults=texp\n_RemoveItemFromAllStock_Category=TC_NEUTRALBUILDING\nRemoveUnitFromStockBJ=1,unitcode,unit\n_RemoveUnitFromStockBJ_Defaults=hfoo,GetTriggerUnit\n_RemoveUnitFromStockBJ_Category=TC_NEUTRALBUILDING\nRemoveUnitFromAllStock=1,unitcode\n_RemoveUnitFromAllStock_Defaults=hfoo\n_RemoveUnitFromAllStock_Category=TC_NEUTRALBUILDING\nSetItemTypeSlots=1,unit,integer\n_SetItemTypeSlots_Defaults=GetTriggerUnit,6\n_SetItemTypeSlots_Category=TC_NEUTRALBUILDING\nSetAllItemTypeSlots=1,integer\n_SetAllItemTypeSlots_Defaults=6\n_SetAllItemTypeSlots_Category=TC_NEUTRALBUILDING\nSetUnitTypeSlots=1,unit,integer\n_SetUnitTypeSlots_Defaults=GetTriggerUnit,6\n_SetUnitTypeSlots_Category=TC_NEUTRALBUILDING\nSetAllUnitTypeSlots=1,integer\n_SetAllUnitTypeSlots_Defaults=6\n_SetAllUnitTypeSlots_Category=TC_NEUTRALBUILDING\nSetPlayerState=0,player,playerstate,integer\n_SetPlayerState_Defaults=Player00,PlayerStateGold,750\n_SetPlayerState_Category=TC_PLAYER\n_SetPlayerState_ScriptName=SetPlayerStateBJ\nAdjustPlayerStateBJ=0,integer,player,playerstate\n_AdjustPlayerStateBJ_Defaults=1000,Player00,PlayerStateGold\n_AdjustPlayerStateBJ_Category=TC_PLAYER\nSetPlayerFlagBJ=0,playerflag,onoffoption,player\n_SetPlayerFlagBJ_Defaults=PlayerFlagGivesBounty,OnOffOff,PlayerNA\n_SetPlayerFlagBJ_Category=TC_PLAYER\nSetPlayerTaxRateBJ=1,integer,playerresource,player,player,\n_SetPlayerTaxRateBJ_Defaults=0,PlayerResourceGold,Player00,Player01\n_SetPlayerTaxRateBJ_Limits=0,100,_,_,_,_,_,_\n_SetPlayerTaxRateBJ_Category=TC_PLAYER\nEnableCreepSleepBJ=1,enabledisableoption\n_EnableCreepSleepBJ_Defaults=EnableDisableDisable\n_EnableCreepSleepBJ_Category=TC_PLAYER\nSetPlayerAllianceStateBJ=0,player,player,alliancesetting\n_SetPlayerAllianceStateBJ_Defaults=Player00,Player01,AllianceSettingAlliedVision\n_SetPlayerAllianceStateBJ_Category=TC_PLAYER\nSetPlayerAllianceBJ=0,player,alliancetype,onoffoption,player\n_SetPlayerAllianceBJ_Defaults=Player00,AllianceTypePassive,OnOffOn,Player01\n_SetPlayerAllianceBJ_Category=TC_PLAYER\nSetPlayerAbilityAvailableBJ=0,enabledisableoption,abilcode,player\n_SetPlayerAbilityAvailableBJ_Defaults=EnableDisableDisable,_,Player00\n_SetPlayerAbilityAvailableBJ_Category=TC_PLAYER\nSetPlayerUnitAvailableBJ=0,unitcode,availabilityoption,player\n_SetPlayerUnitAvailableBJ_Defaults=hfoo,AvailabilityOptionAvailable,Player00\n_SetPlayerUnitAvailableBJ_Category=TC_PLAYER\nSetPlayerUnitMaxAllowed=1,unitcode,integer,player\n_SetPlayerUnitMaxAllowed_Defaults=hfoo,1,Player00\n_SetPlayerUnitMaxAllowed_Limits=_,_,-1,_,_,_\n_SetPlayerUnitMaxAllowed_Category=TC_PLAYER\n_SetPlayerUnitMaxAllowed_ScriptName=SetPlayerTechMaxAllowedSwap\nSetPlayerMaxHeroesAllowed=1,integer,player\n_SetPlayerMaxHeroesAllowed_Defaults=3,Player00\n_SetPlayerMaxHeroesAllowed_Limits=-1,_,_,_\n_SetPlayerMaxHeroesAllowed_Category=TC_PLAYER\nSetPlayerTechResearchedSwap=0,techcode,integer,player\n_SetPlayerTechResearchedSwap_Defaults=_,0,Player00\n_SetPlayerTechResearchedSwap_Limits=_,_,0,_,_,_\n_SetPlayerTechResearchedSwap_Category=TC_PLAYER\nSetPlayerTechMaxAllowedSwap=0,techcode,integer,player\n_SetPlayerTechMaxAllowedSwap_Defaults=_,0,Player00\n_SetPlayerTechMaxAllowedSwap_Limits=_,_,0,_,_,_\n_SetPlayerTechMaxAllowedSwap_Category=TC_PLAYER\nSetPlayerTechMaxAllowed=0,player,unitcode,integer\n_SetPlayerTechMaxAllowed_Defaults=Player00,hfoo,0\n_SetPlayerTechMaxAllowed_Limits=_,_,_,_,0,_\n_SetPlayerTechMaxAllowed_Category=TC_PLAYER\nSetPlayerColorBJ=0,player,playercolor,playerchangecoloroption\n_SetPlayerColorBJ_Defaults=Player00,Color00,PlayerChangeColorChange\n_SetPlayerColorBJ_Category=TC_PLAYER\nSetPlayerHandicapBJ=0,player,real\n_SetPlayerHandicapBJ_Defaults=Player00,100\n_SetPlayerHandicapBJ_Limits=_,_,1,10000\n_SetPlayerHandicapBJ_Category=TC_PLAYER\nSetPlayerOnScoreScreenBJ=0,showhideoption,player\n_SetPlayerOnScoreScreenBJ_Defaults=ShowHideHide,Player00\n_SetPlayerOnScoreScreenBJ_Category=TC_PLAYER\nSetPlayerName=1,player,StringExt\n_SetPlayerName_Defaults=Player00,_\n_SetPlayerName_Category=TC_PLAYER\nIssueNeutralImmediateOrderById=1,player,unit,unitcode\n_IssueNeutralImmediateOrderById_Defaults=Player00,_,nzep\n_IssueNeutralImmediateOrderById_Category=TC_PLAYER\nForForceMultiple=1,force\n_ForForceMultiple_Defaults=GetPlayersAll\n_ForForceMultiple_Category=TC_PLAYERGROUP\n_ForForceMultiple_ScriptName=ForForce\nForForce=0,force,code\n_ForForce_Defaults=GetPlayersAll,DoNothing\n_ForForce_Category=TC_PLAYERGROUP\nForceAddPlayerSimple=0,player,force\n_ForceAddPlayerSimple_Defaults=Player00,_\n_ForceAddPlayerSimple_Category=TC_PLAYERGROUP\nForceRemovePlayerSimple=0,player,force\n_ForceRemovePlayerSimple_Defaults=Player00,_\n_ForceRemovePlayerSimple_Category=TC_PLAYERGROUP\nForceClear=0,force\n_ForceClear_Defaults=_\n_ForceClear_Category=TC_PLAYERGROUP\nSetForceAllianceStateBJ=1,force,force,alliancesetting\n_SetForceAllianceStateBJ_Defaults=GetPlayersAll,GetPlayersAll,AllianceSettingAlliedVision\n_SetForceAllianceStateBJ_Category=TC_PLAYERGROUP\nQuestMessageBJ=0,force,questmessagetype,StringExt\n_QuestMessageBJ_Defaults=GetPlayersAll,QuestMessageTypeUpdated,_\n_QuestMessageBJ_Category=TC_QUEST\nCreateQuestBJ=0,questtypeoption,StringExt,StringExt,imagefile\n_CreateQuestBJ_Defaults=QuestTypeReqDiscovered,_,_,\"ReplaceableTextures\\CommandButtons\\BTNAmbush.blp\"\n_CreateQuestBJ_Limits=_,_,_,24,_,_,_,_\n_CreateQuestBJ_Category=TC_QUEST\nDestroyQuestBJ=0,quest\n_DestroyQuestBJ_Defaults=GetLastCreatedQuestBJ\n_DestroyQuestBJ_Category=TC_QUEST\n_DestroyQuestBJ_ScriptName=DestroyQuest\nQuestSetEnabledBJ=0,enabledisableoption,quest\n_QuestSetEnabledBJ_Defaults=EnableDisableDisable,GetLastCreatedQuestBJ\n_QuestSetEnabledBJ_Category=TC_QUEST\nQuestSetCompletedBJ=0,quest,completionoption\n_QuestSetCompletedBJ_Defaults=GetLastCreatedQuestBJ,CompletionOptionCompleted\n_QuestSetCompletedBJ_Category=TC_QUEST\n_QuestSetCompletedBJ_ScriptName=QuestSetCompleted\nQuestSetFailedBJ=0,quest,failureoption\n_QuestSetFailedBJ_Defaults=GetLastCreatedQuestBJ,FailureOptionFailed\n_QuestSetFailedBJ_Category=TC_QUEST\n_QuestSetFailedBJ_ScriptName=QuestSetFailed\nQuestSetDiscoveredBJ=0,quest,discoveredoption\n_QuestSetDiscoveredBJ_Defaults=GetLastCreatedQuestBJ,DiscoveredOptionDiscovered\n_QuestSetDiscoveredBJ_Category=TC_QUEST\n_QuestSetDiscoveredBJ_ScriptName=QuestSetDiscovered\nQuestSetTitleBJ=0,quest,StringExt\n_QuestSetTitleBJ_Defaults=GetLastCreatedQuestBJ,_\n_QuestSetTitleBJ_Category=TC_QUEST\n_QuestSetTitleBJ_ScriptName=QuestSetTitle\nQuestSetDescriptionBJ=0,quest,StringExt\n_QuestSetDescriptionBJ_Defaults=GetLastCreatedQuestBJ,_\n_QuestSetDescriptionBJ_Category=TC_QUEST\n_QuestSetDescriptionBJ_ScriptName=QuestSetDescription\nCreateQuestItemBJ=0,quest,StringExt\n_CreateQuestItemBJ_Defaults=GetLastCreatedQuestBJ,_\n_CreateQuestItemBJ_Category=TC_QUEST\nQuestItemSetCompletedBJ=0,questitem,completionoption\n_QuestItemSetCompletedBJ_Defaults=GetLastCreatedQuestItemBJ,CompletionOptionCompleted\n_QuestItemSetCompletedBJ_Category=TC_QUEST\n_QuestItemSetCompletedBJ_ScriptName=QuestItemSetCompleted\nQuestItemSetDescriptionBJ=0,questitem,StringExt\n_QuestItemSetDescriptionBJ_Defaults=GetLastCreatedQuestItemBJ,_\n_QuestItemSetDescriptionBJ_Category=TC_QUEST\n_QuestItemSetDescriptionBJ_ScriptName=QuestItemSetDescription\nCreateDefeatConditionBJ=0,StringExt\n_CreateDefeatConditionBJ_Defaults=_\n_CreateDefeatConditionBJ_Category=TC_QUEST\nDestroyDefeatConditionBJ=0,defeatcondition\n_DestroyDefeatConditionBJ_Defaults=GetLastCreatedDefeatConditionBJ\n_DestroyDefeatConditionBJ_Category=TC_QUEST\n_DestroyDefeatConditionBJ_ScriptName=DestroyDefeatCondition\nDefeatConditionSetDescriptionBJ=0,defeatcondition,StringExt\n_DefeatConditionSetDescriptionBJ_Defaults=GetLastCreatedDefeatConditionBJ,_\n_DefeatConditionSetDescriptionBJ_Category=TC_QUEST\n_DefeatConditionSetDescriptionBJ_ScriptName=DefeatConditionSetDescription\nFlashQuestDialogButtonBJ=0,nothing\n_FlashQuestDialogButtonBJ_Defaults=\n_FlashQuestDialogButtonBJ_Category=TC_QUEST\n_FlashQuestDialogButtonBJ_ScriptName=FlashQuestDialogButton\nMoveRectTo=0,rect,real,real\n_MoveRectTo_Defaults=_,GetLocationX,GetLocationY\n_MoveRectTo_Category=TC_REGION\nMoveRectToLoc=0,rect,location\n_MoveRectToLoc_Defaults=_,GetRectCenter\n_MoveRectToLoc_Category=TC_REGION\nRemoveRect=0,rect\n_RemoveRect_Defaults=\n_RemoveRect_Category=TC_REGION\nRegionAddCell=1,region,real,real\n_RegionAddCell_Defaults=_,_,_\n_RegionAddCell_Category=TC_RECTANGLE\nRegionAddCellAtLoc=1,region,location\n_RegionAddCellAtLoc_Defaults=_,_\n_RegionAddCellAtLoc_Category=TC_RECTANGLE\nRegionAddRect=1,region,rect\n_RegionAddRect_Defaults=_,_\n_RegionAddRect_Category=TC_RECTANGLE\nRegionClearCell=1,region,real,real\n_RegionClearCell_Defaults=_,_,_\n_RegionClearCell_Category=TC_RECTANGLE\nRegionClearCellAtLoc=1,region,location\n_RegionClearCellAtLoc_Defaults=_,_\n_RegionClearCellAtLoc_Category=TC_RECTANGLE\nRegionClearRect=1,region,rect\n_RegionClearRect_Defaults=_,_\n_RegionClearRect_Category=TC_RECTANGLE\nRemoveRegion=0,region\n_RemoveRegion_Defaults=\n_RemoveRegion_Category=TC_RECTANGLE\nClearSelectionForPlayer=1,player\n_ClearSelectionForPlayer_Defaults=Player00\n_ClearSelectionForPlayer_Category=TC_UNITSEL\nSelectGroupForPlayerBJ=1,group,player\n_SelectGroupForPlayerBJ_Defaults=_,Player00\n_SelectGroupForPlayerBJ_Category=TC_UNITSEL\nSelectUnitForPlayerSingle=1,unit,player\n_SelectUnitForPlayerSingle_Defaults=GetTriggerUnit,Player00\n_SelectUnitForPlayerSingle_Category=TC_UNITSEL\nSelectUnitAddForPlayer=1,unit,player\n_SelectUnitAddForPlayer_Defaults=GetTriggerUnit,Player00\n_SelectUnitAddForPlayer_Category=TC_UNITSEL\nSelectUnitRemoveForPlayer=1,unit,player\n_SelectUnitRemoveForPlayer_Defaults=GetTriggerUnit,Player00\n_SelectUnitRemoveForPlayer_Category=TC_UNITSEL\nClearSelection=0,nothing\n_ClearSelection_Defaults=\n_ClearSelection_Category=TC_UNITSEL\nSelectGroupBJ=0,group\n_SelectGroupBJ_Defaults=_\n_SelectGroupBJ_Category=TC_UNITSEL\nSelectUnitSingle=0,unit\n_SelectUnitSingle_Defaults=GetTriggerUnit\n_SelectUnitSingle_Category=TC_UNITSEL\nSelectUnitAdd=0,unit\n_SelectUnitAdd_Defaults=GetTriggerUnit\n_SelectUnitAdd_Category=TC_UNITSEL\nSelectUnitRemove=0,unit\n_SelectUnitRemove_Defaults=GetTriggerUnit\n_SelectUnitRemove_Category=TC_UNITSEL\nSyncSelections=0,nothing\n_SyncSelections_Defaults=\n_SyncSelections_Category=TC_UNITSEL\nPlaySoundBJ=0,sound\n_PlaySoundBJ_Defaults=_\n_PlaySoundBJ_Category=TC_SOUND\nPlaySoundAtPointBJ=1,sound,real,location,real\n_PlaySoundAtPointBJ_Defaults=_,100,GetRectCenter,0\n_PlaySoundAtPointBJ_Limits=_,_,0,100,_,_,_,_\n_PlaySoundAtPointBJ_Category=TC_SOUND\nPlaySoundOnUnitBJ=1,sound,real,unit\n_PlaySoundOnUnitBJ_Defaults=_,100,_\n_PlaySoundOnUnitBJ_Limits=_,_,0,100,_,_\n_PlaySoundOnUnitBJ_Category=TC_SOUND\nPlaySoundFromOffsetBJ=1,sound,real,real\n_PlaySoundFromOffsetBJ_Defaults=_,100,0,0\n_PlaySoundFromOffsetBJ_Limits=_,_,0,100,0,_,0,_\n_PlaySoundFromOffsetBJ_Category=TC_SOUND\nStopSoundBJ=0,sound,fadedontoption\n_StopSoundBJ_Defaults=_,FadeDontFade\n_StopSoundBJ_Category=TC_SOUND\nKillSoundWhenDoneBJ=0,sound\n_KillSoundWhenDoneBJ_Defaults=_\n_KillSoundWhenDoneBJ_Category=TC_SOUND\nSetSoundVolumeBJ=0,sound,real\n_SetSoundVolumeBJ_Defaults=_,100\n_SetSoundVolumeBJ_Limits=_,_,0,100\n_SetSoundVolumeBJ_Category=TC_SOUND\nSetSoundOffsetBJ=1,real,sound\n_SetSoundOffsetBJ_Defaults=0,_\n_SetSoundOffsetBJ_Limits=0,_,_,_\n_SetSoundOffsetBJ_Category=TC_SOUND\nSetSoundDistanceCutoffBJ=0,sound,real\n_SetSoundDistanceCutoffBJ_Defaults=_,_\n_SetSoundDistanceCutoffBJ_Category=TC_SOUND\nSetSoundPitchBJ=0,sound,real\n_SetSoundPitchBJ_Defaults=_,_\n_SetSoundPitchBJ_Category=TC_SOUND\nAttachSoundToUnitBJ=0,sound,unit\n_AttachSoundToUnitBJ_Defaults=_,_\n_AttachSoundToUnitBJ_Category=TC_SOUND\nSetSoundPositionLocBJ=0,sound,location,real\n_SetSoundPositionLocBJ_Defaults=_,GetRectCenter,0\n_SetSoundPositionLocBJ_Category=TC_SOUND\nSetSoundDistances=0,sound,real,real\n_SetSoundDistances_Defaults=_,_,_\n_SetSoundDistances_Limits=_,_,0,_,0,_\n_SetSoundDistances_Category=TC_SOUND\nSetStackedSoundBJ=0,addremoveoption,sound,rect\n_SetStackedSoundBJ_Defaults=AddRemoveAdd,_,_\n_SetStackedSoundBJ_Category=TC_SOUND\nSetAmbientDaySound=0,ambientthemeday\n_SetAmbientDaySound_Defaults=AmbientThemeDayL\n_SetAmbientDaySound_Category=TC_SOUND\nSetAmbientNightSound=0,ambientthemenight\n_SetAmbientNightSound_Defaults=AmbientThemeNightL\n_SetAmbientNightSound_Category=TC_SOUND\nEnableDawnDusk=0,enabledisableoption\n_EnableDawnDusk_Defaults=EnableDisableEnable\n_EnableDawnDusk_Category=TC_SOUND\nSetMapMusicIndexedBJ=0,musicfile,integer\n_SetMapMusicIndexedBJ_Defaults=MusicFileMusic,0\n_SetMapMusicIndexedBJ_Category=TC_SOUND\nSetMapMusicRandomBJ=0,musicfile\n_SetMapMusicRandomBJ_Defaults=MusicFileMusic\n_SetMapMusicRandomBJ_Category=TC_SOUND\nClearMapMusicBJ=0,nothing\n_ClearMapMusicBJ_Defaults=\n_ClearMapMusicBJ_Category=TC_SOUND\nPlayMusicBJ=0,musicfile\n_PlayMusicBJ_Defaults=_\n_PlayMusicBJ_Category=TC_SOUND\nPlayMusicExBJ=1,musicfile,real,real\n_PlayMusicExBJ_Defaults=_,0,0\n_PlayMusicExBJ_Limits=_,_,0,_,0,_\n_PlayMusicExBJ_Category=TC_SOUND\nPlayThematicMusicBJ=0,musictheme\n_PlayThematicMusicBJ_Defaults=MusicThemeHeroicVictory\n_PlayThematicMusicBJ_Category=TC_SOUND\nPlayThematicMusicExBJ=1,musictheme,real\n_PlayThematicMusicExBJ_Defaults=MusicThemeHeroicVictory,0\n_PlayThematicMusicExBJ_Limits=_,_,0,_\n_PlayThematicMusicExBJ_Category=TC_SOUND\nEndThematicMusicBJ=0,nothing\n_EndThematicMusicBJ_Defaults=\n_EndThematicMusicBJ_Category=TC_SOUND\nStopMusicBJ=0,fadedontoption\n_StopMusicBJ_Defaults=FadeDontFade\n_StopMusicBJ_Category=TC_SOUND\nResumeMusicBJ=0,nothing\n_ResumeMusicBJ_Defaults=\n_ResumeMusicBJ_Category=TC_SOUND\nSetMusicVolumeBJ=0,real\n_SetMusicVolumeBJ_Defaults=100\n_SetMusicVolumeBJ_Limits=0,100\n_SetMusicVolumeBJ_Category=TC_SOUND\nSetMusicOffsetBJ=1,real\n_SetMusicOffsetBJ_Defaults=0\n_SetMusicOffsetBJ_Limits=0,_\n_SetMusicOffsetBJ_Category=TC_SOUND\nSetThematicMusicOffsetBJ=1,real\n_SetThematicMusicOffsetBJ_Defaults=0\n_SetThematicMusicOffsetBJ_Limits=0,_\n_SetThematicMusicOffsetBJ_Category=TC_SOUND\nVolumeGroupSetVolumeBJ=0,volumegroup,real\n_VolumeGroupSetVolumeBJ_Defaults=VolumeGroupMusic,100\n_VolumeGroupSetVolumeBJ_Limits=_,_,0,100\n_VolumeGroupSetVolumeBJ_Category=TC_SOUND\nSetCineModeVolumeGroupsBJ=0,nothing\n_SetCineModeVolumeGroupsBJ_Defaults=\n_SetCineModeVolumeGroupsBJ_Category=TC_SOUND\nSetSpeechVolumeGroupsBJ=0,nothing\n_SetSpeechVolumeGroupsBJ_Defaults=\n_SetSpeechVolumeGroupsBJ_Category=TC_SOUND\nVolumeGroupResetBJ=0,nothing\n_VolumeGroupResetBJ_Defaults=\n_VolumeGroupResetBJ_Category=TC_SOUND\nAddSpecialEffectLocBJ=0,location,modelfile\n_AddSpecialEffectLocBJ_Defaults=GetRectCenter,\"Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl\"\n_AddSpecialEffectLocBJ_Category=TC_SPECIALEFFECT\nAddSpecialEffectTargetUnitBJ=0,string,unit,modelfile\n_AddSpecialEffectTargetUnitBJ_Defaults=\"overhead\",GetTriggerUnit,\"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl\"\n_AddSpecialEffectTargetUnitBJ_Category=TC_SPECIALEFFECT\nDestroyEffectBJ=0,effect\n_DestroyEffectBJ_Defaults=GetLastCreatedEffectBJ\n_DestroyEffectBJ_Category=TC_SPECIALEFFECT\nAddLightningLoc=0,lightningtype,location,location\n_AddLightningLoc_Defaults=_\n_AddLightningLoc_Category=TC_LIGHTNING\nAddLightningEx=0,lightningtype,boolean,real,real,real,real,real,real\n_AddLightningEx_Defaults=LightningTypeCLPB,true,_\n_AddLightningEx_Category=TC_LIGHTNING\nDestroyLightningBJ=0,lightning\n_DestroyLightningBJ_Defaults=GetLastCreatedLightningBJ\n_DestroyLightningBJ_Category=TC_LIGHTNING\n_DestroyLightningBJ_ScriptName=DestroyLightning\nMoveLightningLoc=0,lightning,location,location\n_MoveLightningLoc_Defaults=_\n_MoveLightningLoc_Category=TC_LIGHTNING\nMoveLightningEx=0,lightning,boolean,real,real,real,real,real,real\n_MoveLightningEx_Defaults=_\n_MoveLightningEx_Category=TC_LIGHTNING\nSetLightningColorBJ=0,lightning,real,real,real,real\n_SetLightningColorBJ_Defaults=_,1,1,1,1\n_SetLightningColorBJ_Category=TC_LIGHTNING\nDestroyTrigger=0,trigger\n_DestroyTrigger_Defaults=GetTriggeringTrigger\n_DestroyTrigger_Category=TC_TRIGGER\nDisableTrigger=0,trigger\n_DisableTrigger_Defaults=GetTriggeringTrigger\n_DisableTrigger_Category=TC_TRIGGER\nEnableTrigger=0,trigger\n_EnableTrigger_Defaults=GetTriggeringTrigger\n_EnableTrigger_Category=TC_TRIGGER\nConditionalTriggerExecute=0,trigger\n_ConditionalTriggerExecute_Defaults=_\n_ConditionalTriggerExecute_Category=TC_TRIGGER\nTriggerExecute=0,trigger\n_TriggerExecute_Defaults=_\n_TriggerExecute_Category=TC_TRIGGER\nQueuedTriggerAddBJ=0,trigger,checkingignoringoption\n_QueuedTriggerAddBJ_Defaults=_,CheckingIgnoringChecking\n_QueuedTriggerAddBJ_Category=TC_TRIGGER\nQueuedTriggerRemoveBJ=0,trigger\n_QueuedTriggerRemoveBJ_Defaults=GetTriggeringTrigger\n_QueuedTriggerRemoveBJ_Category=TC_TRIGGER\nQueuedTriggerClearBJ=0,nothing\n_QueuedTriggerClearBJ_Defaults=\n_QueuedTriggerClearBJ_Category=TC_TRIGGER\nQueuedTriggerClearInactiveBJ=0,nothing\n_QueuedTriggerClearInactiveBJ_Defaults=\n_QueuedTriggerClearInactiveBJ_Category=TC_TRIGGER\nTriggerRemoveCondition=0,trigger,triggercondition\n_TriggerRemoveCondition_Defaults=GetTriggeringTrigger,_\n_TriggerRemoveCondition_Category=TC_TRIGGER\nTriggerClearConditions=0,trigger\n_TriggerClearConditions_Defaults=GetTriggeringTrigger\n_TriggerClearConditions_Category=TC_TRIGGER\nTriggerRemoveAction=0,trigger,triggeraction\n_TriggerRemoveAction_Defaults=GetTriggeringTrigger,_\n_TriggerRemoveAction_Category=TC_TRIGGER\nTriggerClearActions=0,trigger\n_TriggerClearActions_Defaults=GetTriggeringTrigger\n_TriggerClearActions_Category=TC_TRIGGER\nResetTrigger=0,trigger\n_ResetTrigger_Defaults=GetTriggeringTrigger\n_ResetTrigger_Category=TC_TRIGGER\nAddTriggerEvent=1,trigger,eventcall\n_AddTriggerEvent_Defaults=GetTriggeringTrigger,_\n_AddTriggerEvent_Category=TC_TRIGGER\nTriggerAddCondition=1,trigger,boolexpr\n_TriggerAddCondition_Defaults=_,_\n_TriggerAddCondition_Category=TC_TRIGGER\nTriggerAddAction=1,trigger,code\n_TriggerAddAction_Defaults=_,_\n_TriggerAddAction_Category=TC_TRIGGER\nQueuedTriggerRemoveByIndex=0,integer\n_QueuedTriggerRemoveByIndex_Defaults=0\n_QueuedTriggerRemoveByIndex_Category=TC_TRIGGER\nCreateNUnitsAtLoc=0,integer,unitcode,player,location,real\n_CreateNUnitsAtLoc_Defaults=1,hfoo,Player00,GetRectCenter,RealUnitFacing\n_CreateNUnitsAtLoc_Limits=1,_,_,_,_,_,_,_,0,360\n_CreateNUnitsAtLoc_Category=TC_UNIT\nCreateNUnitsAtLocFacingLocBJ=0,integer,unitcode,player,location,location\n_CreateNUnitsAtLocFacingLocBJ_Defaults=1,hfoo,Player00,GetRectCenter,GetUnitLoc\n_CreateNUnitsAtLocFacingLocBJ_Limits=1,_,_,_,_,_,_,_,_,_\n_CreateNUnitsAtLocFacingLocBJ_Category=TC_UNIT\nCreateCorpseLocBJ=0,unitcode,player,location\n_CreateCorpseLocBJ_Defaults=hfoo,Player00,GetRectCenter\n_CreateCorpseLocBJ_Category=TC_UNIT\nCreatePermanentCorpseLocBJ=1,corpsetype,unitcode,player,location,real\n_CreatePermanentCorpseLocBJ_Defaults=CorpseTypeBone,hfoo,Player00,GetRectCenter,GetRandomDirectionDeg\n_CreatePermanentCorpseLocBJ_Limits=_,_,_,_,_,_,_,_,0,360\n_CreatePermanentCorpseLocBJ_Category=TC_UNIT\nKillUnit=0,unit\n_KillUnit_Defaults=GetTriggerUnit\n_KillUnit_Category=TC_UNIT\nRemoveUnit=0,unit\n_RemoveUnit_Defaults=GetTriggerUnit\n_RemoveUnit_Category=TC_UNIT\nExplodeUnitBJ=0,unit\n_ExplodeUnitBJ_Defaults=GetTriggerUnit\n_ExplodeUnitBJ_Category=TC_UNIT\nReplaceUnitBJ=0,unit,unitcode,unitstatemethod\n_ReplaceUnitBJ_Defaults=GetTriggerUnit,hfoo,UnitStateMethodRelative\n_ReplaceUnitBJ_Category=TC_UNIT\nShowUnitHide=0,unit\n_ShowUnitHide_Defaults=_\n_ShowUnitHide_Category=TC_UNIT\nShowUnitShow=0,unit\n_ShowUnitShow_Defaults=_\n_ShowUnitShow_Category=TC_UNIT\nSetUnitColor=0,unit,playercolor\n_SetUnitColor_Defaults=GetTriggerUnit,Color00\n_SetUnitColor_Category=TC_UNIT\nSetUnitOwner=0,unit,player,colorchangeoption\n_SetUnitOwner_Defaults=_,Player00,ChangeColorTrue\n_SetUnitOwner_Category=TC_UNIT\nUnitShareVisionBJ=0,sharedontoption,unit,player\n_UnitShareVisionBJ_Defaults=ShareDontOptionShare,GetTriggerUnit,Player00\n_UnitShareVisionBJ_Category=TC_UNIT\nSetUnitPositionLoc=0,unit,location\n_SetUnitPositionLoc_Defaults=GetTriggerUnit,GetRectCenter\n_SetUnitPositionLoc_Category=TC_UNIT\nSetUnitPositionLocFacingBJ=0,unit,location,real\n_SetUnitPositionLocFacingBJ_Defaults=GetTriggerUnit,GetRectCenter,RealUnitFacing\n_SetUnitPositionLocFacingBJ_Category=TC_UNIT\nSetUnitPositionLocFacingLocBJ=0,unit,location,location\n_SetUnitPositionLocFacingLocBJ_Defaults=GetTriggerUnit,GetRectCenter,GetUnitLoc\n_SetUnitPositionLocFacingLocBJ_Category=TC_UNIT\nSetUnitRallyPoint=1,unit,location\n_SetUnitRallyPoint_Defaults=GetTriggerUnit,GetRectCenter\n_SetUnitRallyPoint_Category=TC_UNIT\nSetUnitRallyUnit=1,unit,unit\n_SetUnitRallyUnit_Defaults=GetTriggerUnit,_\n_SetUnitRallyUnit_Category=TC_UNIT\nSetUnitRallyDestructable=1,unit,destructable\n_SetUnitRallyDestructable_Defaults=GetTriggerUnit,_\n_SetUnitRallyDestructable_Category=TC_UNIT\nSetUnitLifePercentBJ=0,unit,real\n_SetUnitLifePercentBJ_Defaults=GetTriggerUnit,100\n_SetUnitLifePercentBJ_Limits=_,_,0,100\n_SetUnitLifePercentBJ_Category=TC_UNIT\nSetUnitManaPercentBJ=0,unit,real\n_SetUnitManaPercentBJ_Defaults=GetTriggerUnit,100\n_SetUnitManaPercentBJ_Limits=_,_,0,100\n_SetUnitManaPercentBJ_Category=TC_UNIT\nSetUnitLifeBJ=0,unit,real\n_SetUnitLifeBJ_Defaults=GetTriggerUnit,GetUnitStateSwap\n_SetUnitLifeBJ_Defaults=_,_,0,_\n_SetUnitLifeBJ_Category=TC_UNIT\nSetUnitManaBJ=0,unit,real\n_SetUnitManaBJ_Defaults=GetTriggerUnit,0\n_SetUnitManaBJ_Limits=_,_,0,_\n_SetUnitManaBJ_Category=TC_UNIT\nUnitIgnoreAlarm=1,unit,boolean\n_UnitIgnoreAlarm_Defaults=_,true\n_UnitIgnoreAlarm_Category=TC_UNIT\nSetUnitInvulnerable=0,unit,invulnerableoption\n_SetUnitInvulnerable_Defaults=GetTriggerUnit,InvulnerabilityInvulnerable\n_SetUnitInvulnerable_Category=TC_UNIT\nPauseUnitBJ=0,pauseunpauseoption,unit\n_PauseUnitBJ_Defaults=PauseUnpauseOptionPause,GetTriggerUnit\n_PauseUnitBJ_Category=TC_UNIT\nPauseAllUnitsBJ=0,pauseunpauseoption\n_PauseAllUnitsBJ_Defaults=PauseUnpauseOptionPause\n_PauseAllUnitsBJ_Category=TC_UNIT\nUnitPauseTimedLifeBJ=1,pauseunpauseoption,unit\n_UnitPauseTimedLifeBJ_Defaults=PauseUnpauseOptionPause,GetTriggerUnit\n_UnitPauseTimedLifeBJ_Category=TC_UNIT\nUnitApplyTimedLifeBJ=1,real,timedlifebuffcode,unit\n_UnitApplyTimedLifeBJ_Defaults=60,TimedLifeBuffCodeGeneric,GetTriggerUnit\n_UnitApplyTimedLifeBJ_Limits=0,_,_,_,_,_\n_UnitApplyTimedLifeBJ_Category=TC_UNIT\nUnitApplyTimedLifeB=0,unit,buffcode,integer\n_UnitApplyTimedLifeB_Defaults=GetTriggerUnit,_,60\n_UnitApplyTimedLifeB_ScriptName=UnitApplyTimedLife\n_UnitApplyTimedLifeB_Category=TC_UNIT\nSetUnitExplodedBJ=0,unit,explodedontoption\n_SetUnitExplodedBJ_Defaults=GetTriggerUnit,ExplodeDontExplode\n_SetUnitExplodedBJ_Category=TC_UNIT\nUnitSuspendDecayBJ=0,suspendresumeoption,unit\n_UnitSuspendDecayBJ_Defaults=SuspendResumeSuspend,GetTriggerUnit\n_UnitSuspendDecayBJ_Category=TC_UNIT\nUnitResetCooldown=1,unit\n_UnitResetCooldown_Defaults=GetTriggerUnit\n_UnitResetCooldown_Category=TC_UNIT\nUnitSetConstructionProgress=1,unit,integer\n_UnitSetConstructionProgress_Defaults=GetTriggerUnit,50\n_UnitSetConstructionProgress_Limits=_,_,0,100\n_UnitSetConstructionProgress_Category=TC_UNIT\nUnitSetUpgradeProgress=1,unit,integer\n_UnitSetUpgradeProgress_Defaults=GetTriggerUnit,50\n_UnitSetUpgradeProgress_Limits=_,_,0,100\n_UnitSetUpgradeProgress_Category=TC_UNIT\nUnitAddSleepPerm=0,unit,sleepwakeoption\n_UnitAddSleepPerm_Defaults=GetTriggerUnit,SleepWakeOptionSleep\n_UnitAddSleepPerm_Category=TC_UNIT\nUnitSetCanSleepBJ=0,unit,sleepwakeoption\n_UnitSetCanSleepBJ_Defaults=GetTriggerUnit,SleepWakeOptionSleep\n_UnitSetCanSleepBJ_Category=TC_UNIT\nUnitWakeUpBJ=0,unit\n_UnitWakeUpBJ_Defaults=GetTriggerUnit\n_UnitWakeUpBJ_Category=TC_UNIT\nUnitGenerateAlarms=1,unit,onoffoption\n_UnitGenerateAlarms_Defaults=GetTriggerUnit,OnOffOff\n_UnitGenerateAlarms_Category=TC_UNIT\nRescueUnitBJ=0,unit,player,colorchangeoption\n_RescueUnitBJ_Defaults=_,Player00,ChangeColorTrue\n_RescueUnitBJ_Category=TC_UNIT\nMakeUnitRescuableToForceBJ=0,unit,rescuableoption,force\n_MakeUnitRescuableToForceBJ_Defaults=_,RescuableOptionRescuable,Force00\n_MakeUnitRescuableToForceBJ_Category=TC_UNIT\nSetUnitRescueRange=0,unit,real\n_SetUnitRescueRange_Defaults=_,384\n_SetUnitRescueRange_Limits=_,_,0,_\n_SetUnitRescueRange_Category=TC_UNIT\nSetRescueUnitColorChangeBJ=0,colorchangeoption\n_SetRescueUnitColorChangeBJ_Defaults=ChangeColorFalse\n_SetRescueUnitColorChangeBJ_Category=TC_UNIT\nSetRescueBuildingColorChangeBJ=0,colorchangeoption\n_SetRescueBuildingColorChangeBJ_Defaults=ChangeColorFalse\n_SetRescueBuildingColorChangeBJ_Category=TC_UNIT\nSetUnitUseFoodBJ=1,enabledisableoption,unit\n_SetUnitUseFoodBJ_Defaults=EnableDisableDisable,_\n_SetUnitUseFoodBJ_Category=TC_UNIT\nSetUnitFacingToFaceUnitTimed=0,unit,unit,real\n_SetUnitFacingToFaceUnitTimed_Defaults=_,_,0\n_SetUnitFacingToFaceUnitTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingToFaceUnitTimed_Category=TC_UNIT\nSetUnitFacingToFaceLocTimed=0,unit,location,real\n_SetUnitFacingToFaceLocTimed_Defaults=_,GetRectCenter,0\n_SetUnitFacingToFaceLocTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingToFaceLocTimed_Category=TC_UNIT\nSetUnitFacingTimed=0,unit,real,real\n_SetUnitFacingTimed_Defaults=_,RealUnitFacing,0\n_SetUnitFacingTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingTimed_Category=TC_UNIT\nSetUnitMoveSpeed=0,unit,real\n_SetUnitMoveSpeed_Defaults=_,GetUnitDefaultMoveSpeed\n_SetUnitMoveSpeed_Category=TC_UNIT\nSetUnitPathing=0,unit,pathingoption\n_SetUnitPathing_Defaults=_,PathingOff\n_SetUnitPathing_Category=TC_UNIT\nSetUnitAcquireRangeBJ=0,unit,real\n_SetUnitAcquireRangeBJ_Defaults=_,_\n_SetUnitAcquireRangeBJ_Category=TC_UNIT\nSetUnitUserData=1,unit,integer\n_SetUnitUserData_Defaults=_,0\n_SetUnitUserData_Category=TC_UNIT\nUnitRemoveBuffsBJ=0,bufftype,unit\n_UnitRemoveBuffsBJ_Defaults=BuffTypeAll,GetTriggerUnit\n_UnitRemoveBuffsBJ_Category=TC_UNIT\nUnitRemoveBuffsExBJ=1,buffpolarity,buffresist,unit,includeoption,includeoption\n_UnitRemoveBuffsExBJ_Defaults=BuffPolarityEither,BuffResistEither,GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitRemoveBuffsExBJ_Category=TC_UNIT\nUnitRemoveBuffBJ=1,buffcode,unit\n_UnitRemoveBuffBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveBuffBJ_Category=TC_UNIT\nUnitAddAbilityBJ=1,abilcode,unit\n_UnitAddAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitAddAbilityBJ_Category=TC_UNIT\nUnitRemoveAbilityBJ=0,abilcode,unit\n_UnitRemoveAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveAbilityBJ_Category=TC_UNIT\nUnitAddTypeBJ=1,unittype,unit\n_UnitAddTypeBJ_Defaults=UnitTypeMechanical,GetTriggerUnit\n_UnitAddTypeBJ_Category=TC_UNIT\nUnitRemoveTypeBJ=1,unittype,unit\n_UnitRemoveTypeBJ_Defaults=UnitTypeMechanical,GetTriggerUnit\n_UnitRemoveTypeBJ_Category=TC_UNIT\nUnitMakeAbilityPermanentBJ=0,unit,permanentoption,abilcode\n_UnitMakeAbilityPermanentBJ_Defaults=GetTriggerUnit,PermanentPerm,_\n_UnitMakeAbilityPermanentBJ_Category=TC_UNIT\n_UnitMakeAbilityPermanentBJ_ScriptName=UnitMakeAbilityPermanent\nIssueTargetOrder=0,unit,unitorderutarg,unit\n_IssueTargetOrder_Defaults=_,UnitOrderAttackUnit,_\n_IssueTargetOrder_Category=TC_UNIT\n_IssueTargetOrder_ScriptName=IssueTargetOrderBJ\nIssueTargetOrderBJ=0,unit,string,unit\n_IssueTargetOrderBJ_Defaults=_,\"attack\",_\n_IssueTargetOrderBJ_Category=TC_UNIT\n_IssueTargetOrderBJ_ScriptName=IssueTargetOrder\nIssueTargetOrderById=0,unit,ordercode,unit\n_IssueTargetOrderById_Defaults=_,OrderCodeAttackUnit,_\n_IssueTargetOrderById_Category=TC_UNIT\nIssuePointOrderLoc=0,unit,unitorderptarg,location\n_IssuePointOrderLoc_Defaults=_,UnitOrderMove,GetRectCenter\n_IssuePointOrderLoc_Category=TC_UNIT\n_IssuePointOrderLoc_ScriptName=IssuePointOrderLocBJ\nIssuePointOrderLocBJ=0,unit,string,location\n_IssuePointOrderLocBJ_Defaults=_,\"move\",GetRectCenter\n_IssuePointOrderLocBJ_Category=TC_UNIT\n_IssuePointOrderLocBJ_ScriptName=IssuePointOrderLoc\nIssuePointOrderByIdLoc=0,unit,ordercode,location\n_IssuePointOrderByIdLoc_Defaults=_,OrderCodeMoveUnit,GetRectCenter\n_IssuePointOrderByIdLoc_Category=TC_UNIT\nIssueTargetDestructableOrder=0,unit,unitorderdtarg,destructable\n_IssueTargetDestructableOrder_Defaults=_,UnitOrderHarvestDestructible,_\n_IssueTargetDestructableOrder_Category=TC_UNIT\nIssueTargetOrderD=0,unit,string,destructable\n_IssueTargetOrderD_Defaults=_,\"harvest\",_\n_IssueTargetOrderD_Category=TC_UNIT\n_IssueTargetOrderD_ScriptName=IssueTargetOrder\nIssueTargetOrderByIdD=0,unit,ordercode,destructable\n_IssueTargetOrderByIdD_Defaults=_,OrderCodeHarvest,_\n_IssueTargetOrderByIdD_Category=TC_UNIT\n_IssueTargetOrderByIdD_Scriptname=IssueTargetOrderById\nIssueTargetItemOrder=0,unit,unitorderitarg,item\n_IssueTargetItemOrder_Defaults=_,UnitOrderSmartItem,_\n_IssueTargetItemOrder_Category=TC_UNIT\nIssueItemTargetOrderS=0,unit,string,item\n_IssueItemTargetOrderS_Defaults=_,\"smart\",_\n_IssueItemTargetOrderS_Category=TC_UNIT\n_IssueItemTargetOrderS_ScriptName=IssueTargetOrderBJ\nIssueItemTargetOrderId=0,unit,ordercode,item\n_IssueItemTargetOrderId_Defaults=_,OrderCodeAttackUnit,_\n_IssueItemTargetOrderId_Category=TC_UNIT\n_IssueItemTargetOrderId_Scriptname=IssueTargetOrderById\nIssueImmediateOrder=0,unit,unitordernotarg\n_IssueImmediateOrder_Defaults=_,UnitOrderStop\n_IssueImmediateOrder_Category=TC_UNIT\n_IssueImmediateOrder_ScriptName=IssueImmediateOrderBJ\nIssueImmediateOrderBJ=0,unit,string\n_IssueImmediateOrderBJ_Defaults=_,\"stop\"\n_IssueImmediateOrderBJ_Category=TC_UNIT\n_IssueImmediateOrderBJ_ScriptName=IssueImmediateOrder\nIssueImmediateOrderById=0,unit,ordercode\n_IssueImmediateOrderById_Defaults=_,OrderCodeStop\n_IssueImmediateOrderById_Category=TC_UNIT\nIssueTrainOrderByIdBJ=0,unit,unitcode\n_IssueTrainOrderByIdBJ_Defaults=_,hfoo\n_IssueTrainOrderByIdBJ_Category=TC_UNIT\nIssueUpgradeOrderByIdBJ=0,unit,techcode\n_IssueUpgradeOrderByIdBJ_Defaults=_,Rhde\n_IssueUpgradeOrderByIdBJ_Category=TC_UNIT\nIssueBuildOrderByIdLocBJ=0,unit,unitcode,location\n_IssueBuildOrderByIdLocBJ_Defaults=_,hbar,GetRectCenter\n_IssueBuildOrderByIdLocBJ_Category=TC_UNIT\nUnitDropItemPointLoc=1,unit,item,location\n_UnitDropItemPointLoc_Defaults=_,GetLastCreatedItem,GetRectCenter\n_UnitDropItemPointLoc_Category=TC_UNIT\nUnitDropItemSlotBJ=1,unit,item,integer\n_UnitDropItemSlotBJ_Defaults=_,GetLastCreatedItem,1\n_UnitDropItemSlotBJ_Limits=_,_,_,_,1,6\n_UnitDropItemSlotBJ_Category=TC_UNIT\nUnitDropItemTargetBJ=1,unit,item,unit\n_UnitDropItemTargetBJ_Defaults=_,GetLastCreatedItem,_\n_UnitDropItemTargetBJ_Category=TC_UNIT\nUnitDamagePointLoc=1,unit,real,real,location,real,attacktype,damagetype\n_UnitDamagePointLoc_Defaults=GetTriggerUnit,0,500,GetRectCenter,100,AttackTypeNormal,DamageTypeNormal\n_UnitDamagePointLoc_Category=TC_UNIT\nUnitDamageTargetBJ=1,unit,unit,real,attacktype,damagetype\n_UnitDamageTargetBJ_Defaults=GetTriggerUnit,GetTriggerUnit,500,AttackTypeNormal,DamageTypeNormal\n_UnitDamageTargetBJ_Category=TC_UNIT\nDecUnitAbilityLevelSwapped=1,abilcode,unit\n_DecUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit,1\n_DecUnitAbilityLevelSwapped_Category=TC_UNIT\nIncUnitAbilityLevelSwapped=1,abilcode,unit\n_IncUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_IncUnitAbilityLevelSwapped_Category=TC_UNIT\nSetUnitAbilityLevelSwapped=1,abilcode,unit,integer\n_SetUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_SetUnitAbilityLevelSwapped_Limits=_,_,_,_,1,_\n_SetUnitAbilityLevelSwapped_Category=TC_UNIT\nForGroupMultiple=1,group\n_ForGroupMultiple_Defaults=GetUnitsInRectAll\n_ForGroupMultiple_Category=TC_UNITGROUP\n_ForGroupMultiple_ScriptName=ForGroupBJ\nForGroup=0,group,code\n_ForGroup_Defaults=GetUnitsInRectAll,DoNothing\n_ForGroup_Category=TC_UNITGROUP\n_ForGroup_ScriptName=ForGroupBJ\nGroupAddUnitSimple=0,unit,group\n_GroupAddUnitSimple_Defaults=GetTriggerUnit,_\n_GroupAddUnitSimple_Category=TC_UNITGROUP\nGroupAddGroup=0,group,group\n_GroupAddGroup_Defaults=_,_\n_GroupAddGroup_Category=TC_UNITGROUP\nGroupRemoveUnitSimple=0,unit,group\n_GroupRemoveUnitSimple_Defaults=GetTriggerUnit,_\n_GroupRemoveUnitSimple_Category=TC_UNITGROUP\nGroupRemoveGroup=0,group,group\n_GroupRemoveGroup_Defaults=_,_\n_GroupRemoveGroup_Category=TC_UNITGROUP\nDestroyGroup=0,group\n_DestroyGroup_Defaults=_\n_DestroyGroup_Category=TC_UNITGROUP\nGroupClear=0,group\n_GroupClear_Defaults=_\n_GroupClear_Category=TC_UNITGROUP\nGroupTargetOrder=0,group,unitorderutarg,unit\n_GroupTargetOrder_Defaults=GetUnitsInRectAll,UnitOrderAttackUnit,_\n_GroupTargetOrder_Category=TC_UNITGROUP\n_GroupTargetOrder_ScriptName=GroupTargetOrderBJ\nGroupTargetOrderBJ=0,group,string,unit\n_GroupTargetOrderBJ_Defaults=GetUnitsInRectAll,\"attack\",_\n_GroupTargetOrderBJ_Category=TC_UNITGROUP\n_GroupTargetOrderBJ_ScriptName=GroupTargetOrder\nGroupTargetOrderById=0,group,ordercode,unit\n_GroupTargetOrderById_Defaults=GetUnitsInRectAll,OrderCodeAttackUnit,_\n_GroupTargetOrderById_Category=TC_UNITGROUP\nGroupPointOrderLoc=0,group,unitorderptarg,location\n_GroupPointOrderLoc_Defaults=GetUnitsInRectAll,UnitOrderMove,GetRectCenter\n_GroupPointOrderLoc_Category=TC_UNITGROUP\n_GroupPointOrderLoc_ScriptName=GroupPointOrderLocBJ\nGroupPointOrderLocBJ=0,group,string,location\n_GroupPointOrderLocBJ_Defaults=GetUnitsInRectAll,\"move\",GetRectCenter\n_GroupPointOrderLocBJ_Category=TC_UNITGROUP\n_GroupPointOrderLocBJ_ScriptName=GroupPointOrderLoc\nGroupPointOrderByIdLoc=0,group,ordercode,location\n_GroupPointOrderByIdLoc_Defaults=GetUnitsInRectAll,OrderCodeMoveUnit,GetRectCenter\n_GroupPointOrderByIdLoc_Category=TC_UNITGROUP\nGroupTargetDestructableOrder=0,group,unitorderdtarg,destructable\n_GroupTargetDestructableOrder_Defaults=GetUnitsInRectAll,UnitOrderHarvestDestructible,_\n_GroupTargetDestructableOrder_Category=TC_UNITGROUP\nGroupTargetDestructableOrderS=0,group,string,destructable\n_GroupTargetDestructableOrderS_Defaults=GetUnitsInRectAll,\"harvest\",_\n_GroupTargetDestructableOrderS_ScriptName=GroupTargetOrder\n_GroupTargetDestructableOrderS_Category=TC_UNITGROUP\nGroupTargetOrderByIdD=0,group,ordercode,destructable\n_GroupTargetOrderByIdD_Defaults=GetUnitsInRectAll,OrderCodeHarvest,_\n_GroupTargetOrderByIdD_ScriptName=GroupTargetOrderById\n_GroupTargetOrderByIdD_Category=TC_UNITGROUP\nGroupTargetItemOrder=0,group,unitorderitarg,item\n_GroupTargetItemOrder_Defaults=GetUnitsInRectAll,UnitOrderAttackItem,_\n_GroupTargetItemOrder_Category=TC_UNITGROUP\nGroupItemTargetOrderBJ=0,group,string,item\n_GroupItemTargetOrderBJ_Defaults=GetUnitsInRectAll,\"smart\",_\n_GroupItemTargetOrderBJ_Category=TC_UNITGROUP\n_GroupItemTargetOrderBJ_ScriptName=GroupTargetOrder\nGroupItemTargetOrderById=0,group,ordercode,item\n_GroupItemTargetOrderById_Defaults=GetUnitsInRectAll,OrderCodeSmart,_\n_GroupItemTargetOrderById_Category=TC_UNITGROUP\n_GroupItemTargetOrderById_ScriptName=GroupTargetOrderById\nGroupImmediateOrder=0,group,unitordernotarg\n_GroupImmediateOrder_Defaults=GetUnitsInRectAll,UnitOrderStop\n_GroupImmediateOrder_Category=TC_UNITGROUP\n_GroupImmediateOrder_ScriptName=GroupImmediateOrderBJ\nGroupImmediateOrderBJ=0,group,string\n_GroupImmediateOrderBJ_Defaults=GetUnitsInRectAll,\"stop\"\n_GroupImmediateOrderBJ_Category=TC_UNITGROUP\n_GroupImmediateOrderBJ_ScriptName=GroupImmediateOrder\nGroupImmediateOrderById=0,group,ordercode\n_GroupImmediateOrderById_Defaults=GetUnitsInRectAll,OrderCodeStop\n_GroupImmediateOrderById_Category=TC_UNITGROUP\nGroupTrainOrderByIdBJ=0,group,unitcode\n_GroupTrainOrderByIdBJ_Defaults=GetUnitsInRectAll,hfoo\n_GroupTrainOrderByIdBJ_Category=TC_UNITGROUP\nGroupEnumUnitsOfType=1,group,unituiname,boolexpr\n_GroupEnumUnitsOfType_Defaults=_,UnitUINamearchmage,_\n_GroupEnumUnitsOfType_Category=TC_UNITGROUP\nGroupEnumUnitsOfTypeCounted=1,group,unituiname,boolexpr,integer\n_GroupEnumUnitsOfTypeCounted_Defaults=_,UnitUINamearchmage,_,12\n_GroupEnumUnitsOfTypeCounted_Category=TC_UNITGROUP\nGroupEnumUnitsOfPlayer=1,group,player,boolexpr\n_GroupEnumUnitsOfPlayer_Defaults=_,Player00,_\n_GroupEnumUnitsOfPlayer_Category=TC_UNITGROUP\nGroupEnumUnitsInRect=1,group,rect,boolexpr\n_GroupEnumUnitsInRect_Defaults=_,GetEntireMapRect,_\n_GroupEnumUnitsInRect_Category=TC_UNITGROUP\nGroupEnumUnitsInRectCounted=1,group,rect,boolexpr,integer\n_GroupEnumUnitsInRectCounted_Defaults=_,GetEntireMapRect,_,12\n_GroupEnumUnitsInRectCounted_Category=TC_UNITGROUP\nGroupEnumUnitsInRangeOfLoc=1,group,location,real,boolexpr\n_GroupEnumUnitsInRangeOfLoc_Defaults=_,GetRectCenter,500,_\n_GroupEnumUnitsInRangeOfLoc_Category=TC_UNITGROUP\nGroupEnumUnitsInRangeOfLocCounted=1,group,location,real,boolexpr,integer\n_GroupEnumUnitsInRangeOfLocCounted_Defaults=_,GetRectCenter,500,_,12\n_GroupEnumUnitsInRangeOfLocCounted_Category=TC_UNITGROUP\nGroupEnumUnitsSelected=1,group,player,boolexpr\n_GroupEnumUnitsSelected_Defaults=_,Player00,_\n_GroupEnumUnitsSelected_Category=TC_UNITGROUP\nFogEnableOn=0,nothing\n_FogEnableOn_Defaults=\n_FogEnableOn_Category=TC_VISIBILITY\nFogEnableOff=0,nothing\n_FogEnableOff_Defaults=\n_FogEnableOff_Category=TC_VISIBILITY\nFogMaskEnableOn=0,nothing\n_FogMaskEnableOn_Defaults=\n_FogMaskEnableOn_Category=TC_VISIBILITY\nFogMaskEnableOff=0,nothing\n_FogMaskEnableOff_Defaults=\n_FogMaskEnableOff_Category=TC_VISIBILITY\nCreateFogModifierRectBJ=0,enableddisabledoption,player,fogstate,rect\n_CreateFogModifierRectBJ_Defaults=EnabledDisabledEnabled,Player00,FogStateVisible,GetPlayableMapRect\n_CreateFogModifierRectBJ_Category=TC_VISIBILITY\nCreateFogModifierRadiusLocBJ=0,enableddisabledoption,player,fogstate,location,real\n_CreateFogModifierRadiusLocBJ_Defaults=EnabledDisabledEnabled,Player00,FogStateVisible,GetRectCenter,512\n_CreateFogModifierRadiusLocBJ_Defaults=_,_,_,_,_,_,_,_,0,_\n_CreateFogModifierRadiusLocBJ_Category=TC_VISIBILITY\nFogModifierStart=0,fogmodifier\n_FogModifierStart_Defaults=GetLastCreatedFogModifier\n_FogModifierStart_Category=TC_VISIBILITY\nFogModifierStop=0,fogmodifier\n_FogModifierStop_Defaults=GetLastCreatedFogModifier\n_FogModifierStop_Category=TC_VISIBILITY\nDestroyFogModifier=0,fogmodifier\n_DestroyFogModifier_Defaults=GetLastCreatedFogModifier\n_DestroyFogModifier_Category=TC_VISIBILITY\nCreateDestructableZA=0,destructablecode,real,real,real,real,real,integer\n_CreateDestructableZA_Defaults=LTlt,GetLocationX,GetLocationY,0,GetRandomDirectionDeg,1,0\n_CreateDestructableZA_Limits=_,_,_,_,_,_,_,_,_,_,0,_,0,_\n_CreateDestructableZA_ScriptName=CreateDestructableZ\n_CreateDestructableZA_Category=TC_COMPATIBILITY\nCreateDeadDestructableZA=0,destructablecode,real,real,real,real,real,integer\n_CreateDeadDestructableZA_Defaults=LTlt,GetLocationX,GetLocationY,0,GetRandomDirectionDeg,1,0\n_CreateDeadDestructableZA_Limits=_,_,_,_,_,_,_,_,_,_,0,_,0,_\n_CreateDeadDestructableZA_ScriptName=CreateDeadDestructableZ\n_CreateDeadDestructableZA_Category=TC_COMPATIBILITY\nDialogAddButtonWithHotkeyBJ=0,dialog,string,integer\n_DialogAddButtonWithHotkeyBJ_Defaults=_,_,_\n_DialogAddButtonWithHotkeyBJ_Category=TC_COMPATIBILITY\nCreateTrackable=1,modelfile,real,real,real\n_CreateTrackable_Defaults=\"units\\nightelf\\Wisp\\Wisp.mdl\",_,_,0\n_CreateTrackable_Category=TC_COMPATIBILITY\nMultiboardDisplay=1,multiboard,showhideoption\n_MultiboardDisplay_Defaults=CreateMultiboard,ShowHideShow\n_MultiboardDisplay_Category=TC_COMPATIBILITY\nDestroyMultiboard=1,multiboard\n_DestroyMultiboard_Defaults=_\n_DestroyMultiboard_Category=TC_COMPATIBILITY\nMultiboardMinimize=1,multiboard,minimizeoption\n_MultiboardMinimize_Defaults=_,true\n_MultiboardMinimize_Category=TC_COMPATIBILITY\nMultiboardSetTitleTextColor=1,multiboard,integer,integer,integer,integer\n_MultiboardSetTitleTextColor_Defaults=_,100,100,100,0\n_MultiboardSetTitleTextColor_Category=TC_COMPATIBILITY\nMultiboardSetItemsStyle=1,multiboard,showhideoption,showhideoption\n_MultiboardSetItemsStyle_Defaults=_,ShowHideShow,ShowHideShow\n_MultiboardSetItemsStyle_Category=TC_COMPATIBILITY\nMultiboardSetItemsValue=1,multiboard,StringExt\n_MultiboardSetItemsValue_Defaults=_,_\n_MultiboardSetItemsValue_Category=TC_COMPATIBILITY\nMultiboardSetItemsWidth=1,multiboard,real\n_MultiboardSetItemsWidth_Defaults=_,_\n_MultiboardSetItemsWidth_Category=TC_COMPATIBILITY\nMultiboardSetItemsIcon=1,multiboard,imagefile\n_MultiboardSetItemsIcon_Defaults=_,_\n_MultiboardSetItemsIcon_Category=TC_COMPATIBILITY\nMultiboardReleaseItem=1,multiboarditem\n_MultiboardReleaseItem_Defaults=MultiboardGetItem\n_MultiboardReleaseItem_Category=TC_COMPATIBILITY\nMultiboardSetItemStyle=1,multiboarditem,showhideoption,showhideoption\n_MultiboardSetItemStyle_Defaults=_,ShowHideShow,ShowHideShow\n_MultiboardSetItemStyle_Category=TC_COMPATIBILITY\nMultiboardSetItemValue=1,multiboarditem,StringExt\n_MultiboardSetItemValue_Defaults=_,_\n_MultiboardSetItemValue_Category=TC_COMPATIBILITY\nMultiboardSetItemWidth=1,multiboarditem,real\n_MultiboardSetItemWidth_Defaults=_,_\n_MultiboardSetItemWidth_Category=TC_COMPATIBILITY\nMultiboardSetItemIcon=1,multiboarditem,imagefile\n_MultiboardSetItemIcon_Defaults=_,_\n_MultiboardSetItemIcon_Category=TC_COMPATIBILITY\nAddSpellEffectByIdLoc=0,abilcode,effecttype,location\n_AddSpellEffectByIdLoc_Defaults=_,EffectTypeCaster,GetRectCenter\n_AddSpellEffectByIdLoc_Category=TC_COMPATIBILITY\nAddSpellEffectTargetById=0,abilcode,effecttype,unit,string\n_AddSpellEffectTargetById_Defaults=_,EffectTypeCaster,GetLastCreatedUnit,\"overhead\"\n_AddSpellEffectTargetById_Category=TC_COMPATIBILITY\nAddSpellEffectByIdLocB=0,buffcode,effecttypebuff,location\n_AddSpellEffectByIdLocB_Defaults=_,EffectTypeTargetBuff,GetRectCenter\n_AddSpellEffectByIdLocB_Category=TC_COMPATIBILITY\n_AddSpellEffectByIdLocB_ScriptName=AddSpellEffectByIdLoc\nAddSpellEffectTargetByIdB=0,buffcode,effecttypebuff,unit,string\n_AddSpellEffectTargetByIdB_Defaults=_,EffectTypeTargetBuff,GetLastCreatedUnit,\"overhead\"\n_AddSpellEffectTargetByIdB_Category=TC_COMPATIBILITY\n_AddSpellEffectTargetByIdB_ScriptName=AddSpellEffectTargetById\nUnitApplyTimedLife=0,unit,integer,integer\n_UnitApplyTimedLife_Defaults=GetLastCreatedUnit,1,60\n_UnitApplyTimedLife_Category=TC_COMPATIBILITY\nIssueItemTargetOrder=0,unit,unitorderitarg,item\n_IssueItemTargetOrder_Defaults=_,ItemOrderPickUp,_\n_IssueItemTargetOrder_Category=TC_COMPATIBILITY\n_IssueItemTargetOrder_ScriptName=IssueTargetOrderBJ\nGroupItemTargetOrder=0,group,unitorderitarg,item\n_GroupItemTargetOrder_Defaults=GetUnitsInRectAll,ItemOrderPickUp,_\n_GroupItemTargetOrder_Category=TC_COMPATIBILITY\n_GroupItemTargetOrder_ScriptName=GroupTargetOrder\n[TriggerCalls]\nIsDestructableAliveBJ=0,0,boolean,destructable\n_IsDestructableAliveBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableAliveBJ_Category=TC_DESTRUCT\nIsDestructableDeadBJ=0,0,boolean,destructable\n_IsDestructableDeadBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableDeadBJ_Category=TC_DESTRUCT\nIsDestructableInvulnerableBJ=0,0,boolean,destructable\n_IsDestructableInvulnerableBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableInvulnerableBJ_Category=TC_DESTRUCT\nIsPointBlightedBJ=1,1,boolean,location\n_IsPointBlightedBJ_Defaults=GetRectCenter\n_IsPointBlightedBJ_Category=TC_ENVIRONMENT\nIsMapFlagSet=0,1,boolean,mapflag\n_IsMapFlagSet_Defaults=MapFlagUseHandicaps\n_IsMapFlagSet_Category=TC_GAME\nIsCustomCampaignButtonVisibile=1,0,boolean,integer\n_IsCustomCampaignButtonVisibile_Defaults=1\n_IsCustomCampaignButtonVisibile_Limits=1,_\n_IsCustomCampaignButtonVisibile_Category=TC_GAME\nGetCreepCampFilterState=1,1,boolean\n_GetCreepCampFilterState_Category=TC_GAME\nSaveGameExists=1,0,boolean,anyfile\n_SaveGameExists_Defaults=_\n_SaveGameExists_Category=TC_GAME\nGetStoredBooleanBJ=0,0,boolean,string,string,gamecache\n_GetStoredBooleanBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredBooleanBJ_Category=TC_GAMECACHE\nHaveStoredValue=1,0,boolean,string,cachevaluetype,string,gamecache\n_HaveStoredValue_Defaults=_,CacheValueTypeUnit,\"Category\",GetLastCreatedGameCacheBJ\n_HaveStoredValue_Category=TC_GAMECACHE\nUnitHasItem=0,1,boolean,unit,item\n_UnitHasItem_Defaults=GetTriggerUnit,GetLastCreatedItem\n_UnitHasItem_Category=TC_HERO\nUnitHasItemOfTypeBJ=0,1,boolean,unit,itemcode\n_UnitHasItemOfTypeBJ_Defaults=GetTriggerUnit,texp\n_UnitHasItemOfTypeBJ_Category=TC_HERO\nIsSuspendedXP=0,0,boolean,unit\n_IsSuspendedXP_Defaults=GetTriggerUnit\n_IsSuspendedXP_Category=TC_HERO\nCheckItemStatus=1,0,boolean,item,itemstatus\n_CheckItemStatus_Defaults=GetLastCreatedItem,ItemStatusHidden\n_CheckItemStatus_Category=TC_ITEM\nCheckItemcodeStatus=1,0,boolean,itemcode,itemcodestatus\n_CheckItemcodeStatus_Defaults=GetItemTypeId,ItemcodeStatusPowerup\n_CheckItemcodeStatus_Category=TC_ITEM\nIsItemHiddenBJ=1,0,boolean,item\n_IsItemHiddenBJ_Defaults=GetLastCreatedItem\n_IsItemHiddenBJ_Category=TC_ITEM\nIsItemOwned=1,0,boolean,item\n_IsItemOwned_Defaults=GetLastCreatedItem\n_IsItemOwned_Category=TC_ITEM\nRectContainsItem=1,1,boolean,item,rect\n_RectContainsItem_Defaults=GetLastCreatedItem,GetRectCenter\n_RectContainsItem_Category=TC_ITEM\nIsItemInvulnerable=0,0,boolean,item\n_IsItemInvulnerable_Defaults=GetLastCreatedItem\n_IsItemInvulnerable_Category=TC_ITEM\nLeaderboardHasPlayerItemBJ=0,0,boolean,leaderboard,player\n_LeaderboardHasPlayerItemBJ_Defaults=GetLastCreatedLeaderboard,Player00\n_LeaderboardHasPlayerItemBJ_Category=TC_LEADERBOARD\nIsMultiboardDisplayed=1,0,boolean,multiboard\n_IsMultiboardDisplayed_Defaults=GetLastCreatedMultiboard\n_IsMultiboardDisplayed_Category=TC_MULTIBOARD\nIsMultiboardMinimized=1,0,boolean,multiboard\n_IsMultiboardMinimized_Defaults=GetLastCreatedMultiboard\n_IsMultiboardMinimized_Category=TC_MULTIBOARD\nWaygateIsActiveBJ=0,0,boolean,unit\n_WaygateIsActiveBJ_Defaults=_\n_WaygateIsActiveBJ_Category=TC_NEUTRALBUILDING\nIsPlayerFlagSetBJ=0,0,boolean,playerflag,player\n_IsPlayerFlagSetBJ_Defaults=PlayerFlagGivesBounty,PlayerNA\n_IsPlayerFlagSetBJ_Category=TC_PLAYER\nIsPlayerAlly=0,1,boolean,player,player\n_IsPlayerAlly_Defaults=GetTriggerPlayer,Player00\n_IsPlayerAlly_Category=TC_PLAYER\nIsPlayerEnemy=0,1,boolean,player,player\n_IsPlayerEnemy_Defaults=GetTriggerPlayer,Player00\n_IsPlayerEnemy_Category=TC_PLAYER\nGetPlayerAlliance=0,1,boolean,player,player,alliancetype\n_GetPlayerAlliance_Defaults=GetTriggerPlayer,Player00,AllianceTypePassive\n_GetPlayerAlliance_Category=TC_PLAYER\nIsPlayerInForce=0,1,boolean,player,force\n_IsPlayerInForce_Defaults=Player00,GetPlayersAll\n_IsPlayerInForce_Category=TC_PLAYER\nIsQuestItemCompleted=0,0,boolean,questitem\n_IsQuestItemCompleted_Defaults=GetLastCreatedQuestItemBJ\n_IsQuestItemCompleted_Category=TC_QUEST\nIsQuestEnabled=0,0,boolean,quest\n_IsQuestEnabled_Defaults=GetLastCreatedQuestBJ\n_IsQuestEnabled_Category=TC_QUEST\nIsQuestCompleted=0,0,boolean,quest\n_IsQuestCompleted_Defaults=GetLastCreatedQuestBJ\n_IsQuestCompleted_Category=TC_QUEST\nIsQuestFailed=0,0,boolean,quest\n_IsQuestFailed_Defaults=GetLastCreatedQuestBJ\n_IsQuestFailed_Category=TC_QUEST\nIsQuestDiscovered=0,0,boolean,quest\n_IsQuestDiscovered_Defaults=GetLastCreatedQuestBJ\n_IsQuestDiscovered_Category=TC_QUEST\nIsQuestRequired=0,0,boolean,quest\n_IsQuestRequired_Defaults=GetLastCreatedQuestBJ\n_IsQuestRequired_Category=TC_QUEST\nRectContainsLoc=0,1,boolean,rect,location\n_RectContainsLoc_Defaults=GetPlayableMapRect,GetRectCenter\n_RectContainsLoc_Category=TC_REGION\nIsTriggerEnabled=0,1,boolean,trigger\n_IsTriggerEnabled_Defaults=GetTriggeringTrigger\n_IsTriggerEnabled_Category=TC_TRIGGER\nTriggerEvaluate=0,1,boolean,trigger\n_TriggerEvaluate_Defaults=_\n_TriggerEvaluate_Category=TC_TRIGGER\nIsTriggerQueuedBJ=0,0,boolean,trigger\n_IsTriggerQueuedBJ_Defaults=_\n_IsTriggerQueuedBJ_Category=TC_TRIGGER\nIsTriggerQueueEmptyBJ=0,0,boolean\n_IsTriggerQueueEmptyBJ_Defaults=\n_IsTriggerQueueEmptyBJ_Category=TC_TRIGGER\nIsUnitType=0,1,boolean,unit,unittype\n_IsUnitType_Defaults=GetTriggerUnit,UnitTypeStructure\n_IsUnitType_Category=TC_UNIT\nIsUnitIdType=1,1,boolean,unitcode,unittype\n_IsUnitIdType_Defaults=GetUnitTypeId,UnitTypeStructure\n_IsUnitIdType_Category=TC_UNIT\nIsUnitInGroup=0,1,boolean,unit,group\n_IsUnitInGroup_Defaults=GetTriggerUnit,GetUnitsInRectAll\n_IsUnitInGroup_Category=TC_UNIT\nRectContainsUnit=0,1,boolean,rect,unit\n_RectContainsUnit_Defaults=GetPlayableMapRect,GetTriggerUnit\n_RectContainsUnit_Category=TC_UNIT\nIsUnitAliveBJ=0,0,boolean,unit\n_IsUnitAliveBJ_Defaults=GetTriggerUnit\n_IsUnitAliveBJ_Category=TC_UNIT\nIsUnitDeadBJ=0,0,boolean,unit\n_IsUnitDeadBJ_Defaults=GetTriggerUnit\n_IsUnitDeadBJ_Category=TC_UNIT\nIsUnitPausedBJ=0,0,boolean,unit\n_IsUnitPausedBJ_Defaults=GetTriggerUnit\n_IsUnitPausedBJ_Category=TC_UNIT\nIsUnitHiddenBJ=0,0,boolean,unit\n_IsUnitHiddenBJ_Defaults=GetTriggerUnit\n_IsUnitHiddenBJ_Category=TC_UNIT\nIsUnitIllusionBJ=0,0,boolean,unit\n_IsUnitIllusionBJ_Defaults=GetTriggerUnit\n_IsUnitIllusionBJ_Category=TC_UNIT\nUnitCanSleepPerm=0,0,boolean,unit\n_UnitCanSleepPerm_Defaults=GetTriggerUnit\n_UnitCanSleepPerm_Category=TC_UNIT\nUnitCanSleepBJ=0,0,boolean,unit\n_UnitCanSleepBJ_Defaults=GetTriggerUnit\n_UnitCanSleepBJ_Category=TC_UNIT\nUnitIsSleepingBJ=0,0,boolean,unit\n_UnitIsSleepingBJ_Defaults=GetTriggerUnit\n_UnitIsSleepingBJ_Category=TC_UNIT\nDoesUnitGenerateAlarms=1,0,boolean,unit\n_DoesUnitGenerateAlarms_Defaults=GetTriggerUnit\n_DoesUnitGenerateAlarms_Category=TC_UNIT\nIsUnitLoadedBJ=0,0,boolean,unit\n_IsUnitLoadedBJ_Defaults=GetTriggerUnit\n_IsUnitLoadedBJ_Category=TC_UNIT\nIsUnitInTransportBJ=0,0,boolean,unit,unit\n_IsUnitInTransportBJ_Defaults=GetTriggerUnit,_\n_IsUnitInTransportBJ_Category=TC_UNIT\nIsUnitSelected=0,1,boolean,unit,player\n_IsUnitSelected_Defaults=GetTriggerUnit,Player00\n_IsUnitSelected_Category=TC_UNIT\nIsUnitAlly=0,1,boolean,unit,player\n_IsUnitAlly_Defaults=GetTriggerUnit,Player00\n_IsUnitAlly_Category=TC_UNIT\nIsUnitEnemy=0,1,boolean,unit,player\n_IsUnitEnemy_Defaults=GetTriggerUnit,Player00\n_IsUnitEnemy_Category=TC_UNIT\nUnitHasBuffBJ=1,1,boolean,unit,buffcode\n_UnitHasBuffBJ_Defaults=GetTriggerUnit,_\n_UnitHasBuffBJ_Category=TC_UNIT\nIsUnitGroupEmptyBJ=0,1,boolean,group\n_IsUnitGroupEmptyBJ_Defaults=_\n_IsUnitGroupEmptyBJ_Category=TC_UNITGROUP\nIsUnitGroupInRectBJ=0,1,boolean,group,rect\n_IsUnitGroupInRectBJ_Defaults=_\n_IsUnitGroupInRectBJ_Category=TC_UNITGROUP\nIsUnitGroupDeadBJ=0,1,boolean,group\n_IsUnitGroupDeadBJ_Defaults=_\n_IsUnitGroupDeadBJ_Category=TC_UNITGROUP\nIsFogEnabled=0,1,boolean\n_IsFogEnabled_Defaults=\n_IsFogEnabled_Category=TC_VISIBILITY\nIsFogMaskEnabled=0,1,boolean\n_IsFogMaskEnabled_Defaults=\n_IsFogMaskEnabled_Category=TC_VISIBILITY\nIsUnitVisible=0,1,boolean,unit,player\n_IsUnitVisible_Defaults=GetTriggerUnit,Player00\n_IsUnitVisible_Category=TC_VISIBILITY\nIsUnitInvisible=0,1,boolean,unit,player\n_IsUnitInvisible_Defaults=GetTriggerUnit,Player00\n_IsUnitInvisible_Category=TC_VISIBILITY\nIsUnitFogged=0,1,boolean,unit,player\n_IsUnitFogged_Defaults=GetTriggerUnit,Player00\n_IsUnitFogged_Category=TC_VISIBILITY\nIsUnitMasked=0,1,boolean,unit,player\n_IsUnitMasked_Defaults=GetTriggerUnit,Player00\n_IsUnitMasked_Category=TC_VISIBILITY\nIsLocationVisibleToPlayer=0,1,boolean,location,player\n_IsLocationVisibleToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationVisibleToPlayer_Category=TC_VISIBILITY\nIsLocationFoggedToPlayer=0,1,boolean,location,player\n_IsLocationFoggedToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationFoggedToPlayer_Category=TC_VISIBILITY\nIsLocationMaskedToPlayer=0,1,boolean,location,player\n_IsLocationMaskedToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationMaskedToPlayer_Category=TC_VISIBILITY\nOperatorInt=0,1,integer,integer,ArithmeticOperator,integer\n_OperatorInt_Defaults=_,OperatorAdd,1\n_OperatorInt_Category=TC_ARITHMETIC\n_OperatorInt_UseWithAI=1\nGetForLoopIndexA=0,0,integer\n_GetForLoopIndexA_Defaults=\n_GetForLoopIndexA_Category=TC_FORLOOP\nGetForLoopIndexB=0,0,integer\n_GetForLoopIndexB_Defaults=\n_GetForLoopIndexB_Category=TC_FORLOOP\nStringLength=1,1,integer,string\n_StringLength_Defaults=GetEventPlayerChatString\n_StringLength_Category=TC_NOTHING\nR2I=0,1,integer,real\n_R2I_Defaults=GetUnitStateSwap\n_R2I_Category=TC_CONVERSION\nS2I=0,1,integer,string\n_S2I_Defaults=GetEventPlayerChatString\n_S2I_Category=TC_CONVERSION\nGetElevatorHeight=1,1,integer,destructable\n_GetElevatorHeight_Defaults=_\n_GetElevatorHeight_Category=TC_DESTRUCT\nGetTerrainCliffLevelBJ=1,1,integer,location\n_GetTerrainCliffLevelBJ_Defaults=GetRectCenter\n_GetTerrainCliffLevelBJ_Category=TC_ENVIRONMENT\nGetTerrainTypeBJ=1,1,terraintype,location\n_GetTerrainTypeBJ_Defaults=GetRectCenter\n_GetTerrainTypeBJ_Category=TC_ENVIRONMENT\nGetTerrainVarianceBJ=1,1,integer,location\n_GetTerrainVarianceBJ_Defaults=GetRectCenter\n_GetTerrainVarianceBJ_Category=TC_ENVIRONMENT\nIsTerrainPathableBJ=1,1,integer,location,pathingtype\n_IsTerrainPathableBJ_Defaults=GetRectCenter,PathingTypeAny\n_IsTerrainPathableBJ_Category=TC_ENVIRONMENT\nGetLearnedSkillLevel=0,0,integer\n_GetLearnedSkillLevel_Defaults=\n_GetLearnedSkillLevel_Category=TC_EVENTRESPONSE\nGetPlayers=0,1,integer\n_GetPlayers_Defaults=\n_GetPlayers_Category=TC_GAME\nGetTeams=0,1,integer\n_GetTeams_Defaults=\n_GetTeams_Category=TC_GAME\nGetAllyColorFilterState=1,1,integer\n_GetAllyColorFilterState_Defaults=\n_GetAllyColorFilterState_Category=TC_GAME\nGetTournamentFinishNowRule=1,0,integer\n_GetTournamentFinishNowRule_Defaults=\n_GetTournamentFinishNowRule_Category=TC_GAME\nGetTournamentScore=1,0,integer,player\n_GetTournamentScore_Defaults=Player00\n_GetTournamentScore_Category=TC_GAME\nGetStoredIntegerBJ=0,0,integer,string,string,gamecache\n_GetStoredIntegerBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredIntegerBJ_Category=TC_GAMECACHE\nGetHeroLevel=0,1,integer,unit\n_GetHeroLevel_Defaults=GetTriggerUnit\n_GetHeroLevel_Category=TC_HERO\nGetHeroXP=0,1,integer,unit\n_GetHeroXP_Defaults=GetTriggerUnit\n_GetHeroXP_Category=TC_HERO\nGetHeroStatBJ=1,1,integer,herostat,unit,includeoption\n_GetHeroStatBJ_Defaults=HeroStatStr,_,InclusionExclude\n_GetHeroStatBJ_Category=TC_HERO\nGetHeroSkillPoints=1,1,integer,unit\n_GetHeroSkillPoints_Defaults=_\n_GetHeroSkillPoints_Category=TC_HERO\nGetItemLevel=1,1,integer,item\n_GetItemLevel_Defaults=GetLastCreatedItem\n_GetItemLevel_Category=TC_ITEM\nGetItemCharges=1,1,integer,item\n_GetItemCharges_Defaults=GetLastCreatedItem\n_GetItemCharges_Category=TC_ITEM\nGetItemUserData=1,1,integer,item\n_GetItemUserData_Defaults=_\n_GetItemUserData_Category=TC_ITEM\nLeaderboardGetPlayerIndexBJ=0,0,integer,player,leaderboard\n_LeaderboardGetPlayerIndexBJ_Defaults=Player00,GetLastCreatedLeaderboard\n_LeaderboardGetPlayerIndexBJ_Category=TC_LEADERBOARD\nGetRandomInt=0,1,integer,integer,integer\n_GetRandomInt_Defaults=1,10\n_GetRandomInt_Category=TC_MATH\nIMinBJ=0,1,integer,integer,integer\n_IMinBJ_Defaults=_,_\n_IMinBJ_Category=TC_MATH\nIMaxBJ=0,1,integer,integer,integer\n_IMaxBJ_Defaults=_,_\n_IMaxBJ_Category=TC_MATH\nIAbsBJ=0,1,integer,integer\n_IAbsBJ_Defaults=_\n_IAbsBJ_Category=TC_MATH\nISignBJ=0,1,integer,integer\n_ISignBJ_Defaults=_\n_ISignBJ_Category=TC_MATH\nModuloInteger=0,1,integer,integer,integer\n_ModuloInteger_Defaults=_,_\n_ModuloInteger_Category=TC_MATH\nMultiboardGetRowCount=1,1,integer,multiboard\n_MultiboardGetRowCount_Defaults=GetLastCreatedMultiboard\n_MultiboardGetRowCount_Category=TC_MULTIBOARD\nMultiboardGetColumnCount=1,1,integer,multiboard\n_MultiboardGetColumnCount_Defaults=GetLastCreatedMultiboard\n_MultiboardGetColumnCount_Category=TC_MULTIBOARD\nGetResourceAmount=0,1,integer,unit\n_GetResourceAmount_Defaults=_\n_GetResourceAmount_Category=TC_NEUTRALBUILDING\nGetPlayerState=0,1,integer,player,playerstate\n_GetPlayerState_Defaults=Player00,PlayerStateGold\n_GetPlayerState_Category=TC_PLAYER\nGetPlayerTaxRateBJ=1,1,integer,playerresource,player,player\n_GetPlayerTaxRateBJ_Defaults=PlayerResourceGold,Player00,Player01\n_GetPlayerTaxRateBJ_Category=TC_PLAYER\nGetPlayerScore=1,1,integer,player,playerscore\n_GetPlayerScore_Defaults=Player00,PlayerScoreTotal\n_GetPlayerScore_Category=TC_PLAYER\nGetConvertedPlayerId=0,1,integer,player\n_GetConvertedPlayerId_Defaults=GetTriggerPlayer\n_GetConvertedPlayerId_Category=TC_PLAYER\nGetPlayerStructureCount=0,1,integer,player,includeoption\n_GetPlayerStructureCount_Defaults=Player00,InclusionExclude\n_GetPlayerStructureCount_Category=TC_PLAYER\nGetPlayerUnitCount=0,1,integer,player,includeoption\n_GetPlayerUnitCount_Defaults=Player00,InclusionExclude\n_GetPlayerUnitCount_Category=TC_PLAYER\nGetPlayerTechCountSimple=0,1,integer,techcode,player\n_GetPlayerTechCountSimple_Defaults=_,Player00\n_GetPlayerTechCountSimple_Category=TC_PLAYER\nGetPlayerTechMaxAllowedSwap=0,1,integer,techcode,player\n_GetPlayerTechMaxAllowedSwap_Defaults=_,Player00\n_GetPlayerTechMaxAllowedSwap_Category=TC_PLAYER\nGetPlayerTeam=0,1,integer,player\n_GetPlayerTeam_Defaults=Player00\n_GetPlayerTeam_Category=TC_PLAYER\nCountPlayersInForceBJ=0,1,integer,force\n_CountPlayersInForceBJ_Defaults=GetPlayersByMapControl\n_CountPlayersInForceBJ_Category=TC_PLAYER\nCountUnitsInGroup=0,1,integer,group\n_CountUnitsInGroup_Defaults=GetUnitsInRectAll\n_CountUnitsInGroup_Category=TC_UNIT\nCountLivingPlayerUnitsOfTypeId=1,1,integer,unitcode,player\n_CountLivingPlayerUnitsOfTypeId_Defaults=hfoo,Player00\n_CountLivingPlayerUnitsOfTypeId_Category=TC_UNIT\nGetUnitFoodUsed=0,1,integer,unit\n_GetUnitFoodUsed_Defaults=GetTriggerUnit\n_GetUnitFoodUsed_Category=TC_UNIT\nGetUnitFoodMade=0,1,integer,unit\n_GetUnitFoodMade_Defaults=GetTriggerUnit\n_GetUnitFoodMade_Category=TC_UNIT\nGetFoodUsed=1,1,integer,unitcode\n_GetFoodUsed_Defaults=hfoo\n_GetFoodUsed_Category=TC_UNIT\nGetFoodMade=0,1,integer,unitcode\n_GetFoodMade_Defaults=hfoo\n_GetFoodMade_Category=TC_UNIT\nGetUnitPointValue=0,1,integer,unit\n_GetUnitPointValue_Defaults=GetTriggerUnit\n_GetUnitPointValue_Category=TC_UNIT\nGetUnitPointValueByType=0,1,integer,unitcode\n_GetUnitPointValueByType_Defaults=hfoo\n_GetUnitPointValueByType_Category=TC_UNIT\nGetUnitUserData=1,1,integer,unit\n_GetUnitUserData_Defaults=_\n_GetUnitUserData_Category=TC_UNIT\nGetUnitLevel=1,1,integer,unit\n_GetUnitLevel_Defaults=GetTriggerUnit\n_GetUnitLevel_Category=TC_UNIT\nGetUnitAbilityLevelSwapped=1,1,integer,abilcode,unit\n_GetUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_GetUnitAbilityLevelSwapped_Category=TC_UNIT\nUnitInventoryCount=1,1,integer,unit\n_UnitInventoryCount_Defaults=GetTriggerUnit\n_UnitInventoryCount_Category=TC_UNIT\nUnitCountBuffsExBJ=1,1,integer,buffpolarity,buffresist,unit,includeoption,includeoption\n_UnitCountBuffsExBJ_Defaults=BuffPolarityEither,BuffResistEither,GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitCountBuffsExBJ_Category=TC_UNIT\nGetTriggerEvalCount=0,1,integer,trigger\n_GetTriggerEvalCount_Defaults=GetTriggeringTrigger\n_GetTriggerEvalCount_Category=TC_TRIGGER\nGetTriggerExecCount=0,1,integer,trigger\n_GetTriggerExecCount_Defaults=GetTriggeringTrigger\n_GetTriggerExecCount_Category=TC_TRIGGER\nQueuedTriggerCountBJ=0,0,integer\n_QueuedTriggerCountBJ_Defaults=\n_QueuedTriggerCountBJ_Category=TC_TRIGGER\nOperatorReal=0,1,real,real,ArithmeticOperator,real\n_OperatorReal_Defaults=1,OperatorAdd,1\n_OperatorReal_Category=TC_ARITHMETIC\nGetLocationX=0,1,real,location\n_GetLocationX_Defaults=GetRectCenter\n_GetLocationX_Category=TC_NOTHING\nGetLocationY=0,1,real,location\n_GetLocationY_Defaults=GetRectCenter\n_GetLocationY_Category=TC_NOTHING\nCameraSetupGetFieldSwap=0,1,real,camerafield,camerasetup\n_CameraSetupGetFieldSwap_Defaults=CameraFieldTargetDistance,_\n_CameraSetupGetFieldSwap_Category=TC_CAMERA\nGetCameraField=0,1,real,camerafield\n_GetCameraField_Defaults=CameraFieldTargetDistance\n_GetCameraField_Category=TC_CAMERA\nGetCameraTargetPositionX=0,1,real\n_GetCameraTargetPositionX_Defaults=\n_GetCameraTargetPositionX_Category=TC_CAMERA\nGetCameraTargetPositionY=0,1,real\n_GetCameraTargetPositionY_Defaults=\n_GetCameraTargetPositionY_Category=TC_CAMERA\nGetCameraTargetPositionZ=0,1,real\n_GetCameraTargetPositionZ_Defaults=\n_GetCameraTargetPositionZ_Category=TC_CAMERA\nGetCameraEyePositionX=0,1,real\n_GetCameraEyePositionX_Defaults=\n_GetCameraEyePositionX_Category=TC_CAMERA\nGetCameraEyePositionY=0,1,real\n_GetCameraEyePositionY_Defaults=\n_GetCameraEyePositionY_Category=TC_CAMERA\nGetCameraEyePositionZ=0,1,real\n_GetCameraEyePositionZ_Defaults=\n_GetCameraEyePositionZ_Category=TC_CAMERA\nGetLastTransmissionDurationBJ=0,1,real\n_GetLastTransmissionDurationBJ_Defaults=\n_GetLastTransmissionDurationBJ_Category=TC_CINEMATIC\nI2R=0,1,real,integer\n_I2R_Defaults=GetUnitPointValueByType\n_I2R_Category=TC_CONVERSION\nS2R=0,1,real,string\n_S2R_Defaults=GetEventPlayerChatString\n_S2R_Category=TC_CONVERSION\nDeg2Rad=0,1,real,real\n_Deg2Rad_Defaults=0\n_Deg2Rad_Category=TC_CONVERSION\nRad2Deg=0,1,real,real\n_Rad2Deg_Defaults=0\n_Rad2Deg_Category=TC_CONVERSION\nTimerGetElapsed=0,1,real,timer\n_TimerGetElapsed_Defaults=_\n_TimerGetElapsed_Category=TC_TIMER\nTimerGetRemaining=0,1,real,timer\n_TimerGetRemaining_Defaults=_\n_TimerGetRemaining_Category=TC_TIMER\nTimerGetTimeout=0,1,real,timer\n_TimerGetTimeout_Defaults=_\n_TimerGetTimeout_Category=TC_TIMER\nGetDestructableLife=0,1,real,destructable\n_GetDestructableLife_Defaults=GetLastCreatedDestructable\n_GetDestructableLife_Category=TC_DESTRUCT\nGetDestructableMaxLife=0,1,real,destructable\n_GetDestructableMaxLife_Defaults=GetLastCreatedDestructable\n_GetDestructableMaxLife_Category=TC_DESTRUCT\nGetDestructableOccluderHeight=1,1,real,destructable\n_GetDestructableOccluderHeight_Defaults=GetLastCreatedDestructable\n_GetDestructableOccluderHeight_Category=TC_DESTRUCT\nGetEventDamage=0,0,real\n_GetEventDamage_Defaults=\n_GetEventDamage_Category=TC_EVENTRESPONSE\nGetTournamentFinishSoonTimeRemaining=1,0,real\n_GetTournamentFinishSoonTimeRemaining_Defaults=\n_GetTournamentFinishSoonTimeRemaining_Category=TC_EVENTRESPONSE\nGetTimeOfDay=0,1,real\n_GetTimeOfDay_Defaults=\n_GetTimeOfDay_Category=TC_GAME\nGetTimeOfDayScalePercentBJ=0,1,real\n_GetTimeOfDayScalePercentBJ_Defaults=\n_GetTimeOfDayScalePercentBJ_Category=TC_GAME\nGetStoredRealBJ=0,0,real,string,string,gamecache\n_GetStoredRealBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredRealBJ_Category=TC_GAMECACHE\nGetItemLifeBJ=0,0,real,item\n_GetItemLifeBJ_Defaults=GetLastCreatedItem\n_GetItemLifeBJ_Category=TC_ITEM\nGetRandomReal=0,1,real,real,real\n_GetRandomReal_Defaults=0,1\n_GetRandomReal_Category=TC_MATH\nGetRandomDirectionDeg=0,1,real\n_GetRandomDirectionDeg_Defaults=\n_GetRandomDirectionDeg_Category=TC_MATH\nGetRandomPercentageBJ=0,1,real\n_GetRandomPercentageBJ_Defaults=\n_GetRandomPercentageBJ_Category=TC_MATH\nDistanceBetweenPoints=0,1,real,location,location\n_DistanceBetweenPoints_Defaults=GetUnitLoc,GetUnitLoc\n_DistanceBetweenPoints_Category=TC_MATH\nAngleBetweenPoints=0,1,real,location,location\n_AngleBetweenPoints_Defaults=GetUnitLoc,GetUnitLoc\n_AngleBetweenPoints_Category=TC_MATH\nRMinBJ=0,1,real,real,real\n_RMinBJ_Defaults=_,_\n_RMinBJ_Category=TC_MATH\nRMaxBJ=0,1,real,real,real\n_RMaxBJ_Defaults=_,_\n_RMaxBJ_Category=TC_MATH\nRAbsBJ=0,1,real,real\n_RAbsBJ_Defaults=_\n_RAbsBJ_Category=TC_MATH\nRSignBJ=0,1,real,real\n_RSignBJ_Defaults=_\n_RSignBJ_Category=TC_MATH\nModuloReal=0,1,real,real,real\n_ModuloReal_Defaults=_,_\n_ModuloReal_Category=TC_MATH\nPow=0,1,real,real,real\n_Pow_Defaults=_,_\n_Pow_Category=TC_MATH\nSquareRoot=0,1,real,real\n_SquareRoot_Defaults=_\n_SquareRoot_Limits=0,_\n_SquareRoot_Category=TC_MATH\nSinBJ=0,1,real,real\n_SinBJ_Defaults=GetUnitFacing\n_SinBJ_Category=TC_MATH\nCosBJ=0,1,real,real\n_CosBJ_Defaults=GetUnitFacing\n_CosBJ_Category=TC_MATH\nTanBJ=0,1,real,real\n_TanBJ_Defaults=GetUnitFacing\n_TanBJ_Category=TC_MATH\nAsinBJ=0,1,real,real\n_AsinBJ_Defaults=_\n_AsinBJ_Limits=-1,1\n_AsinBJ_Category=TC_MATH\nAcosBJ=0,1,real,real\n_AcosBJ_Defaults=_\n_AcosBJ_Limits=-1,1\n_AcosBJ_Category=TC_MATH\nAtanBJ=0,1,real,real\n_AtanBJ_Defaults=_\n_AtanBJ_Category=TC_MATH\nAtan2BJ=0,1,real,real,real\n_Atan2BJ_Defaults=_,_\n_Atan2BJ_Category=TC_MATH\nGetPlayerHandicapXPBJ=0,0,real,player\n_GetPlayerHandicapXPBJ_Defaults=Player00\n_GetPlayerHandicapXPBJ_Category=TC_PLAYER\nGetPlayerHandicapBJ=0,0,real,player\n_GetPlayerHandicapBJ_Defaults=Player00\n_GetPlayerHandicapBJ_Category=TC_PLAYER\nGetLocationZ=1,1,real,location\n_GetLocationZ_Defaults=GetUnitLoc\n_GetLocationZ_Category=TC_LOCATION\nGetRectCenterX=0,1,real,rect\n_GetRectCenterX_Defaults=GetPlayableMapRect\n_GetRectCenterX_Category=TC_REGION\nGetRectCenterY=0,1,real,rect\n_GetRectCenterY_Defaults=GetPlayableMapRect\n_GetRectCenterY_Category=TC_REGION\nGetRectMinX=0,1,real,rect\n_GetRectMinX_Defaults=GetPlayableMapRect\n_GetRectMinX_Category=TC_REGION\nGetRectMinY=0,1,real,rect\n_GetRectMinY_Defaults=GetPlayableMapRect\n_GetRectMinY_Category=TC_REGION\nGetRectMaxX=0,1,real,rect\n_GetRectMaxX_Defaults=GetPlayableMapRect\n_GetRectMaxX_Category=TC_REGION\nGetRectMaxY=0,1,real,rect\n_GetRectMaxY_Defaults=GetPlayableMapRect\n_GetRectMaxY_Category=TC_REGION\nGetRectWidthBJ=0,1,real,rect\n_GetRectWidthBJ_Defaults=_\n_GetRectWidthBJ_Category=TC_REGION\nGetRectHeightBJ=0,1,real,rect\n_GetRectHeightBJ_Defaults=_\n_GetRectHeightBJ_Category=TC_REGION\nGetSoundDurationBJ=0,1,real,sound\n_GetSoundDurationBJ_Defaults=GetLastPlayedSound\n_GetSoundDurationBJ_Category=TC_SOUND\nGetSoundFileDurationBJ=0,1,real,musicfile\n_GetSoundFileDurationBJ_Defaults=GetLastPlayedMusic\n_GetSoundFileDurationBJ_Category=TC_SOUND\nGetUnitStateSwap=0,1,real,unitstate,unit\n_GetUnitStateSwap_Defaults=UnitStateLife,GetTriggerUnit\n_GetUnitStateSwap_Category=TC_UNIT\nGetUnitLifePercent=1,1,real,unit\n_GetUnitLifePercent_Defaults=GetTriggerUnit\n_GetUnitLifePercent_Category=TC_UNIT\nGetUnitManaPercent=1,1,real,unit\n_GetUnitManaPercent_Defaults=GetTriggerUnit\n_GetUnitManaPercent_Category=TC_UNIT\nGetUnitFacing=0,1,real,unit\n_GetUnitFacing_Defaults=GetTriggerUnit\n_GetUnitFacing_Category=TC_UNIT\nGetUnitMoveSpeed=0,1,real,unit\n_GetUnitMoveSpeed_Defaults=GetTriggerUnit\n_GetUnitMoveSpeed_Category=TC_UNIT\nGetUnitDefaultMoveSpeed=0,1,real,unit\n_GetUnitDefaultMoveSpeed_Defaults=GetTriggerUnit\n_GetUnitDefaultMoveSpeed_Category=TC_UNIT\nGetUnitAcquireRange=0,1,real,unit\n_GetUnitAcquireRange_Defaults=GetTriggerUnit\n_GetUnitAcquireRange_Category=TC_UNIT\nGetUnitDefaultAcquireRange=0,1,real,unit\n_GetUnitDefaultAcquireRange_Defaults=GetTriggerUnit\n_GetUnitDefaultAcquireRange_Category=TC_UNIT\nGetUnitTurnSpeed=0,1,real,unit\n_GetUnitTurnSpeed_Defaults=GetTriggerUnit\n_GetUnitTurnSpeed_Category=TC_UNIT\nGetUnitDefaultTurnSpeed=0,1,real,unit\n_GetUnitDefaultTurnSpeed_Defaults=GetTriggerUnit\n_GetUnitDefaultTurnSpeed_Category=TC_UNIT\nGetUnitPropWindowBJ=0,1,real,unit\n_GetUnitPropWindowBJ_Defaults=GetTriggerUnit\n_GetUnitPropWindowBJ_Category=TC_UNIT\nGetUnitDefaultPropWindowBJ=0,1,real,unit\n_GetUnitDefaultPropWindowBJ_Defaults=GetTriggerUnit\n_GetUnitDefaultPropWindowBJ_Category=TC_UNIT\nGetUnitFlyHeight=0,1,real,unit\n_GetUnitFlyHeight_Defaults=GetTriggerUnit\n_GetUnitFlyHeight_Category=TC_UNIT\nGetUnitDefaultFlyHeight=0,1,real,unit\n_GetUnitDefaultFlyHeight_Defaults=GetTriggerUnit\n_GetUnitDefaultFlyHeight_Category=TC_UNIT\nOperatorString=0,1,string,string,string\n_OperatorString_Defaults=_,_\n_OperatorString_Category=TC_NOTHING\nSubStringBJ=0,1,string,string,integer,integer\n_SubStringBJ_Defaults=_,1,5\n_SubStringBJ_Category=TC_NOTHING\nGetAbilityName=1,1,string,abilcode\n_GetAbilityName_Defaults=_\n_GetAbilityName_Category=TC_NOTHING\n_GetAbilityName_ScriptName=GetObjectName\nI2S=0,1,string,integer\n_I2S_Defaults=GetConvertedPlayerId\n_I2S_Category=TC_CONVERSION\nR2S=0,1,string,real\n_R2S_Defaults=GetUnitStateSwap\n_R2S_Category=TC_CONVERSION\nR2SW=0,1,string,real,integer,integer\n_R2SW_Defaults=GetUnitStateSwap,1,2\n_R2SW_Limits=_,_,0,_,0,_\n_R2SW_Category=TC_CONVERSION\nOrderId2StringBJ=0,1,string,ordercode\n_OrderId2StringBJ_Defaults=GetIssuedOrderIdBJ\n_OrderId2StringBJ_Category=TC_CONVERSION\nUnitId2StringBJ=0,1,string,unitcode\n_UnitId2StringBJ_Defaults=GetUnitTypeId\n_UnitId2StringBJ_Category=TC_CONVERSION\nStringIdentity=1,0,string,StringExt\n_StringIdentity_Defaults=_\n_StringIdentity_Category=TC_CONVERSION\nStringCase=1,1,string,StringExt,stringcaseoption\n_StringCase_Defaults=_,StringCaseLower\n_StringCase_Category=TC_CONVERSION\nGetDestructableName=1,1,string,destructable\n_GetDestructableName_Defaults=GetLastCreatedDestructable\n_GetDestructableName_Category=TC_DESTRUCT\nGetEventPlayerChatString=0,0,string\n_GetEventPlayerChatString_Defaults=\n_GetEventPlayerChatString_Category=TC_EVENTRESPONSE\nGetEventPlayerChatStringMatched=0,0,string\n_GetEventPlayerChatStringMatched_Defaults=\n_GetEventPlayerChatStringMatched_Category=TC_EVENTRESPONSE\nGetSaveBasicFilename=1,0,string\n_GetSaveBasicFilename_Defaults=\n_GetSaveBasicFilename_Category=TC_EVENTRESPONSE\nGetStoredStringBJ=1,0,string,string,string,gamecache\n_GetStoredStringBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredStringBJ_Category=TC_GAMECACHE\nGetHeroProperName=1,1,string,unit\n_GetHeroProperName_Defaults=GetTriggerUnit\n_GetHeroProperName_Category=TC_HERO\nGetItemName=1,1,string,item\n_GetItemName_Defaults=GetLastCreatedItem\n_GetItemName_Category=TC_ITEM\nMultiboardGetTitleText=1,1,string,multiboard\n_MultiboardGetTitleText_Defaults=GetLastCreatedMultiboard\n_MultiboardGetTitleText_Category=TC_MULTIBOARD\nGetPlayerName=0,1,string,player\n_GetPlayerName_Defaults=GetTriggerPlayer\n_GetPlayerName_Category=TC_PLAYER\nGetUnitName=0,1,string,unit\n_GetUnitName_Defaults=GetTriggerUnit\n_GetUnitName_Category=TC_UNIT\nGetRectCenter=0,1,location,rect\n_GetRectCenter_Defaults=GetPlayableMapRect\n_GetRectCenter_Category=TC_NOTHING\nGetRandomLocInRect=0,1,location,rect\n_GetRandomLocInRect_Defaults=GetPlayableMapRect\n_GetRandomLocInRect_Category=TC_NOTHING\nOffsetLocation=0,1,location,location,real,real\n_OffsetLocation_Defaults=GetRectCenter,0,0\n_OffsetLocation_Category=TC_NOTHING\nPolarProjectionBJ=0,1,location,location,real,real\n_PolarProjectionBJ_Defaults=GetRectCenter,256,0\n_PolarProjectionBJ_Category=TC_NOTHING\nCameraSetupGetDestPositionLoc=0,1,location,camerasetup\n_CameraSetupGetDestPositionLoc_Defaults=_\n_CameraSetupGetDestPositionLoc_Category=TC_CAMERA\nGetCameraTargetPositionLoc=0,1,location\n_GetCameraTargetPositionLoc_Defaults=\n_GetCameraTargetPositionLoc_Category=TC_CAMERA\nGetCameraEyePositionLoc=0,1,location\n_GetCameraEyePositionLoc_Defaults=\n_GetCameraEyePositionLoc_Category=TC_CAMERA\nLocation=0,1,location,real,real\n_Location_Defaults=0,0\n_Location_Category=TC_CONVERSION\nGetDestructableLoc=0,1,location,destructable\n_GetDestructableLoc_Defaults=GetLastCreatedDestructable\n_GetDestructableLoc_Category=TC_DESTRUCT\nGetOrderPointLoc=0,0,location\n_GetOrderPointLoc_Defaults=\n_GetOrderPointLoc_Category=TC_EVENTRESPONSE\nGetSpellTargetLoc=1,0,location\n_GetSpellTargetLoc_Defaults=\n_GetSpellTargetLoc_Category=TC_EVENTRESPONSE\nGetItemLoc=0,1,location,item\n_GetItemLoc_Defaults=GetLastCreatedItem\n_GetItemLoc_Category=TC_ITEM\nWaygateGetDestinationLocBJ=0,0,location,unit\n_WaygateGetDestinationLocBJ_Defaults=_\n_WaygateGetDestinationLocBJ_Category=TC_NEUTRALBUILDING\nGetPlayerStartLocationLoc=0,1,location,player\n_GetPlayerStartLocationLoc_Defaults=Player00\n_GetPlayerStartLocationLoc_Category=TC_PLAYER\nGetUnitLoc=0,1,location,unit\n_GetUnitLoc_Defaults=GetTriggerUnit\n_GetUnitLoc_Category=TC_UNIT\nGetUnitRallyPoint=1,1,location,unit\n_GetUnitRallyPoint_Defaults=GetTriggerUnit\n_GetUnitRallyPoint_Category=TC_UNIT\nGetCurrentCameraBoundsMapRectBJ=0,1,rect\n_GetCurrentCameraBoundsMapRectBJ_Defaults=\n_GetCurrentCameraBoundsMapRectBJ_Category=TC_NOTHING\nGetCameraBoundsMapRect=0,1,rect\n_GetCameraBoundsMapRect_Defaults=\n_GetCameraBoundsMapRect_Category=TC_NOTHING\nGetPlayableMapRect=0,1,rect\n_GetPlayableMapRect_Defaults=\n_GetPlayableMapRect_Category=TC_NOTHING\nGetEntireMapRect=0,1,rect\n_GetEntireMapRect_Defaults=\n_GetEntireMapRect_Category=TC_NOTHING\nOffsetRectBJ=0,0,rect,rect,real,real\n_OffsetRectBJ_Defaults=_,0,0\n_OffsetRectBJ_Category=TC_NOTHING\nRectFromCenterSizeBJ=0,1,rect,location,real,real\n_RectFromCenterSizeBJ_Defaults=GetUnitLoc,_,_\n_RectFromCenterSizeBJ_Category=TC_CONVERSION\nRect=0,1,rect,real,real,real,real\n_Rect_Defaults=0,0,0,0\n_Rect_Category=TC_CONVERSION\nRectFromLoc=0,1,rect,location,location\n_RectFromLoc_Defaults=Location,Location\n_RectFromLoc_Category=TC_CONVERSION\nGetLastCreatedUnit=0,0,unit\n_GetLastCreatedUnit_Defaults=\n_GetLastCreatedUnit_Category=TC_LAST\nGetLastRestoredUnitBJ=0,0,unit\n_GetLastRestoredUnitBJ_Defaults=\n_GetLastRestoredUnitBJ_Category=TC_LAST\nGetLastReplacedUnitBJ=0,0,unit\n_GetLastReplacedUnitBJ_Defaults=\n_GetLastReplacedUnitBJ_Category=TC_LAST\nGetLastHauntedGoldMine=0,0,unit\n_GetLastHauntedGoldMine_Defaults=\n_GetLastHauntedGoldMine_Category=TC_LAST\nGetEnumUnit=0,0,unit\n_GetEnumUnit_Defaults=\n_GetEnumUnit_Category=TC_NOTHING\nGetFilterUnit=0,0,unit\n_GetFilterUnit_Defaults=\n_GetFilterUnit_Category=TC_NOTHING\nGroupPickRandomUnit=0,0,unit,group\n_GroupPickRandomUnit_Defaults=_\n_GroupPickRandomUnit_Category=TC_NOTHING\nGetAttackedUnitBJ=0,0,unit\n_GetAttackedUnitBJ_Defaults=\n_GetAttackedUnitBJ_Category=TC_EVENTRESPONSE\nGetAttacker=0,0,unit\n_GetAttacker_Defaults=\n_GetAttacker_Category=TC_EVENTRESPONSE\nGetBuyingUnit=1,0,unit\n_GetBuyingUnit_Defaults=\n_GetBuyingUnit_Category=TC_EVENTRESPONSE\nGetCancelledStructure=0,0,unit\n_GetCancelledStructure_Defaults=\n_GetCancelledStructure_Category=TC_EVENTRESPONSE\nGetSpellAbilityUnit=1,0,unit\n_GetSpellAbilityUnit_Defaults=\n_GetSpellAbilityUnit_Category=TC_EVENTRESPONSE\nGetConstructingStructure=0,0,unit\n_GetConstructingStructure_Defaults=\n_GetConstructingStructure_Category=TC_EVENTRESPONSE\nGetConstructedStructure=0,0,unit\n_GetConstructedStructure_Defaults=\n_GetConstructedStructure_Category=TC_EVENTRESPONSE\nGetDecayingUnit=0,0,unit\n_GetDecayingUnit_Defaults=\n_GetDecayingUnit_Category=TC_EVENTRESPONSE\nGetDyingUnit=0,0,unit\n_GetDyingUnit_Defaults=\n_GetDyingUnit_Category=TC_EVENTRESPONSE\nGetEnteringUnit=0,0,unit\n_GetEnteringUnit_Defaults=\n_GetEnteringUnit_Category=TC_EVENTRESPONSE\nGetManipulatingUnit=0,0,unit\n_GetManipulatingUnit_Defaults=\n_GetManipulatingUnit_Category=TC_EVENTRESPONSE\nGetKillingUnitBJ=0,0,unit\n_GetKillingUnitBJ_Defaults=\n_GetKillingUnitBJ_Category=TC_EVENTRESPONSE\nGetLearningUnit=0,0,unit\n_GetLearningUnit_Defaults=\n_GetLearningUnit_Category=TC_EVENTRESPONSE\nGetLeavingUnit=0,0,unit\n_GetLeavingUnit_Defaults=\n_GetLeavingUnit_Category=TC_EVENTRESPONSE\nGetLevelingUnit=0,0,unit\n_GetLevelingUnit_Defaults=\n_GetLevelingUnit_Category=TC_EVENTRESPONSE\nGetLoadedUnitBJ=0,0,unit\n_GetLoadedUnitBJ_Defaults=\n_GetLoadedUnitBJ_Category=TC_EVENTRESPONSE\nGetOrderedUnit=0,0,unit\n_GetOrderedUnit_Defaults=\n_GetOrderedUnit_Category=TC_EVENTRESPONSE\nGetChangingUnit=1,0,unit\n_GetChangingUnit_Defaults=\n_GetChangingUnit_Category=TC_EVENTRESPONSE\nGetResearchingUnit=0,0,unit\n_GetResearchingUnit_Defaults=\n_GetResearchingUnit_Category=TC_EVENTRESPONSE\nGetRevivableUnit=0,0,unit\n_GetRevivableUnit_Defaults=\n_GetRevivableUnit_Category=TC_EVENTRESPONSE\nGetRevivingUnit=0,0,unit\n_GetRevivingUnit_Defaults=\n_GetRevivingUnit_Category=TC_EVENTRESPONSE\nGetSellingUnit=1,0,unit\n_GetSellingUnit_Defaults=\n_GetSellingUnit_Category=TC_EVENTRESPONSE\nGetSoldUnit=1,0,unit\n_GetSoldUnit_Defaults=\n_GetSoldUnit_Category=TC_EVENTRESPONSE\nGetSummonedUnit=0,0,unit\n_GetSummonedUnit_Defaults=\n_GetSummonedUnit_Category=TC_EVENTRESPONSE\nGetSummoningUnit=0,0,unit\n_GetSummoningUnit_Defaults=\n_GetSummoningUnit_Category=TC_EVENTRESPONSE\nGetOrderTargetUnit=0,0,unit\n_GetOrderTargetUnit_Defaults=\n_GetOrderTargetUnit_Category=TC_EVENTRESPONSE\nGetSpellTargetUnit=1,0,unit\n_GetSpellTargetUnit_Defaults=\n_GetSpellTargetUnit_Category=TC_EVENTRESPONSE\nGetEventTargetUnit=0,0,unit\n_GetEventTargetUnit_Defaults=\n_GetEventTargetUnit_Category=TC_EVENTRESPONSE\nGetTrainedUnit=0,0,unit\n_GetTrainedUnit_Defaults=\n_GetTrainedUnit_Category=TC_EVENTRESPONSE\nGetTransportUnitBJ=0,0,unit\n_GetTransportUnitBJ_Defaults=\n_GetTransportUnitBJ_Category=TC_EVENTRESPONSE\nGetTriggerUnit=0,0,unit\n_GetTriggerUnit_Defaults=\n_GetTriggerUnit_Category=TC_EVENTRESPONSE\nGetUnitRallyUnit=1,0,unit,unit\n_GetUnitRallyUnit_Defaults=GetTriggerUnit\n_GetUnitRallyUnit_Category=TC_UNIT\nGetUnitTypeId=0,1,unitcode,unit\n_GetUnitTypeId_Defaults=GetTriggerUnit\n_GetUnitTypeId_Category=TC_NOTHING\nChooseRandomCreepBJ=0,1,unitcode,integer\n_ChooseRandomCreepBJ_Defaults=1\n_ChooseRandomCreepBJ_Limits=-1,10\n_ChooseRandomCreepBJ_Category=TC_NOTHING\nChooseRandomNPBuildingBJ=0,1,unitcode\n_ChooseRandomNPBuildingBJ_Defaults=\n_ChooseRandomNPBuildingBJ_Category=TC_NOTHING\nString2UnitIdBJ=0,1,unitcode,string\n_String2UnitIdBJ_Defaults=footman\n_String2UnitIdBJ_Category=TC_CONVERSION\nGetTrainedUnitType=0,0,unitcode\n_GetTrainedUnitType_Defaults=\n_GetTrainedUnitType_Category=TC_EVENTRESPONSE\nString2OrderIdBJ=0,0,ordercode,string\n_String2OrderIdBJ_Defaults=stop\n_String2OrderIdBJ_Category=TC_CONVERSION\nUnitId2OrderIdBJ=0,0,ordercode,unitcode\n_UnitId2OrderIdBJ_Defaults=hfoo\n_UnitId2OrderIdBJ_Category=TC_CONVERSION\nGetIssuedOrderIdBJ=0,0,ordercode\n_GetIssuedOrderIdBJ_Defaults=\n_GetIssuedOrderIdBJ_Category=TC_EVENTRESPONSE\nGetUnitCurrentOrder=1,0,ordercode,unit\n_GetUnitCurrentOrder_Defaults=GetTriggerUnit\n_GetUnitCurrentOrder_Category=TC_UNIT\nGetLastCreatedDestructable=0,0,destructable\n_GetLastCreatedDestructable_Defaults=\n_GetLastCreatedDestructable_Category=TC_LAST\nRandomDestructableInRectSimpleBJ=0,0,destructable,rect\n_RandomDestructableInRectSimpleBJ_Defaults=_\n_RandomDestructableInRectSimpleBJ_Category=TC_NOTHING\nRandomDestructableInRectBJ=0,0,destructable,rect,boolexpr\n_RandomDestructableInRectBJ_Defaults=_,_\n_RandomDestructableInRectBJ_Category=TC_NOTHING\nGetEnumDestructable=0,0,destructable\n_GetEnumDestructable_Defaults=\n_GetEnumDestructable_Category=TC_NOTHING\nGetFilterDestructable=0,0,destructable\n_GetFilterDestructable_Defaults=\n_GetFilterDestructable_Category=TC_NOTHING\nGetDyingDestructable=0,0,destructable\n_GetDyingDestructable_Defaults=\n_GetDyingDestructable_Category=TC_EVENTRESPONSE\nGetOrderTargetDestructable=0,0,destructable\n_GetOrderTargetDestructable_Defaults=\n_GetOrderTargetDestructable_Category=TC_EVENTRESPONSE\nGetSpellTargetDestructable=1,0,destructable\n_GetSpellTargetDestructable_Defaults=\n_GetSpellTargetDestructable_Category=TC_EVENTRESPONSE\nGetUnitRallyDestructable=1,0,destructable,unit\n_GetUnitRallyDestructable_Defaults=GetTriggerUnit\n_GetUnitRallyDestructable_Category=TC_UNIT\nGetDestructableTypeId=0,1,destructablecode,destructable\n_GetDestructableTypeId_Defaults=GetLastCreatedDestructable\n_GetDestructableTypeId_Category=TC_NOTHING\nGetLastCreatedItem=0,0,item\n_GetLastCreatedItem_Defaults=\n_GetLastCreatedItem_Category=TC_LAST\nGetLastRemovedItem=0,0,item\n_GetLastRemovedItem_Defaults=\n_GetLastRemovedItem_Category=TC_LAST\nRandomItemInRectSimpleBJ=1,0,item,rect\n_RandomItemInRectSimpleBJ_Defaults=_\n_RandomItemInRectSimpleBJ_Category=TC_NOTHING\nRandomItemInRectBJ=1,0,item,rect,boolexpr\n_RandomItemInRectBJ_Defaults=_,_\n_RandomItemInRectBJ_Category=TC_NOTHING\nGetEnumItem=1,0,item\n_GetEnumItem_Defaults=\n_GetEnumItem_Category=TC_NOTHING\nGetFilterItem=1,0,item\n_GetFilterItem_Defaults=\n_GetFilterItem_Category=TC_NOTHING\nUnitItemInSlotBJ=0,0,item,unit,integer\n_UnitItemInSlotBJ_Defaults=_,1\n_UnitItemInSlotBJ_Limits=_,_,1,6\n_UnitItemInSlotBJ_Category=TC_NOTHING\nGetItemOfTypeFromUnitBJ=0,0,item,unit,itemcode\n_GetItemOfTypeFromUnitBJ_Defaults=_,texp\n_GetItemOfTypeFromUnitBJ_Category=TC_NOTHING\nGetManipulatedItem=0,0,item\n_GetManipulatedItem_Defaults=\n_GetManipulatedItem_Category=TC_EVENTRESPONSE\nGetSoldItem=1,0,item\n_GetSoldItem_Defaults=\n_GetSoldItem_Category=TC_EVENTRESPONSE\nGetOrderTargetItem=0,0,item\n_GetOrderTargetItem_Defaults=\n_GetOrderTargetItem_Category=TC_EVENTRESPONSE\nGetSpellTargetItem=1,0,item\n_GetSpellTargetItem_Defaults=\n_GetSpellTargetItem_Category=TC_EVENTRESPONSE\nGetItemType=1,1,itemtype,item\n_GetItemType_Defaults=GetLastCreatedItem\n_GetItemType_Category=TC_NOTHING\nGetItemTypeId=0,1,itemcode,item\n_GetItemTypeId_Defaults=GetLastCreatedItem\n_GetItemTypeId_Category=TC_NOTHING\nChooseRandomItemBJ=0,1,itemcode,integer\n_ChooseRandomItemBJ_Defaults=1\n_ChooseRandomItemBJ_Limits=-1,10\n_ChooseRandomItemBJ_Category=TC_NOTHING\nChooseRandomItemExBJ=1,1,itemcode,integer,itemtype\n_ChooseRandomItemExBJ_Defaults=1,ItemTypeAny\n_ChooseRandomItemExBJ_Limits=-1,8,_,_\n_ChooseRandomItemExBJ_Category=TC_NOTHING\nGetResearched=0,1,techcode\n_GetResearched_Defaults=\n_GetResearched_Category=TC_EVENTRESPONSE\nGetSpellAbilityId=1,0,abilcode\n_GetSpellAbilityId_Defaults=\n_GetSpellAbilityId_Category=TC_EVENTRESPONSE\nGetLearnedSkillBJ=0,0,heroskillcode\n_GetLearnedSkillBJ_Defaults=\n_GetLearnedSkillBJ_Category=TC_EVENTRESPONSE\nGetEnumPlayer=0,0,player\n_GetEnumPlayer_Defaults=\n_GetEnumPlayer_Category=TC_NOTHING\nGetFilterPlayer=0,0,player\n_GetFilterPlayer_Defaults=\n_GetFilterPlayer_Category=TC_NOTHING\nGetOwningPlayer=0,1,player,unit\n_GetOwningPlayer_Defaults=GetTriggerUnit\n_GetOwningPlayer_Category=TC_NOTHING\nGetItemPlayer=0,1,player,item\n_GetItemPlayer_Defaults=GetLastCreatedItem\n_GetItemPlayer_Category=TC_NOTHING\nForcePickRandomPlayer=0,0,player,force\n_ForcePickRandomPlayer_Defaults=_\n_ForcePickRandomPlayer_Category=TC_NOTHING\nConvertedPlayer=0,1,player,integer\n_ConvertedPlayer_Defaults=1\n_ConvertedPlayer_Limits=1,16\n_ConvertedPlayer_Category=TC_CONVERSION\nGetChangingUnitPrevOwner=1,0,player\n_GetChangingUnitPrevOwner_Defaults=\n_GetChangingUnitPrevOwner_Category=TC_EVENTRESPONSE\nGetTriggerPlayer=0,0,player\n_GetTriggerPlayer_Defaults=\n_GetTriggerPlayer_Category=TC_EVENTRESPONSE\nLeaderboardGetIndexedPlayerBJ=1,0,player,integer,leaderboard\n_LeaderboardGetIndexedPlayerBJ_Defaults=1,GetLastCreatedLeaderboard\n_LeaderboardGetIndexedPlayerBJ_Limits=1,16\n_LeaderboardGetIndexedPlayerBJ_Category=TC_LEADERBOARD\nGetLastCreatedGroup=0,0,group\n_GetLastCreatedGroup_Defaults=\n_GetLastCreatedGroup_Category=TC_LAST\nGetRandomSubGroup=1,0,group,integer,group\n_GetRandomSubGroup_Defaults=4,GetUnitsInRectAll\n_GetRandomSubGroup_Category=TC_NOTHING\nGetUnitsInRectAll=0,0,group,rect\n_GetUnitsInRectAll_Defaults=GetPlayableMapRect\n_GetUnitsInRectAll_Category=TC_NOTHING\nGetUnitsInRectOfPlayer=0,0,group,rect,player\n_GetUnitsInRectOfPlayer_Defaults=GetPlayableMapRect,Player00\n_GetUnitsInRectOfPlayer_Category=TC_NOTHING\nGetUnitsInRectMatching=0,0,group,rect,boolexpr\n_GetUnitsInRectMatching_Defaults=GetPlayableMapRect,_\n_GetUnitsInRectMatching_Category=TC_NOTHING\nGetUnitsInRangeOfLocAll=0,0,group,real,location\n_GetUnitsInRangeOfLocAll_Defaults=512,GetRectCenter\n_GetUnitsInRangeOfLocAll_Limits=0,_,_,_\n_GetUnitsInRangeOfLocAll_Category=TC_NOTHING\nGetUnitsInRangeOfLocMatching=0,0,group,real,location,boolexpr\n_GetUnitsInRangeOfLocMatching_Defaults=512,GetRectCenter,_\n_GetUnitsInRangeOfLocMatching_Limits=0,_,_,_,_,_\n_GetUnitsInRangeOfLocMatching_Category=TC_NOTHING\nGetUnitsOfPlayerAll=0,0,group,player\n_GetUnitsOfPlayerAll_Defaults=Player00\n_GetUnitsOfPlayerAll_Category=TC_NOTHING\nGetUnitsOfPlayerAndTypeId=0,0,group,player,unitcode\n_GetUnitsOfPlayerAndTypeId_Defaults=Player00,hfoo\n_GetUnitsOfPlayerAndTypeId_Category=TC_NOTHING\nGetUnitsOfPlayerMatching=0,0,group,player,boolexpr\n_GetUnitsOfPlayerMatching_Defaults=Player00,_\n_GetUnitsOfPlayerMatching_Category=TC_NOTHING\nGetUnitsOfTypeIdAll=0,0,group,unitcode\n_GetUnitsOfTypeIdAll_Defaults=hfoo\n_GetUnitsOfTypeIdAll_Category=TC_NOTHING\nGetUnitsSelectedAll=0,0,group,player\n_GetUnitsSelectedAll_Defaults=Player00\n_GetUnitsSelectedAll_Category=TC_NOTHING\nGetPlayersAll=0,0,force\n_GetPlayersAll_Defaults=\n_GetPlayersAll_Category=TC_NOTHING\nGetPlayersByMapControl=0,0,force,mapcontrol\n_GetPlayersByMapControl_Defaults=MapControlComputer\n_GetPlayersByMapControl_Category=TC_NOTHING\nGetPlayersMatching=0,0,force,boolexpr\n_GetPlayersMatching_Defaults=_\n_GetPlayersMatching_Category=TC_NOTHING\nGetPlayersAllies=0,0,force,player\n_GetPlayersAllies_Defaults=Player00\n_GetPlayersAllies_Category=TC_NOTHING\nGetPlayersEnemies=0,0,force,player\n_GetPlayersEnemies_Defaults=Player00\n_GetPlayersEnemies_Category=TC_NOTHING\nGetForceOfPlayer=0,0,force,player\n_GetForceOfPlayer_Defaults=Player00\n_GetForceOfPlayer_Category=TC_NOTHING\nGetPlayerRace=0,1,race,player\n_GetPlayerRace_Defaults=Player00\n_GetPlayerRace_Category=TC_NOTHING\nGetUnitRace=0,1,race,unit\n_GetUnitRace_Defaults=GetTriggerUnit\n_GetUnitRace_Category=TC_NOTHING\nGetCurrentCameraSetup=0,0,camerasetup\n_GetCurrentCameraSetup_Defaults=\n_GetCurrentCameraSetup_Category=TC_NOTHING\nGetLastCreatedFogModifier=0,0,fogmodifier\n_GetLastCreatedFogModifier_Defaults=\n_GetLastCreatedFogModifier_Category=TC_LAST\nGetTriggeringTrigger=0,0,trigger\n_GetTriggeringTrigger_Defaults=\n_GetTriggeringTrigger_Category=TC_NOTHING\nGetGameDifficulty=0,1,gamedifficulty\n_GetGameDifficulty_Defaults=\n_GetGameDifficulty_Category=TC_NOTHING\nGetAIDifficulty=1,1,aidifficulty,player\n_GetAIDifficulty_Defaults=Player00\n_GetAIDifficulty_Category=TC_NOTHING\nGetGameSpeed=0,1,gamespeed\n_GetGameSpeed_Defaults=\n_GetGameSpeed_Category=TC_NOTHING\nGetPlayerController=0,1,mapcontrol,player\n_GetPlayerController_Defaults=Player00\n_GetPlayerController_Category=TC_NOTHING\nGetPlayerColor=0,1,playercolor,player\n_GetPlayerColor_Defaults=Player00\n_GetPlayerColor_Category=TC_NOTHING\nGetPlayerSlotState=0,1,playerslotstate,player\n_GetPlayerSlotState_Defaults=Player00\n_GetPlayerSlotState_Category=TC_NOTHING\nGetLastCreatedEffectBJ=0,0,effect\n_GetLastCreatedEffectBJ_Defaults=\n_GetLastCreatedEffectBJ_Category=TC_LAST\nGetLastCreatedImage=0,0,image\n_GetLastCreatedImage_Defaults=\n_GetLastCreatedImage_Category=TC_LAST\nGetLastCreatedUbersplat=0,0,ubersplat\n_GetLastCreatedUbersplat_Defaults=\n_GetLastCreatedUbersplat_Category=TC_LAST\nGetLastCreatedWeatherEffect=0,0,weathereffect\n_GetLastCreatedWeatherEffect_Defaults=\n_GetLastCreatedWeatherEffect_Category=TC_LAST\nGetLastCreatedTerrainDeformation=1,0,terraindeformation\n_GetLastCreatedTerrainDeformation_Defaults=\n_GetLastCreatedTerrainDeformation_Category=TC_LAST\nGetLastPlayedSound=0,0,sound\n_GetLastPlayedSound_Defaults=\n_GetLastPlayedSound_Category=TC_LAST\nGetLastPlayedMusic=0,0,musicfile\n_GetLastPlayedMusic_Defaults=\n_GetLastPlayedMusic_Category=TC_LAST\nGetLastCreatedQuestBJ=0,0,quest\n_GetLastCreatedQuestBJ_Defaults=\n_GetLastCreatedQuestBJ_Category=TC_LAST\nGetLastCreatedQuestItemBJ=0,0,questitem\n_GetLastCreatedQuestItemBJ_Defaults=\n_GetLastCreatedQuestItemBJ_Category=TC_LAST\nGetLastCreatedDefeatConditionBJ=0,0,defeatcondition\n_GetLastCreatedDefeatConditionBJ_Defaults=\n_GetLastCreatedDefeatConditionBJ_Category=TC_LAST\nGetClickedDialogBJ=0,0,dialog\n_GetClickedDialogBJ_Defaults=\n_GetClickedDialogBJ_Category=TC_EVENTRESPONSE\nGetLastCreatedButtonBJ=0,0,button\n_GetLastCreatedButtonBJ_Defaults=\n_GetLastCreatedButtonBJ_Category=TC_LAST\nGetClickedButtonBJ=0,0,button\n_GetClickedButtonBJ_Defaults=\n_GetClickedButtonBJ_Category=TC_EVENTRESPONSE\nGetLastCreatedLeaderboard=0,0,leaderboard\n_GetLastCreatedLeaderboard_Defaults=\n_GetLastCreatedLeaderboard_Category=TC_LAST\nPlayerGetLeaderboardBJ=0,0,leaderboard,player\n_PlayerGetLeaderboardBJ_Defaults=Player00\n_PlayerGetLeaderboardBJ_Category=TC_NOTHING\nGetLastCreatedMultiboard=1,0,multiboard\n_GetLastCreatedMultiboard_Defaults=\n_GetLastCreatedMultiboard_Category=TC_LAST\nGetLastCreatedTimerBJ=0,0,timer\n_GetLastCreatedTimerBJ_Defaults=\n_GetLastCreatedTimerBJ_Category=TC_LAST\nGetExpiredTimer=0,0,timer\n_GetExpiredTimer_Defaults=\n_GetExpiredTimer_Category=TC_EVENTRESPONSE\nGetLastCreatedTimerDialogBJ=0,0,timerdialog\n_GetLastCreatedTimerDialogBJ_Defaults=\n_GetLastCreatedTimerDialogBJ_Category=TC_LAST\nGetLastCreatedGameCacheBJ=0,0,gamecache\n_GetLastCreatedGameCacheBJ_Defaults=\n_GetLastCreatedGameCacheBJ_Category=TC_LAST\nGetLastCreatedTextTag=1,0,texttag\n_GetLastCreatedTextTag_Defaults=\n_GetLastCreatedTextTag_Category=TC_LAST\nGetLocalPlayer=1,0,player\n_GetLocalPlayer_Defaults=\n_GetLocalPlayer_Category=TC_PLAYER\nGetEventDetectingPlayer=0,0,player\n_GetEventDetectingPlayer_Defaults=\n_GetEventDetectingPlayer_Category=TC_EVENTRESPONSE\nGetWinningPlayer=1,0,player\n_GetWinningPlayer_Defaults=\n_GetWinningPlayer_Category=TC_EVENTRESPONSE\nGetUnitX=0,1,real,unit\n_GetUnitX_Defaults=GetTriggerUnit\n_GetUnitX_Category=TC_UNIT\nGetUnitY=0,1,real,unit\n_GetUnitY_Defaults=GetTriggerUnit\n_GetUnitY_Category=TC_UNIT\nCreateTimerBJ=0,1,timer,periodicoption,real\n_CreateTimerBJ_Defaults=PeriodicOptionOneTime,30\n_CreateTimerBJ_Categor=TC_TIMER\nCreateTrigger=0,1,trigger\n_CreateTrigger_Defaults=\n_CreateTrigger_Category=TC_TRIGGER\nCreateDestructableZ=0,0,destructable,destructablecode,real,real,real,real,real,integer\n_CreateDestructableZ_Defaults=LTlt,GetLocationX,GetLocationY,0,GetRandomDirectionDeg,1,0\n_CreateDestructableZ_Limits=_,_,_,_,_,_,_,_,_,_,0,_,0,_\n_CreateDestructableZ_Category=TC_DESTRUCT\nCreateDeadDestructableZ=0,0,destructable,destructablecode,real,real,real,real,real,integer\n_CreateDeadDestructableZ_Defaults=LTlt,GetLocationX,GetLocationY,0,GetRandomDirectionDeg,1,0\n_CreateDeadDestructableZ_Limits=_,_,_,_,_,_,_,_,_,_,0,_,0,_\n_CreateDeadDestructableZ_Category=TC_DESTRUCT\nGetTriggerEventId=0,1,eventid\n_GetTriggerEventId_Defaults=_\n_GetTriggerEventId_Category=TC_TRIGGER\nQueuedTriggerGetIndex=0,0,integer,trigger\n_QueuedTriggerGetIndex_Defaults=_\n_QueuedTriggerGetIndex_Category=TC_TRIGGER\nIntegerTertiaryOp=0,1,integer,boolean,integer,integer\n_IntegerTertiaryOp_Defaults=_,_,_\n_IntegerTertiaryOp_Category=TC_MATH\nIsLocationInRegion=1,2,boolean,region,location\n_IsLocationInRegion_Defaults=_,_\n_IsLocationInRegion_Category=TC_REGION\nIsUnitInRegion=1,2,boolean,region,unit\n_IsUnitInRegion_Defaults=_,_\n_IsUnitInRegion_Category=TC_REGION\nIsPointInRegion=0,1,boolean,region,real,real\n_IsPointInRegion_Defaults=GetTriggeringRegion,GetLocationX,GetLocationY\n_IsPointInRegion_Category=TC_REGION\nCompareRectsBJ=0,1,boolean,rect,rect\n_CompareRectsBJ_Defaults=GetPlayableMapRect,GetPlayableMapRect\n_CompareRectsBJ_Category=TC_REGION\nIsUnitInForce=0,1,boolean,unit,force\n_IsUnitInForce_Defaults=GetTriggerUnit,_\n_IsUnitInForce_Category=TC_UNIT\nIsUnitOwnedByPlayer=0,1,boolean,unit,player\n_IsUnitOwnedByPlayer_Defaults=GetTriggerUnit,Player00\n_IsUnitOwnedByPlayer_Category=TC_UNIT\nIsUnitInRange=0,1,boolean,unit,unit,real\n_IsUnitInRange_Defaults=GetTriggerUnit,_,500\n_IsUnitInRange_Category=TC_UNIT\nIsUnitInRangeLoc=0,1,boolean,unit,location,real\n_IsUnitInRangeLoc_Defaults=GetTriggerUnit,_,500\n_IsUnitInRangeLoc_Category=TC_UNIT\nCreateUnit=0,0,unit,player,unitcode,real,real,real\n_CreateUnit_Defaults=Player00,hfoo,GetLocationX,GetLocationY,0\n_CreateUnit_Category=TC_UNIT\nCreateUnitAtLoc=0,0,unit,player,unitcode,location,real\n_CreateUnitAtLoc_Defaults=Player00,hfoo,GetRectCenter,0\n_CreateUnitAtLoc_Category=TC_UNIT\nGetRescuer=1,0,unit\n_GetRescuer_Defaults=\n_GetRescuer_Category=TC_EVENTRESPONSE\nGetEventUnitState=1,0,unitstate\n_GetEventUnitState_Defaults=\n_GetEventUnitState_Category=TC_EVENTRESPONSE\nGetEventPlayerState=1,0,playerstate\n_GetEventPlayerState_Defaults=\n_GetEventPlayerState_Category=TC_EVENTRESPONSE\nDialogCreate=1,0,dialog\n_DialogCreate_Defaults=\n_DialogCreate_Category=TC_DIALOG\nCreateForce=1,1,force\n_CreateForce_Defaults=\n_CreateForce_Category=TC_PLAYERGROUP\nCreateGroup=1,1,group\n_CreateGroup_Defaults=\n_CreateGroup_Category=TC_UNITGROUP\nGetTriggeringRegion=1,1,region\n_GetTriggeringRegion_Defaults\n_GetTriggeringRegion_Category=TC_RECTANGLE\nCreateRegion=1,0,region\n_CreateRegion_Defaults=\n_CreateRegion_Category=TC_RECTANGLE\nGetPlayerTypedUnitCount=1,1,integer,player,unituiname,boolean,boolean\n_GetPlayerTypedUnitCount_Defaults=Player00,\"townhall\",true,true\n_GetPlayerTypedUnitCount_Category=TC_UNIT\nRandomDistChoose=1,0,itemcode\n_RandomDistChoose_Defaults=\n_RandomDistChoose_Category=TC_ITEM\nGetDetectedUnit=1,0,unit\n_GetDetectedUnit_Defaults=\n_GetDetectedUnit_Category=TC_EVENTRESPONSE\nLeaderboardGetLabelText=0,0,string,leaderboard\n_LeaderboardGetLabelText_Defaults=GetLastCreatedLeaderboard\n_LeaderboardGetLabelText_Category=TC_LEADERBOARD\nUnitIgnoreAlarmToggled=1,1,boolean,unit\n_UnitIgnoreAlarmToggled_Defaults=_\n_UnitIgnoreAlarmToggled_Category=TC_UNIT\nUnitInventorySizeBJ=1,1,integer,unit\n_UnitInventorySizeBJ_Defaults=GetTriggerUnit\n_UnitInventorySizeBJ_Category=TC_UNIT\nGetLastCreatedLightningBJ=0,0,lightning\n_GetLastCreatedLightningBJ_Defaults=\n_GetLastCreatedLightningBJ_Category=TC_LAST\nGetLightningColorABJ=1,0,real,lightning\n_GetLightningColorABJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorABJ_Category=TC_SPECIALEFFECT\n_GetLightningColorABJ_ScriptName=GetLightningColorA\nGetLightningColorRBJ=1,0,real,lightning\n_GetLightningColorRBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorRBJ_Category=TC_SPECIALEFFECT\n_GetLightningColorRBJ_ScriptName=GetLightningColorR\nGetLightningColorGBJ=1,0,real,lightning\n_GetLightningColorGBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorGBJ_Category=TC_SPECIALEFFECT\n_GetLightningColorGBJ_ScriptName=GetLightningColorG\nGetLightningColorBBJ=1,0,real,lightning\n_GetLightningColorBBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorBBJ_Category=TC_SPECIALEFFECT\n_GetLightningColorBBJ_ScriptName=GetLightningColorB\nGetEventDamageSource=1,0,unit\n_GetEventDamageSource_Defaults=\n_GetEventDamageSource_Category=TC_EVENTRESPONSE\nGetAbilityEffectBJ=1,1,string,string,effecttype,integer\n_GetAbilityEffectBJ_Defaults=\"blizzard\",EffectTypeEffect,0\n_GetAbilityEffectBJ_Category=TC_NOTHING\n_GetAbilityEffectBJ_ScriptName=GetAbilityEffect\nGetAbilitySoundBJ=1,1,string,string,soundtype\n_GetAbilitySoundBJ_Defaults=\"blizzard\",SoundTypeEffect\n_GetAbilitySoundBJ_Category=TC_NOTHING\n_GetAbilitySoundBJ_ScriptName=GetAbilitySound\nGetAbilityEffectById=1,1,string,buffcode,effecttypebuff,integer\n_GetAbilityEffectById_Defaults=_,EffectTypeEffectBuff,0\n_GetAbilityEffectById_Category=TC_NOTHING\nGetAbilitySoundById=1,1,string,abilcode,soundtype\n_GetAbilitySoundById_Defaults=_,SoundTypeEffect\n_GetAbilitySoundById_Category=TC_NOTHING\nGetTriggerName=0,1,string\n_GetTriggerName_Defaults=\n_GetTriggerName_Category=TC_TRIGGER\nHaveStoredInteger=1,1,boolean,gamecache,string,string\n_HaveStoredInteger_Defaults=_,_,_\n_HaveStoredInteger_Category=TC_GAMECACHE\nHaveStoredBoolean=1,1,boolean,gamecache,string,string\n_HaveStoredBoolean_Defaults=_,_,_\n_HaveStoredBoolean_Category=TC_GAMECACHE\nHaveStoredReal=1,1,boolean,gamecache,string,string\n_HaveStoredReal_Defaults=_,_,_\n_HaveStoredReal_Category=TC_GAMECACHE\nHaveStoredUnit=1,1,boolean,gamecache,string,string\n_HaveStoredUnit_Defaults=_,_,_\n_HaveStoredUnit_Category=TC_GAMECACHE\nHaveStoredString=1,1,boolean,gamecache,string,string\n_HaveStoredString_Defaults=_,_,_\n_HaveStoredString_Category=TC_GAMECACHE\nexitwhen=0,1,scriptcode,boolcall\n_exitwhen_Defaults=\n_exitwhen_Category=TC_CUSTOM\nAddSpecialEffectLoc=0,0,effect,modelfile,location\n_AddSpecialEffectLoc_Defaults=\n_AddSpecialEffectLoc_Category=TC_SPECIALEFFECT\nAddSpecialEffect=0,0,effect,modelfile,real,real\n_AddSpecialEffect_Defaults=\n_AddSpecialEffect_Category=TC_SPECIALEFFECT\nAddSpecialEffectTarget=0,0,effect,modelfile,unit,string\n_AddSpecialEffectTarget_Defaults=\n_AddSpecialEffectTarget_Category=TC_SPECIALEFFECT\nCreateTrackable=0,1,trackable,modelfile,real,real,real\n_CreateTrackable_Defaults=\"units\\nightelf\\Wisp\\Wisp.mdl\",_,_,0\n_CreateTrackable_Category=TC_TRACKABLE\nGetTriggeringTrackable=0,0,trackable\n_GetTriggeringTrackable_Defaults=\n_GetTriggeringTrackable_Category=TC_TRACKABLE\nLeaderboardGetItemCount=0,0,integer,leaderboard\n_LeaderboardGetItemCount_Defaults=GetLastCreatedLeaderboard\n_LeaderboardGetItemCount_Category=TC_LEADERBOARD\nFirstOfGroup=0,0,unit,group\n_FirstOfGroup_Defaults=_\n_FirstOfGroup_Category=TC_UNITGROUP\nCreateItemLoc=0,1,item,itemcode,location\n_CreateItemLoc_Defaults=texp,GetRectCenter\n_CreateItemLoc_Category=TC_ITEM\nGetEventGameState=1,0,gamestate\n_GetEventGameState_Defaults=\n_GetEventGameState_Category=TC_EVENTRESPONSE\nGetIntegerGameState=0,1,integer,igamestate\n_GetIntegerGameState_Defaults=IGamestateDisconnected\n_GetIntegerGameState_Category=TC_GAME\nIsTimerDialogDisplayed=0,1,boolean,timerdialog\n_IsTimerDialogDisplayed_Defaults=GetLastCreatedTimerDialogBJ\n_IsTimerDialogDisplayed_Category=TC_TIMER\nQueuedTriggerRemoveByIndex=0,0,boolean,integer\n_QueuedTriggerRemoveByIndex_Defaults=0\n_QueuedTriggerRemoveByIndex_Category=TC_RETURNSUCCESS\nReviveHeroLoc=0,0,boolean,unit,location,showhideoption\n_ReviveHeroLoc_Defaults=_,GetRectCenter,ShowHideHide\n_ReviveHeroLoc_Category=TC_RETURNSUCCESS\nUnitMakeAbilityPermanent=0,0,boolean,unit,permanentoption,abilcode\n_UnitMakeAbilityPermanent_Defaults=GetTriggerUnit,PermanentPerm,_\n_UnitMakeAbilityPermanent_Category=TC_RETURNSUCCESS\nUnitAddAbilityBJ=0,0,boolean,abilcode,unit\n_UnitAddAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitAddAbilityBJ_Category=TC_RETURNSUCCESS\nUnitRemoveAbilityBJ=0,0,boolean,abilcode,unit\n_UnitRemoveAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveAbilityBJ_Category=TC_RETURNSUCCESS\nUnitRemoveBuffBJ=0,0,boolean,buffcode,unit\n_UnitRemoveBuffBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveBuffBJ_Category=TC_RETURNSUCCESS\nUnitAddItemSwapped=0,0,boolean,item,unit\n_UnitAddItemSwapped_Defaults=GetLastCreatedItem,GetTriggerUnit\n_UnitAddItemSwapped_Category=TC_RETURNSUCCESS\nUnitAddItemByIdSwapped=0,0,boolean,itemcode,unit\n_UnitAddItemByIdSwapped_Defaults=texp,GetTriggerUnit\n_UnitAddItemByIdSwapped_Category=TC_RETURNSUCCESS\nUnitUseItem=0,0,boolean,unit,item\n_UnitUseItem_Defaults=_,GetLastCreatedItem\n_UnitUseItem_Category=TC_RETURNSUCCESS\nUnitUseItemTarget=0,0,boolean,unit,item,unit\n_UnitUseItemTarget_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemTarget_Category=TC_RETURNSUCCESS\nUnitUseItemPointLoc=0,0,boolean,unit,item,location\n_UnitUseItemPointLoc_Defaults=_,GetLastCreatedItem,GetRectCenter\n_UnitUseItemPointLoc_Category=TC_RETURNSUCCESS\nUnitUseItemDestructable=0,0,boolean,unit,item,destructable\n_UnitUseItemDestructable_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemDestructable_Category=TC_RETURNSUCCESS\nIssueInstantTargetOrder=1,0,boolean,unit,unitorderinstant,unit,item\n_IssueInstantTargetOrder_Defaults=GetTriggerUnit,InstantOrderGive,GetLastCreatedUnit,UnitItemInSlotBJ\n_IssueInstantTargetOrder_Category=TC_RETURNSUCCESS\nIssueImmediateOrder=0,0,boolean,unit,unitordernotarg\n_IssueImmediateOrder_Defaults=_,UnitOrderStop\n_IssueImmediateOrder_Category=TC_RETURNSUCCESS\nIssuePointOrderLoc=0,0,boolean,unit,unitorderptarg,location\n_IssuePointOrderLoc_Defaults=_,UnitOrderMove,GetRectCenter\n_IssuePointOrderLoc_Category=TC_RETURNSUCCESS\nIssueTargetOrder=0,0,boolean,unit,unitorderutarg,unit\n_IssueTargetOrder_Defaults=_,UnitOrderAttackUnit,_\n_IssueTargetOrder_Category=TC_RETURNSUCCESS\nIssueTargetDestructableOrder=0,0,boolean,unit,unitorderdtarg,destructable\n_IssueTargetDestructableOrder_Defaults=_,UnitOrderHarvestDestructible,_\n_IssueTargetDestructableOrder_Category=TC_RETURNSUCCESS\nIssueTargetOrderBJ=0,0,boolean,unit,unitorderitarg,item\n_IssueTargetOrderBJ_Defaults=_,ItemOrderPickUp,_\n_IssueTargetOrderBJ_Category=TC_RETURNSUCCESS\nIssueBuildOrderByIdLocBJ=0,0,boolean,unit,unitcode,location\n_IssueBuildOrderByIdLocBJ_Defaults=_,hbar,GetRectCenter\n_IssueBuildOrderByIdLocBJ_Category=TC_RETURNSUCCESS\nIssueTrainOrderByIdBJ=0,0,boolean,unit,unitcode\n_IssueTrainOrderByIdBJ_Defaults=_,hfoo\n_IssueTrainOrderByIdBJ_Category=TC_RETURNSUCCESS\nIssueUpgradeOrderByIdBJ=0,0,boolean,unit,techcode\n_IssueUpgradeOrderByIdBJ_Defaults=_,Rhde\n_IssueUpgradeOrderByIdBJ_Category=TC_RETURNSUCCESS\nGroupTargetOrder=0,0,boolean,group,unitorderutarg,unit\n_GroupTargetOrder_Defaults=GetUnitsInRectAll,UnitOrderAttackUnit,_\n_GroupTargetOrder_Category=TC_RETURNSUCCESS\nGroupTargetDestructableOrder=0,0,boolean,group,unitorderdtarg,destructable\n_GroupTargetDestructableOrder_Defaults=GetUnitsInRectAll,UnitOrderHarvestDestructible,_\n_GroupTargetDestructableOrder_Category=TC_RETURNSUCCESS\nGroupTargetOrderBJ=0,0,boolean,group,unitorderutarg,item\n_GroupTargetOrderBJ_Defaults=GetUnitsInRectAll,ItemOrderPickUp,_\n_GroupTargetOrderBJ_Category=TC_RETURNSUCCESS\nGroupPointOrderLoc=0,0,boolean,group,unitorderptarg,location\n_GroupPointOrderLoc_Defaults=GetUnitsInRectAll,UnitOrderMove,GetRectCenter\n_GroupPointOrderLoc_Category=TC_RETURNSUCCESS\nGroupImmediateOrder=0,0,boolean,group,unitordernotarg\n_GroupImmediateOrder_Defaults=GetUnitsInRectAll,UnitOrderStop\n_GroupImmediateOrder_Category=TC_RETURNSUCCESS\nGroupTrainOrderByIdBJ=0,0,boolean,group,unitcode\n_GroupTrainOrderByIdBJ_Defaults=GetUnitsInRectAll,hfoo\n_GroupTrainOrderByIdBJ_Category=TC_RETURNSUCCESS\nIssueNeutralImmediateOrderById=1,0,boolean,player,unit,unitcode\n_IssueNeutralImmediateOrderById_Defaults=Player00,_,nzep\n_IssueNeutralImmediateOrderById_Category=TC_RETURNSUCCESS\nGetUnitAbilityLevel=0,1,integer,unit,buffcode\n_GetUnitAbilityLevel_Defaults=GetTriggerUnit,_\n_GetUnitAbilityLevel_Category=TC_COMPATIBILITY\nAddSpellEffectByIdLoc=0,0,effect,abilcode,effecttype,location\n_AddSpellEffectByIdLoc_Defaults=_,EffectTypeTarget,GetRectCenter\n_AddSpellEffectByIdLoc_Category=TC_COMPATIBILITY\nAddSpellEffectById=0,0,effect,abilcode,effecttype,real,real\n_AddSpellEffectById_Defaults=_,EffectTypeTarget,0,0\n_AddSpellEffectById_Category=TC_COMPATIBILITY\nAddSpellEffectTargetById=0,0,effect,abilcode,effecttype,unit,string\n_AddSpellEffectTargetById_Defaults=_,EffectTypeTarget,GetLastCreatedUnit,\"origin\"\n_AddSpellEffectTargetById_Category=TC_COMPATIBILITY\nCreateMultiboard=1,0,multiboard\n_CreateMultiboard_Defaults=\n_CreateMultiboard_Category=TC_COMPATIBILITY\nMultiboardGetItem=1,0,multiboarditem,multiboard,integer,integer\n_MultiboardGetItem_Defaults=CreateMultiboard,_,_\n_MultiboardGetItem_Category=TC_COMPATIBILITY\nTriggerRegisterVariableEvent=0,1,event,trigger,AnyGlobal,limitop,null\n_TriggerRegisterVariableEvent_Defaults=GetTriggeringTrigger,_,LimitOpEqual,_\n_TriggerRegisterVariableEvent_Category=TC_COMPATIBILITY\nTriggerRegisterTimerExpireEvent=0,1,event,trigger,timer\n_TriggerRegisterTimerExpireEvent_Defaults=GetTriggeringTrigger,_\n_TriggerRegisterTimerExpireEvent_Category=TC_COMPATIBILITY\nTriggerRegisterDialogEvent=0,1,event,trigger,dialog\n_TriggerRegisterDialogEvent_Defaults=GetTriggeringTrigger,_\n_TriggerRegisterDialogEvent_Category=TC_COMPATIBILITY\nTriggerRegisterDialogButtonEvent=0,1,event,trigger,button\n_TriggerRegisterDialogButtonEvent_Defaults=GetTriggeringTrigger,_\n_TriggerRegisterDialogButtonEvent_Category=TC_COMPATIBILITY\nTriggerRegisterGameEvent=0,1,event,trigger,gameeventoption\n_TriggerRegisterGameEvent_Defaults=GetTriggeringTrigger,GameEventBuildSubMenu\n_TriggerRegisterGameEvent_Category=TC_COMPATIBILITY\nTriggerRegisterEnterRegion=0,1,event,trigger,region,boolexpr\n_TriggerRegisterEnterRegion_Defaults=GetTriggeringTrigger,_,_\n_TriggerRegisterEnterRegion_Category=TC_COMPATIBILITY\nTriggerRegisterLeaveRegion=0,1,event,trigger,region,boolexpr\n_TriggerRegisterLeaveRegion_Defaults=GetTriggeringTrigger,_,_\n_TriggerRegisterLeaveRegion_Category=TC_COMPATIBILITY\nTriggerRegisterPlayerEvent=0,1,event,trigger,player,playereventoption\n_TriggerRegisterPlayerEvent_Defaults=GetTriggeringTrigger,Player00,PlayerEventLeave\n_TriggerRegisterPlayerEvent_Category=TC_COMPATIBILITY\nTriggerRegisterPlayerUnitEventSimple=0,1,event,trigger,player,playerunitevent\n_TriggerRegisterPlayerUnitEventSimple_Defaults=GetTriggeringTrigger,Player00,PlayerUnitEventDeath\n_TriggerRegisterPlayerUnitEventSimple_Category=TC_COMPATIBILITY\nTriggerRegisterPlayerUnitEvent=0,1,event,trigger,player,playerunitevent,boolexpr\n_TriggerRegisterPlayerUnitEvent_Defaults=GetTriggeringTrigger,Player00,PlayerUnitEventDeath,_\n_TriggerRegisterPlayerUnitEvent_Category=TC_COMPATIBILITY\nTriggerRegisterPlayerStateEvent=0,1,event,trigger,player,playerstate,limitop,real\n_TriggerRegisterPlayerStateEvent_Defaults=GetTriggeringTrigger,Player00,PlayerStateGold,LimitOpGreaterThanOrEqual,1000\n_TriggerRegisterPlayerStateEvent_Category=TC_COMPATIBILITY\nTriggerRegisterPlayerChatEvent=0,1,event,trigger,player,string,chatmatchtype\n_TriggerRegisterPlayerChatEvent_Defaults=GetTriggeringTrigger,Player00,_,ChatMatchTypeExact\n_TriggerRegisterPlayerChatEvent_Category=TC_COMPATIBILITY\nTriggerRegisterDeathEvent=0,1,event,trigger,destructable\n_TriggerRegisterDeathEvent_Defaults=GetTriggeringTrigger,_\n_TriggerRegisterDeathEvent_Category=TC_COMPATIBILITY\nTriggerRegisterUnitStateEvent=0,1,event,trigger,unit,unitstate,limitop,real\n_TriggerRegisterUnitStateEvent_Defaults=GetTriggeringTrigger,_,UnitStateLife,LimitOpGreaterThanOrEqual,100\n_TriggerRegisterUnitStateEvent_Category=TC_COMPATIBILITY\nTriggerRegisterUnitEvent=0,1,event,trigger,unit,unitevent\n_TriggerRegisterUnitEvent_Defaults=GetTriggeringTrigger,_,UnitEventDeath\n_TriggerRegisterUnitEvent_Category=TC_COMPATIBILITY\nTriggerRegisterUnitInRangeSimple=0,1,event,trigger,real,unit\n_TriggerRegisterUnitInRangeSimple_Defaults=GetTriggeringTrigger,100,_\n_TriggerRegisterUnitInRangeSimple_Defaults=GetTriggeringTrigger,100,_,_,_\n_TriggerRegisterUnitInRangeSimple_Category=TC_COMPATIBILITY\nTriggerAddAction=0,1,triggeraction,trigger,code\n_TriggerAddAction_Defaults=GetTriggeringTrigger,_\n_TriggerAddAction_Category=TC_COMPATIBILITY\nTriggerAddCondition=0,1,triggercondition,trigger,boolexpr\n_TriggerAddCondition_Defaults=GetTriggeringTrigger,_\n_TriggerAddCondition_Category=TC_COMPATIBILITY\n[DefaultTriggerCategories]\nNumCategories=1\nCategory01=WESTRING_INITIALIZATION\n[DefaultTriggers]\nNumTriggers=1\nTrigger01Name=WESTRING_MELEEINITIALIZATION\nTrigger01Comment=WESTRING_MELEEINITIALIZATION_COMMENT\nTrigger01Category=1\nTrigger01Events=1\nTrigger01Event01=MapInitializationEvent\nTrigger01Conditions=0\nTrigger01Actions=8\nTrigger01Action01=MeleeStartingVisibility\nTrigger01Action02=MeleeStartingHeroLimit\nTrigger01Action03=MeleeGrantHeroItems\nTrigger01Action04=MeleeStartingResources\nTrigger01Action05=MeleeClearExcessUnits\nTrigger01Action06=MeleeStartingUnits\nTrigger01Action07=MeleeStartingAI\nTrigger01Action08=MeleeInitVictoryDefeat\n"
  },
  {
    "path": "clients/weu/TriggerDataYDWE.txt",
    "content": "\n\n\n\n\n\n\n\n\n\n\n\n//***************************************************************************\n[TriggerCategories]\n// Defines categories for organizing trigger functions\n// Key: Arbitrary category identifier\n\n// Value 0: Display text\n// Value 1: Icon image file\n// Value 2: Optional flag (defaults to 0) indicating to disable display of category name\n//\n\n\n//最萌小汐\nTC_MU_BAKA=专用库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_BASE=基础库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_EVENT=事件库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_MATH=数学库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_STRING=字符串库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_UNIT=单位库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_ITEM=物品库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_TEXT=漂浮文字库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_EFFECT=特效库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_SOUND=音效库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_PROCESS=过程库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_MU_MOVER=弹幕库<MU>,ReplaceableTextures\\WorldEditUI\\Actions-Game\n\nTC_ARITHMETIC=WESTRING_TRIGCAT_ARITHMETIC,ReplaceableTextures\\WorldEditUI\\Actions-AI,1\nTC_NOTHING=WESTRING_TRIGCAT_NOTHING,ReplaceableTextures\\CommandButtons\\BTNPillage.blp,1\nTC_COMMENT=WESTRING_TRIGCAT_COMMENT,ReplaceableTextures\\WorldEditUI\\Actions-Comment,1\nTC_CUSTOM=WESTRING_TRIGCAT_CUSTOM,ReplaceableTextures\\CommandButtons\\BTNSpellSteal.blp,1\nTC_CONDITION=WESTRING_TRIGCAT_CONDITION,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_WAIT=WESTRING_TRIGCAT_WAIT,ReplaceableTextures\\WorldEditUI\\Actions-Wait,1\nTC_SETVARIABLE=WESTRING_TRIGCAT_SETVARIABLE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables,1\nTC_SKIPACTIONS=WESTRING_TRIGCAT_SKIPACTIONS,ReplaceableTextures\\CommandButtons\\BTNTemp.blp,1\nTC_LOGIC=WESTRING_TRIGCAT_LOGIC,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_FORLOOP=WESTRING_TRIGCAT_FORLOOP,ReplaceableTextures\\WorldEditUI\\Actions-Logical,1\nTC_LAST=WESTRING_TRIGCAT_LAST,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables,1\nTC_YDAB=技能[YDWE],ReplaceableTextures\\CommandButtons\\BTNImmolationOn.blp\nTC_YDST=系统[YDWE],ReplaceableTextures\\CommandButtons\\BTNMetamorphosis.blp\nTC_YDFC=函数[YDWE],ReplaceableTextures\\CommandButtons\\BTNEvasion.blp\nTC_YDLD=存储[YDWE],ReplaceableTextures\\CommandButtons\\BTNLoad.blp\nTC_YDSE=特效[YDWE],ReplaceableTextures\\PassiveButtons\\PASBTNFeedBack.blp\n\nTC_YDLC=变量[YDWE],ReplaceableTextures\\WorldEditUI\\Editor-ScriptVariable.blp,1\n\n\n\nTC_YDAI=AI[YDWE],ReplaceableTextures\\CommandButtons\\BTNHeroTinker.blp\nTC_YDET=事件[YDWE],UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon.blp\nTC_YDBF=逆天[YDWE],ReplaceableTextures\\CommandButtons\\BTNInfernal.blp\nTC_YDSL=存档[YDWE],ReplaceableTextures\\CommandButtons\\BTNTome.blp\nTC_SCRIPTSET=电影<Script System>,ReplaceableTextures\\WorldEditUI\\Doodad-Cinematic.blp\nTC_AI=WESTRING_TRIGCAT_AI,ReplaceableTextures\\WorldEditUI\\Actions-AI\nTC_TRIGGER=WESTRING_TRIGCAT_TRIGGER,ReplaceableTextures\\CommandButtons\\BTNEngineeringUpgrade.blp\nTC_UNIT=WESTRING_TRIGCAT_UNIT,ReplaceableTextures\\WorldEditUI\\Actions-Unit\nTC_UNITPOOL=单位池,ReplaceableTextures\\WorldEditUI\\Actions-Unit\nTC_UNITGROUP=WESTRING_TRIGCAT_UNITGROUP,ReplaceableTextures\\WorldEditUI\\Actions-UnitGroup\nTC_UBERSPLAT=WESTRING_TRIGCAT_UBERSPLAT,ReplaceableTextures\\CommandButtons\\BTNEarthquake.blp\nTC_LOCATION=点,ReplaceableTextures\\CommandButtons\\BTNStun.blp\nTC_CINEMATIC=WESTRING_TRIGCAT_CINEMATIC,ReplaceableTextures\\WorldEditUI\\Actions-Camera\nTC_ANIMATION=WESTRING_TRIGCAT_ANIMATION,ReplaceableTextures\\WorldEditUI\\Actions-Animation\nTC_DIALOG=WESTRING_TRIGCAT_DIALOG,ReplaceableTextures\\WorldEditUI\\Actions-Dialog\nTC_MELEE=WESTRING_TRIGCAT_MELEE,ReplaceableTextures\\WorldEditUI\\Actions-Melee\nTC_MULTIBOARD=WESTRING_TRIGCAT_MULTIBOARD,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_ENVIRONMENT=WESTRING_TRIGCAT_ENVIRONMENT,ReplaceableTextures\\WorldEditUI\\Actions-Environment\nTC_CAMERA=WESTRING_TRIGCAT_CAMERA,ReplaceableTextures\\WorldEditUI\\Actions-Camera\nTC_TIMER=WESTRING_TRIGCAT_TIMER,ReplaceableTextures\\WorldEditUI\\Events-Time\nTC_VISIBILITY=WESTRING_TRIGCAT_VISIBILITY,ReplaceableTextures\\WorldEditUI\\Actions-Visibility\nTC_DESTRUCT=WESTRING_TRIGCAT_DESTRUCT,ReplaceableTextures\\WorldEditUI\\Actions-Destructibles\nTC_TRACKABLE=可追踪物,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_LEADERBOARD=WESTRING_TRIGCAT_LEADERBOARD,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_TEXTTAG=WESTRING_TRIGCAT_TEXTTAG,ReplaceableTextures\\CommandButtons\\BTNSpy.blp\nTC_REGION=区域(不规则),ReplaceableTextures\\WorldEditUI\\Actions-Region\nTC_RECT=区域(矩形),ReplaceableTextures\\WorldEditUI\\Actions-Region\nTC_YDID=获取整数,ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp\nTC_QUEST=WESTRING_TRIGCAT_QUEST,ReplaceableTextures\\WorldEditUI\\Actions-Quest\nTC_LIGHTNING=WESTRING_TRIGCAT_LIGHTNING,ReplaceableTextures\\CommandButtons\\BTNChainLightning.blp\nTC_EVENTRESPONSE=WESTRING_TRIGCAT_EVENTRESPONSE,ReplaceableTextures\\CommandButtons\\BTNBerserkForTrolls.blp\nTC_SOUND=WESTRING_TRIGCAT_SOUND,ReplaceableTextures\\WorldEditUI\\Actions-Sound\nTC_TIME=WESTRING_TRIGCAT_TIME,ReplaceableTextures\\WorldEditUI\\Events-Time\nTC_MATH=WESTRING_TRIGCAT_MATH,ReplaceableTextures\\WorldEditUI\\Actions-Logical\nTC_SPECIALEFFECT=WESTRING_TRIGCAT_SPECIALEFFECT,ReplaceableTextures\\WorldEditUI\\Actions-Animation\nTC_IMAGE=WESTRING_TRIGCAT_IMAGE,ReplaceableTextures\\CommandButtons\\BTNStaffOfPreservation.blp\nTC_PLAYER=WESTRING_TRIGCAT_PLAYER,ReplaceableTextures\\WorldEditUI\\Actions-Player\nTC_PLAYERGROUP=WESTRING_TRIGCAT_PLAYERGROUP,ReplaceableTextures\\WorldEditUI\\Actions-PlayerGroup\nTC_ITEM=WESTRING_TRIGCAT_ITEM,ReplaceableTextures\\WorldEditUI\\Actions-Item\nTC_ITEMPOOL=物品池,ReplaceableTextures\\WorldEditUI\\Actions-Item\nTC_UNITSEL=WESTRING_TRIGCAT_UNITSEL,ReplaceableTextures\\WorldEditUI\\Actions-UnitSelection\nTC_HERO=WESTRING_TRIGCAT_HERO,ReplaceableTextures\\WorldEditUI\\Actions-Hero\nTC_WIDGET=物体,ReplaceableTextures\\CommandButtons\\BTNBox.blp\nTC_GAME=WESTRING_TRIGCAT_GAME,ReplaceableTextures\\WorldEditUI\\Actions-Game\nTC_GAMECACHE=WESTRING_TRIGCAT_GAMECACHE,ReplaceableTextures\\WorldEditUI\\Actions-SetVariables\nTC_NEUTRALBUILDING=WESTRING_TRIGCAT_NEUTRALBUILDING,ReplaceableTextures\\WorldEditUI\\Actions-Goldmine\nTC_CONVERSION=WESTRING_TRIGCAT_CONVERSION,ReplaceableTextures\\WorldEditUI\\Actions-AI\nTC_HASHTABLE=WESTRING_TRIGCAT_HASHTABLE,ReplaceableTextures\\WorldEditUI\\Editor-Toolbar-SaveMap\n//%%% DEBUG - Remove for retail\nTC_OBSOLETE=WESTRING_TRIGCAT_OBSOLETE,ReplaceableTextures\\WorldEditUI\\Editor-TriggerFunction\nTC_DEBUG=WESTRING_TRIGCAT_DEBUG,ReplaceableTextures\\WorldEditUI\\Editor-TriggerFunction\nTC_YDHIDE=不推荐使用,ReplaceableTextures\\CommandButtons\\BTNCancel.blp\n\n// AI Editor only\nTC_AI_TOWN=WESTRING_TRIGCAT_AI_TOWN,none\nTC_AI_HERO=WESTRING_TRIGCAT_AI_HERO,none\nTC_AI_RESOURCES=WESTRING_TRIGCAT_AI_RESOURCES,none\nTC_AI_MISC=WESTRING_TRIGCAT_AI_MISC,none\nTC_AI_UNIT=WESTRING_TRIGCAT_AI_UNIT,none\nTC_AI_UPGRADE=WESTRING_TRIGCAT_AI_UPGRADE,none\nTC_AI_COMMAND=WESTRING_TRIGCAT_AI_COMMAND,none\n\n\n//***************************************************************************\n[TriggerTypes]\n\n// Defines all trigger variable types to be used by the Script Editor\n// Key: type name\n// Value 0: first game version in which this type is valid\n// Value 1: flag (0 or 1) indicating if this type can be a global variable\n// Value 2: flag (0 or 1) indicating if this type can be used with comparison operators\n// Value 3: string to display in the editor\n// Value 4: base type, used only for custom types\n// Value 5: import type, for strings which represent files (optional)\n// Value 6: flag (0 or 1) indicating to treat this type as the base type in the editor\n\n// Trigger Variable Types\n// These are sorted so that they appear as such in the Variables dialog.\nboolean=0,1,1,WESTRING_TRIGTYPE_boolean\ninteger=0,1,1,WESTRING_TRIGTYPE_integer\nreal=0,1,1,WESTRING_TRIGTYPE_real\nstring=0,1,1,WESTRING_TRIGTYPE_string\ndestructable=0,1,1,WESTRING_TRIGTYPE_destructable\ndestructablecode=0,1,1,WESTRING_TRIGTYPE_destructablecode,integer\nitem=0,1,1,WESTRING_TRIGTYPE_item\nitemcode=0,1,1,WESTRING_TRIGTYPE_itemcode,integer\nitempool=0,1,0,物品池\nunit=0,1,1,WESTRING_TRIGTYPE_unit\ngroup=0,1,0,WESTRING_TRIGTYPE_group\nunitcode=0,1,1,WESTRING_TRIGTYPE_unitcode,integer\nunitpool=0,1,0,单位池\nplayer=0,1,1,WESTRING_TRIGTYPE_player\nforce=0,1,0,WESTRING_TRIGTYPE_force\nlocation=0,1,1,WESTRING_TRIGTYPE_location\nrect=0,1,1,WESTRING_TRIGTYPE_rect\nregion=0,1,1,不规则区域\ntrigger=0,1,1,WESTRING_TRIGTYPE_trigger\ndialog=0,1,0,WESTRING_TRIGTYPE_dialog\nbutton=0,1,0,WESTRING_TRIGTYPE_button\ntimer=0,1,0,WESTRING_TRIGTYPE_timer\ntimerdialog=0,1,0,WESTRING_TRIGTYPE_timerdialog\ntexttag=1,1,0,WESTRING_TRIGTYPE_texttag\nleaderboard=0,1,0,WESTRING_TRIGTYPE_leaderboard\nmultiboard=1,1,0,WESTRING_TRIGTYPE_multiboard\nmultiboarditem=1,1,0,多面板项目\ncamerasetup=0,1,0,WESTRING_TRIGTYPE_camerasetup\ntrackable=0,1,0,可追踪物\nimage=1,1,1,WESTRING_TRIGTYPE_image\nsound=0,1,0,WESTRING_TRIGTYPE_sound\neffect=0,1,0,WESTRING_TRIGTYPE_effect\nlightning=1,1,1,WESTRING_TRIGTYPE_lightning\nwidget=0,1,1,物体\ngamecache=0,1,0,WESTRING_TRIGTYPE_gamecache\nabilcode=0,1,1,WESTRING_TRIGTYPE_abilcode,integer\nbuffcode=1,1,1,WESTRING_TRIGTYPE_buffcode,integer\nordercode=0,1,1,WESTRING_TRIGTYPE_ordercode,integer\nrace=0,1,1,WESTRING_TRIGTYPE_race\nquest=0,1,0,WESTRING_TRIGTYPE_quest\nquestitem=0,1,0,WESTRING_TRIGTYPE_questitem\ntechcode=0,1,1,WESTRING_TRIGTYPE_techcode,integer\nterraindeformation=1,1,0,WESTRING_TRIGTYPE_terraindeformation\nubersplat=1,1,1,WESTRING_TRIGTYPE_ubersplat\nfogmodifier=0,1,0,WESTRING_TRIGTYPE_fogmodifier\nweathereffect=0,1,0,WESTRING_TRIGTYPE_weathereffect\nboolexpr=0,1,0,布尔表达式\nradian=0,1,1,弧度,real\ndegree=0,1,1,角度,real\nhashtable=0,1,0,WESTRING_TRIGTYPE_hashtable\ncode=0,1,0,WESTRING_TRIGTYPE_code\n\nhandle=0,0,0,WESTRING_TRIGTYPE_handle\nagent=0,0,0,WESTRING_TRIGTYPE_agent,agent\n\ntypename=1,0,0,参数类型,string\nobjecttype=1,0,0,物体类型,string\n\nunitstatechangetype=0,0,0,单位状态修改类型,integer\nbonusType=0,0,0,属性类型,integer\neventid=0,0,0,事件ID\nevent=0,0,0,WESTRING_TRIGTYPE_event\ntriggercondition=0,0,0,WESTRING_TRIGTYPE_triggercondition\ntriggeraction=0,0,0,WESTRING_TRIGTYPE_triggeraction\ndefeatcondition=0,0,0,WESTRING_TRIGTYPE_defeatcondition\ngamespeed=0,0,1,WESTRING_TRIGTYPE_gamespeed\nplayercolor=0,0,1,WESTRING_TRIGTYPE_playercolor\n\nitemtype=1,0,1,WESTRING_TRIGTYPE_itemtype\neffecttype=1,0,1,WESTRING_TRIGTYPE_effecttype\npathingtype=1,0,1,WESTRING_TRIGTYPE_pathingtype\nattacktype=1,0,1,WESTRING_TRIGTYPE_attacktype\nweapontype=1,0,1,WESTRING_TRIGTYPE_weapontype\ndamagetype=1,0,1,WESTRING_TRIGTYPE_damagetype\nlightningtype=1,0,1,WESTRING_TRIGTYPE_lightningtype,string\nsoundtype=1,0,1,WESTRING_TRIGTYPE_soundtype\nimagetype=1,0,1,WESTRING_TRIGTYPE_imagetype,integer\nterrainshape=1,0,1,WESTRING_TRIGTYPE_terrainshape,integer\nterraintype=1,0,1,WESTRING_TRIGTYPE_terraintype,integer\nubersplattype=1,0,1,WESTRING_TRIGTYPE_ubersplattype,string\n\n// Trigger Non-Variable Types - Atomic (built-in to the language)\n//removeguardtype=0,0,0,整数,integer\n//targetattach=0,1,1,身体部位,string\nturnclockwise=0,0,1,单位转向类型,integer\nheadORchest=0,0,1,头部或胸部,integer\ncamerachangetype=0,0,1,镜头切换方式,integer\ncamerastattype=0,0,1,镜头参数类型,integer\ncameratgnoreterrain=0,0,1,镜头忽略悬崖,boolean\nattackorattackedevent=0,0,1,事件类型,integer\ntargettype=0,0,1,目标类型,integer\n\n// Trigger Non-Variable Types - Basic (from common.j)\nunittype=0,0,0,WESTRING_TRIGTYPE_unittype\nalliancetype=0,0,0,WESTRING_TRIGTYPE_alliancetype\nplayerstate=0,0,0,WESTRING_TRIGTYPE_playerstate\nplayerscore=1,0,0,WESTRING_TRIGTYPE_playerscore\nplayergameresult=0,0,0,WESTRING_TRIGTYPE_playergameresult\nunitstate=0,0,0,WESTRING_TRIGTYPE_unitstate\nplayerunitevent=0,0,0,WESTRING_TRIGTYPE_playerunitevent\nunitevent=0,0,0,WESTRING_TRIGTYPE_unitevent\nlimitop=0,0,0,WESTRING_TRIGTYPE_limitop\ngamedifficulty=0,0,1,WESTRING_TRIGTYPE_gamedifficulty\ngameevent=1,0,0,WESTRING_TRIGTYPE_gameevent\naidifficulty=0,0,1,WESTRING_TRIGTYPE_aidifficulty\nmapdensity=0,0,1,WESTRING_TRIGTYPE_mapdensity\nmapcontrol=0,0,1,WESTRING_TRIGTYPE_mapcontrol\nmapflag=0,0,0,WESTRING_TRIGTYPE_mapflag\nplayerslotstate=0,0,1,WESTRING_TRIGTYPE_playerslotstate\ncamerafield=0,0,0,WESTRING_TRIGTYPE_camerafield\nraritycontrol=0,0,0,WESTRING_TRIGTYPE_raritycontrol\nblendmode=0,0,0,WESTRING_TRIGTYPE_blendmode\nfogstate=0,0,0,WESTRING_TRIGTYPE_fogstate\nvolumegroup=0,0,0,WESTRING_TRIGTYPE_volumegroup\n\n// Trigger Non-Variable Types - Utility, only used to simplify triggers\nkeyeventtype=1,0,0,WESTRING_TRIGTYPE_keyeventtype,integer\nkeyeventkey=1,0,0,WESTRING_TRIGTYPE_keyeventkey,integer\ncolorchangeoption=0,0,0,WESTRING_TRIGTYPE_colorchangeoption,boolean\nplayerchangecoloroption=0,0,0,WESTRING_TRIGTYPE_playerchangecoloroption,boolean\nchatmatchtype=0,0,0,WESTRING_TRIGTYPE_chatmatchtype,boolean\nunitfacingbone=0,0,0,WESTRING_TRIGTYPE_unitfacingbone,string\nincludeoption=0,0,0,WESTRING_TRIGTYPE_inclusionoption,boolean\ncameraapplyoption=0,0,0,WESTRING_TRIGTYPE_cameraapplyoption,boolean\ncameraorientationoption=0,0,0,WESTRING_TRIGTYPE_cameraorientationoption,boolean\ninvulnerableoption=0,0,0,WESTRING_TRIGTYPE_invulnerableoption,boolean\navailabilityoption=0,0,0,WESTRING_TRIGTYPE_availabilityoption,boolean\nshowhideoption=0,0,0,WESTRING_TRIGTYPE_showhideoption,boolean\nminimizeoption=1,0,0,WESTRING_TRIGTYPE_minimizeoption,boolean\nskymodelstring=0,0,0,WESTRING_TRIGTYPE_skymodelstring,string,Model\ncinefiltertexture=0,0,0,WESTRING_TRIGTYPE_cinefiltertexture,string,Image\npathingoption=0,0,0,WESTRING_TRIGTYPE_pathingoption,boolean\npawnableoption=1,0,0,WESTRING_TRIGTYPE_pawnableoption,boolean\ndropnodropoption=0,0,0,WESTRING_TRIGTYPE_dropnodropoption,boolean\ndroppableoption=0,0,0,WESTRING_TRIGTYPE_droppableoption,boolean\nbeforeafteroption=0,0,0,WESTRING_TRIGTYPE_beforeafteroption,boolean\nonoffoption=0,0,0,WESTRING_TRIGTYPE_onoffoption,boolean\nenabledisableoption=0,0,0,WESTRING_TRIGTYPE_enabledisableoption,boolean\nenableddisabledoption=0,0,0,WESTRING_TRIGTYPE_enableddisabledoption,boolean\nrescuableoption=0,0,0,WESTRING_TRIGTYPE_rescuableoption,boolean\nallowdontoption=0,0,0,WESTRING_TRIGTYPE_allowdontoption,boolean\nfadedontoption=0,0,0,WESTRING_TRIGTYPE_fadedontoption,boolean\nunitorderutarg=0,0,0,WESTRING_TRIGTYPE_unitorderutarg,string\nunitorderptarg=0,0,0,WESTRING_TRIGTYPE_unitorderptarg,string\nunitorderdtarg=0,0,0,WESTRING_TRIGTYPE_unitorderdtarg,string\nunitorderitarg=1,0,0,WESTRING_TRIGTYPE_unitorderitarg,string\nunitordernotarg=0,0,0,WESTRING_TRIGTYPE_unitordernotarg,string\nordercodeutarg=0,0,0,WESTRING_TRIGTYPE_unitorderutarg,integer\nordercodeptarg=0,0,0,WESTRING_TRIGTYPE_unitorderptarg,integer\nordercodedtarg=0,0,0,WESTRING_TRIGTYPE_unitorderdtarg,integer\nordercodeitarg=1,0,0,WESTRING_TRIGTYPE_unitorderitarg,integer\nordercodenotarg=0,0,0,WESTRING_TRIGTYPE_unitordernotarg,integer\nheroskillcode=0,0,0,WESTRING_TRIGTYPE_heroskillcode,integer\nweathereffectcode=0,0,0,WESTRING_TRIGTYPE_weathereffectcode,integer\nalliancesetting=0,0,0,WESTRING_TRIGTYPE_alliancesetting,integer\naddsettooption=0,0,0,WESTRING_TRIGTYPE_addsettooption,integer\nmodifymethod=1,0,0,WESTRING_TRIGTYPE_modifymethod,integer\nwaitdontoption=0,0,0,WESTRING_TRIGTYPE_waitdontoption,boolean\ncratertype=1,0,0,WESTRING_TRIGTYPE_cratertype,boolean\nrippletype=1,0,0,WESTRING_TRIGTYPE_rippletype,boolean\ncreateremoveoption=0,0,0,WESTRING_TRIGTYPE_createremoveoption,boolean\naddremoveoption=0,0,0,WESTRING_TRIGTYPE_addremoveoption,boolean\nquesttypeoption=0,0,0,WESTRING_TRIGTYPE_questtypeoption,integer\nquestmessagetype=0,0,0,WESTRING_TRIGTYPE_questmessagetype,integer\nherostat=1,0,0,WESTRING_TRIGTYPE_herostat,integer\ncompletionoption=0,0,0,WESTRING_TRIGTYPE_completionoption,boolean\nfailureoption=0,0,0,WESTRING_TRIGTYPE_failureoption,boolean\ndiscoveredoption=0,0,0,WESTRING_TRIGTYPE_discoveredoption,boolean\npauseresumeoption=0,0,0,WESTRING_TRIGTYPE_pauseresumeoption,boolean\nperiodicoption=0,0,0,WESTRING_TRIGTYPE_periodicoption,boolean\nleaderboardsortoption=0,0,0,WESTRING_TRIGTYPE_leaderboardsortoption,integer\nascendingoption=0,0,0,WESTRING_TRIGTYPE_ascendingoption,boolean\nsleepwakeoption=0,0,0,WESTRING_TRIGTYPE_sleepwakeoption,boolean\npauseunpauseoption=0,0,0,WESTRING_TRIGTYPE_pauseunpauseoption,boolean\nsharedontoption=0,0,0,WESTRING_TRIGTYPE_sharedontoption,boolean\nfadetypeoption=0,0,0,WESTRING_TRIGTYPE_fadetypeoption,boolean\nbufftype=0,0,0,WESTRING_TRIGTYPE_bufftype,integer\nbuffpolarity=1,0,0,WESTRING_TRIGTYPE_buffpolarity,integer\nbuffresist=1,0,0,WESTRING_TRIGTYPE_buffresist,integer\ncameraboundsadjusttype=0,0,0,WESTRING_TRIGTYPE_cameraboundsadjusttype,integer\navailableoption=0,0,0,WESTRING_TRIGTYPE_availableoption,boolean\nexplodedontoption=0,0,0,WESTRING_TRIGTYPE_explodedontoption,boolean\nsuspendresumeoption=0,0,0,WESTRING_TRIGTYPE_suspendresumeoption,boolean\nsuspendresumeoption_R=0,0,0,WESTRING_TRIGTYPE_suspendresumeoption,boolean\n\nmissionindex=0,0,0,WESTRING_TRIGTYPE_missionindex,integer\ncampaignindex=0,0,0,WESTRING_TRIGTYPE_campaignindex,integer\ncinematicindex=0,0,0,WESTRING_TRIGTYPE_cinematicindex,integer\nmusictheme=0,0,0,WESTRING_TRIGTYPE_musictheme,string,Sound\nambientthemeday=0,0,0,WESTRING_TRIGTYPE_ambientthemeday,string\nambientthemenight=0,0,0,WESTRING_TRIGTYPE_ambientthemenight,string\nunitstatemethod=0,0,0,WESTRING_TRIGTYPE_unitstatemethod,string\ncheckingignoringoption=0,0,0,WESTRING_TRIGTYPE_checkingignoringoption,string\nplayerflag=0,0,0,WESTRING_TRIGTYPE_playerflag,playerstate\nplayerresource=1,0,0,WESTRING_TRIGTYPE_playerresource,playerstate\ngateoperation=0,0,0,WESTRING_TRIGTYPE_gateoperation,integer\nelevatorwallop=1,0,0,WESTRING_TRIGTYPE_elevatorwallop,boolean\nelevatorwalltype=1,0,0,WESTRING_TRIGTYPE_elevatorwalltype,integer\nuseskipoption=0,0,0,WESTRING_TRIGTYPE_useskipoption,boolean\nseldeseloption=0,0,0,WESTRING_TRIGTYPE_seldeseloption,boolean\ncachevaluetype=1,0,0,WESTRING_TRIGTYPE_cachevaluetype,integer\nfogstyle=0,0,0,WESTRING_TRIGTYPE_fogstyle,integer\ntimedlifebuffcode=1,0,0,WESTRING_TRIGTYPE_timedlifebuffcode,integer\naicaptaintype=1,0,0,WESTRING_TRIGTYPE_aicaptaintype,boolean\naicommandpop=1,0,0,WESTRING_TRIGTYPE_aicommandpop,boolean\nscriptcode=1,0,0,WESTRING_TRIGTYPE_scriptcode,string\nitemstatus=1,0,0,WESTRING_TRIGTYPE_itemstatus,integer\nitemcodestatus=1,0,0,WESTRING_TRIGTYPE_itemcodestatus,integer\nminimappingstyle=1,0,0,WESTRING_TRIGTYPE_minimappingstyle,integer\ncorpsetype=1,0,0,WESTRING_TRIGTYPE_corpsetype,integer\nstringcaseoption=1,0,0,WESTRING_TRIGTYPE_stringcaseoption,boolean\nhashtablevaluetype=1,0,0,WESTRING_TRIGTYPE_hashtablevaluetype,integer\n//=============== Added Custom Types ==================\nunitstatesec=0,0,0,WESTRING_TRIGTYPE_unitstate,unitstate\nnearestonlyoption=0,0,0,选取方式,boolean\nvertonlyoption=0,0,0,晃动方式,boolean\nincludeoptionnot=0,0,0,WESTRING_TRIGTYPE_inclusionoption,boolean\nunittypeaddable=0,0,0,WESTRING_TRIGTYPE_unittype,unittype\nisnotoption=0,0,0,判断选项,boolean\npingstyle=1,0,0,WESTRING_TRIGTYPE_minimappingstyle,boolean\nhotkeyint=0,0,0,快捷键,integer\nsharevisionoption=0,0,0,共享视野选项,boolean\nconverunitoption=0,0,0,覆盖选项,boolean\nlockunlockoption=0,0,0,锁定选项,boolean\nonoffintoption=0,0,0,WESTRING_TRIGTYPE_onoffoption,integer\nonoffnotoption=0,0,0,WESTRING_TRIGTYPE_onoffoption,boolean\n\n// Trigger Non-Variable Types - File strings\naiscript=0,0,0,WESTRING_TRIGTYPE_aiscript,string,AIScript,1\nmodelfile=0,0,0,WESTRING_TRIGTYPE_modelfile,string,Model,1\nanyfile=0,0,0,WESTRING_TRIGTYPE_anyfile,string,Any,1\npreloadfile=0,0,0,WESTRING_TRIGTYPE_preloadfile,string,Preload,1\nimagefile=0,0,0,WESTRING_TRIGTYPE_imagefile,string,Image,1\n\n// Trigger Non-Variable Types - Custom (handled internally by the editor)\nStringExt=0,0,0,WESTRING_TRIGTYPE_StringExt,string\nAnyGlobal=0,0,0,WESTRING_TRIGTYPE_AnyGlobal\nAnyType=0,0,0,WESTRING_TRIGTYPE_AnyType\nVarAsString_Real=0,0,0,WESTRING_TRIGTYPE_VarAsString_Real\nArithmeticOperator=0,0,0,WESTRING_TRIGTYPE_ArithmeticOperator\nComparisonOperator=0,0,0,WESTRING_TRIGTYPE_ComparisonOperator\nEqualNotEqualOperator=0,0,0,WESTRING_TRIGTYPE_EqualNotEqualOperator\nboolcall=0,0,0,WESTRING_TRIGTYPE_boolcall\neventcall=1,0,0,WESTRING_TRIGTYPE_eventcall\ndoodadcode=0,0,0,WESTRING_TRIGTYPE_doodadcode,integer\nmusicfile=0,0,0,WESTRING_TRIGTYPE_musicfile,string\nintegervar=1,0,0,WESTRING_TRIGTYPE_integer,integer\n\nabilevent=0,0,0,技能类型,integer\nracepreference=0,0,0,种族选项\n\nAbilityState=0,0,0,技能属性,integer\nAbilityDataInteger=0,0,0,技能数据 (整数),integer\nAbilityDataReal=0,0,0,技能数据 (实数),integer\nAbilityDataString=0,0,0,技能数据 (字符串),integer\nChatRecipient=0,0,0,频道类型,integer\n\n//最萌小汐\nskillType=0,0,0,技能阶段,integer\ndamageTypeA=0,0,0,单位类型,integer\ndamageTypeB=0,0,0,伤害类型,integer\nhealType=0,0,0,治疗类型,integer\ntypename=0,0,0,变量类型,scriptcode\nremoveWhichLocation=0,0,0,清除哪个点,integer\nDisOrAng=0,0,0,距离/方向,integer\nshowTo=0,0,0,漂浮文字可见性,integer\nisLuck=0,0,0,神符效果,boolean\nmover_state_real=0,0,0,弹幕属性(实数),integer\nSkillBarEndReason=0,0,0,技能进度条事件原因,integer\nitemPickDrop=0,0,0,获得还是丢弃,integer\nadd_remove=0,0,0,添加或移除,boolean\ncrit_crited=0,0,0,暴击模块对象,integer\nhit_dodg=0,0,0,命中闪躲模块对象,integer\nhit_dodg_crit=0,0,0,命中闪躲暴击模块对象,integer\nunit_response_type=0,0,0,单位回应类型,integer\n\n\n//***************************************************************************\n[TriggerTypeDefaults]\n// Defines an optional default value for a trigger type used as a global variable\n// Key: variable type\n// Value 0: script text\n// Value 1: display text (if not present, script text will be used)\n//\n// If a type does not have an entry here, it will be set to null if it is a handle\n//\n\nboolean=false,WESTRING_FALSE\ninteger=0\nreal=0\ngroup=CreateGroup(),WESTRING_TRIGDEFAULT_GROUP\nforce=CreateForce(),WESTRING_TRIGDEFAULT_FORCE\ntimer=CreateTimer(),WESTRING_TRIGDEFAULT_TIMER\ndialog=DialogCreate(),WESTRING_TRIGDEFAULT_DIALOG\nregion=CreateRegion(),新建不规则区域\n\n\n\n\n//***************************************************************************\n[TriggerParams]\n// Defines possible values for variable types\n// Key: arbitrary text\n// Value 0: first game version in which this parameter is valid\n// Value 1: variable type\n// Value 2: code text (used in script)\n// Value 3: display text\n//\n// Note: If the code text is a literal string, surround it with backward single quotes (`),\n//       and they will be converted to double quotes in the script.\n//\n\n//最萌小汐\nskillTypeA=0,skillType,1,准备施放\nskillTypeB=0,skillType,2,开始施放\nskillTypeC=0,skillType,3,发动了\nskillTypeD=0,skillType,4,停止施放\nskillTypeE=0,skillType,5,结束施放\n\ndamageTypeA1=0,damageTypeA,0,任意单位\ndamageTypeA2=0,damageTypeA,1,英雄单位\ndamageTypeA3=0,damageTypeA,2,普通单位\n\ndamageTypeB1=0,damageTypeB,0,任意伤害\ndamageTypeB2=0,damageTypeB,1,攻击伤害\ndamageTypeB3=0,damageTypeB,2,非攻击伤害\ndamageTypeB4=0,damageTypeB,3,致命伤害\ndamageTypeB5=0,damageTypeB,4,暴击伤害\n\nhealType1=0,healType,0,治疗\nhealType2=0,healType,0,治疗(结算)\n\nmover_state_real1=0,mover_state_real,1,在原力场中降低的移动速度(%)\nmover_state_real2=0,mover_state_real,2,在原力场中受到的额外斥力(%)\n\nitemPickDrop1=0,itemPickDrop,0,获得\nitemPickDrop2=0,itemPickDrop,1,失去\n\nadd_remove_add=0,add_remove,true,添加\nadd_remove_remove=0,add_remove,false,移除\n\ncrit_crited_crit=0,crit_crited,0,暴击\ncrit_crited_crited=0,crit_crited,1,被暴击\n\nhit_dodg_hit=0,hit_dodg,0,命中\nhit_dodg_dodg=0,hit_dodg,1,闪躲\n\nhit_dodg_crit_hit=0,hit_dodg_crit,0,命中\nhit_dodg_crit_dodg=0,hit_dodg_crit,1,闪躲\nhit_dodg_crit_crit=0,hit_dodg_crit,2,暴击\n\nunit_response_type1=0,unit_response_type,1,选中回应\nunit_response_type2=0,unit_response_type,2,移动回应\nunit_response_type3=0,unit_response_type,3,攻击回应\n\n//YDWE 修改属性\nbonusTypeC=0,bonusType,3,攻击\nbonusTypeD=0,bonusType,2,防御(*0.01)\nbonusTypeA=0,bonusType,0,生命上限\nbonusTypeB=0,bonusType,1,魔法上限\nbonusTypeE=0,bonusType,4,攻击速度\nbonusTypeF=0,bonusType,5,绿字敏捷\nbonusTypeG=0,bonusType,6,绿字智力\nbonusTypeH=0,bonusType,7,绿字力量\n\n//YDWE 修改单位\n//targetattachA=0,targetattach,\"overhead\",头顶\nunitstatechangetypeA=0,unitstatechangetype,0,增加\nunitstatechangetypeB=0,unitstatechangetype,1,减少\nunitstatechangetypeC=0,unitstatechangetype,2,等于\n//removeguardtypeA=0,removeguardtype,1,佣兵死亡\n//removeguardtypeB=0,removeguardtype,2,主人死亡\n//removeguardtypeC=0,removeguardtype,3,佣兵或主人死亡\n\nturnclockwiseA=0,turnclockwise,1,逆时针\nturnclockwiseB=0,turnclockwise,-1,顺时针\nturnclockwiseC=0,turnclockwise,0,最近方向\n\nheadORchestA=0,headORchest,0,头部\nheadORchestB=0,headORchest,1,胸部\n\ncamerachangetypeA=0,camerachangetype,1,立即\ncamerachangetypeB=0,camerachangetype,2,线性\ncamerachangetypeC=0,camerachangetype,3,平滑\ncamerachangetypeD=0,camerachangetype,4,平滑后停止\n\ncamerastattypeA=0,camerastattype,1,X坐标(目标X轴)\ncamerastattypeB=0,camerastattype,2,Y坐标(目标Y轴)\ncamerastattypeC=0,camerastattype,3,Z坐标(Z轴偏移)\ncamerastattypeD=0,camerastattype,4,面向角度(Z轴旋转角度)\ncamerastattypeE=0,camerastattype,5,仰角(X轴旋转角度)\ncamerastattypeF=0,camerastattype,6,倾斜角度(Y轴旋转角度)\ncamerastattypeG=0,camerastattype,7,视野范围(镜头区域)\ncamerastattypeH=0,camerastattype,8,远处裁景(远处截断距离)\ncamerastattypeI=0,camerastattype,9,镜头目标距离(镜头距离)\n\ncameratgnoreterrainA=0,cameratgnoreterrain,false,不忽略\ncameratgnoreterrainB=0,cameratgnoreterrain,true,忽略\n\n//攻击或被攻击事件\nattackorattackedeventA=0,attackorattackedevent,0,被攻击\nattackorattackedeventB=0,attackorattackedevent,1,攻击\n//技能施放目标\ntargettypeA=0,targettype,1,对敌人\ntargettypeB=0,targettype,2,对点\ntargettypeC=0,targettype,3,立即\ntargettypeD=0,targettype,4,对自己\n\n\n//逆天-类型\ntypename01_integer=0,typename,1,整数\ntypename02_real=0,typename,2,实数\ntypename03_boolean=0,typename,3,真值\ntypename04_string=0,typename,4,字符串\ntypename05_timer=0,typename,5,计时器\ntypename06_trigger=0,typename,6,触发器\ntypename07_unit=0,typename,7,单位\ntypename08_unitcode=0,typename,8,单位类型\ntypename09_abilcode=0,typename,9,技能\ntypename10_item=0,typename,10,物品\ntypename11_itemcode=0,typename,11,物品类型\ntypename12_group=0,typename,12,单位组\ntypename13_player=0,typename,13,玩家\ntypename14_location=0,typename,14,点\ntypename15_destructable=0,typename,15,可破坏物\ntypename16_force=0,typename,16,玩家组\ntypename17_rect=0,typename,17,矩形区域\ntypename18_region=0,typename,18,不规则区域\ntypename19_sound=0,typename,19,声音\ntypename20_effect=0,typename,20,特效\ntypename21_unitpool=0,typename,21,单位池\ntypename22_itempool=0,typename,22,物品池\ntypename23_quest=0,typename,23,任务\ntypename24_questitem=0,typename,24,任务目标项\ntypename25_timerdialog=0,typename,25,计时器窗口\ntypename26_leaderboard=0,typename,26,排行榜\ntypename27_multiboard=0,typename,27,多面板\ntypename28_multiboarditem=0,typename,28,多面板项目\ntypename29_trackable=0,typename,29,可追踪物\ntypename30_dialog=0,typename,30,对话框\ntypename31_button=0,typename,31,对话框按钮\ntypename32_texttag=0,typename,32,漂浮文字\ntypename33_lightning=0,typename,33,闪电\ntypename34_image=0,typename,34,图像\ntypename35_fogstate=0,typename,35,迷雾\ntypename36_fogmodifier=0,typename,36,可见度修正器\ntypename37_radian=0,typename,37,弧度\ntypename38_degree=0,typename,38,角度\n//typename39_widget=0,typename,39,物体\n\nobjecttype00_abilcode=0,objecttype,YDWE_OBJECT_TYPE_ABILITY,WESTRING_OBJTAB_ABILITIES\nobjecttype01_buffcode=0,objecttype,YDWE_OBJECT_TYPE_BUFF,WESTRING_OBJTAB_BUFFS\nobjecttype02_unitcode=0,objecttype,YDWE_OBJECT_TYPE_UNIT,WESTRING_OBJTAB_UNITS\nobjecttype03_itemcode=0,objecttype,YDWE_OBJECT_TYPE_ITEM,WESTRING_OBJTAB_ITEMS\nobjecttype04_techcode=0,objecttype,YDWE_OBJECT_TYPE_UPGRADE,WESTRING_OBJTAB_UPGRADES\nobjecttype05_doodadcode=0,objecttype,YDWE_OBJECT_TYPE_DOODAD,WESTRING_OBJTAB_DOODADS\nobjecttype06_destructablecode=0,objecttype,YDWE_OBJECT_TYPE_DESTRUCTABLE,WESTRING_OBJTAB_DESTRUCTABLES\n\n//最萌小汐\nremoveWhichLocationA=0,removeWhichLocation,0,不清除点\nremoveWhichLocationB=0,removeWhichLocation,1,清除这2个点\nremoveWhichLocationC=0,removeWhichLocation,2,清除前面一个点\nremoveWhichLocationD=0,removeWhichLocation,3,清除后面一个点\n\nDisOrAngA=0,DisOrAng,0,距离\nDisOrAngB=0,DisOrAng,1,方向\n\nshowToA=0,showTo,0,对所有玩家可见\nshowToB=0,showTo,1,对友方可见\nshowToC=0,showTo,2,仅对自己可见\n\nisLuckA=0,isLuck,true,好神符\nisLuckB=0,isLuck,false,坏神符\n\nSkillBarEndReasonA=0,SkillBarEndReason,0,技能成功\nSkillBarEndReasonB=0,SkillBarEndReason,1,技能失败\n\n// Operators\nOperatorAdd=0,ArithmeticOperator,\"+\",WESTRING_ARITHMETICOPERATOR_ADD\nOperatorSubtract=0,ArithmeticOperator,\"-\",WESTRING_ARITHMETICOPERATOR_SUBTRACT\nOperatorMultiply=0,ArithmeticOperator,\"*\",WESTRING_ARITHMETICOPERATOR_MULTIPLY\nOperatorDivide=0,ArithmeticOperator,\"/\",WESTRING_ARITHMETICOPERATOR_DIVIDE\n\nOperatorEqual=0,ComparisonOperator,\"==\",WESTRING_COMPARISONOPERATOR_EQUAL\nOperatorNotEqual=0,ComparisonOperator,\"!=\",WESTRING_COMPARISONOPERATOR_NOTEQUAL\nOperatorGreater=0,ComparisonOperator,\">\",WESTRING_COMPARISONOPERATOR_GREATER\nOperatorGreaterEq=0,ComparisonOperator,\">=\",WESTRING_COMPARISONOPERATOR_GREATEREQ\nOperatorLess=0,ComparisonOperator,\"<\",WESTRING_COMPARISONOPERATOR_LESS\nOperatorLessEq=0,ComparisonOperator,\"<=\",WESTRING_COMPARISONOPERATOR_LESSEQ\n\nOperatorEqualENE=0,EqualNotEqualOperator,\"==\",WESTRING_EQUALNOTEQUALOPERATOR_EQUAL\nOperatorNotEqualENE=0,EqualNotEqualOperator,\"!=\",WESTRING_EQUALNOTEQUALOPERATOR_NOTEQUAL\n\n//Integer\nbj_forLoopAIndex=0,integer,bj_forLoopAIndex,循环整数A [R]\nbj_forLoopBIndex=0,integer,bj_forLoopBIndex,循环整数B [R]\nprocess.lastKey=0,integer,process.lastKey,最后创建的过程 <过程库>\nydl_timer_handle=0,integer,ydl_timer_handle,最后启动的逆天计时器地址\nydl_exp_timer_handle=0,integer,ydl_exp_timer_handle,到期的逆天计时器地址\nydl_trigger_handle=0,integer,ydl_trigger_handle,最后注册的逆天触发器地址\nydl_tri_trigger_handle=0,integer,ydl_tri_trigger_handle,触发的逆天触发器地址\n\nabileventA=0,abilevent,1,环绕(特效)\nabileventB=0,abilevent,2,跳跃\nabileventC=0,abilevent,3,丝带\nabileventD=0,abilevent,4,钩子(命中)\nabileventE=0,abilevent,5,钩子(返回)\nabileventF=0,abilevent,6,冲锋\nabileventG=0,abilevent,7,跳劈\nabileventH=0,abilevent,8,月神箭(命中)\nabileventI=0,abilevent,9,月神箭(消失)\nabileventJ=0,abilevent,10,环绕(模板)\n\n// Reals\nRealQueueDelayQuest=0,real,bj_QUEUE_DELAY_QUEST,WESTRING_QUEUE_DELAY_QUEST\nRealQueueDelayHint=0,real,bj_QUEUE_DELAY_HINT,WESTRING_QUEUE_DELAY_HINT\nRealQueueDelaySecret=0,real,bj_QUEUE_DELAY_SECRET,WESTRING_QUEUE_DELAY_SECRET\nRealHandicapEasy=0,real,bj_HANDICAP_EASY,WESTRING_HANDICAP_EASY\nRealCellWidth=0,real,bj_CELLWIDTH,WESTRING_REAL_CELLWIDTH\nRealUnitFacing=0,real,bj_UNIT_FACING,WESTRING_REAL_UNITFACING\nRealCamDefDistance=0,real,bj_CAMERA_DEFAULT_DISTANCE,WESTRING_CAMDEFAULT_DISTANCE\nRealCamDefFarZ=0,real,bj_CAMERA_DEFAULT_FARZ,WESTRING_CAMDEFAULT_FARZ\nRealCamDefAoA=0,real,bj_CAMERA_DEFAULT_AOA,WESTRING_CAMDEFAULT_AOA\nRealCamDefFoV=0,real,bj_CAMERA_DEFAULT_FOV,WESTRING_CAMDEFAULT_FOV\nRealCamDefRoll=0,real,bj_CAMERA_DEFAULT_ROLL,WESTRING_CAMDEFAULT_ROLL\nRealCamDefRotation=0,real,bj_CAMERA_DEFAULT_ROTATION,WESTRING_CAMDEFAULT_ROTATION\nbj_lastTransmissionDuration=0,real,bj_lastTransmissionDuration,最后发言长度 [R]\nRealE=0,real,bj_E,WESTRING_REAL_E\nRealPi=0,real,bj_PI,WESTRING_REAL_PI\nUnit.lastMoveDis=0,real,Unit.lastMoveDis,上次移动的距离 <单位库>\n\n//ScriptCode\nScriptCode00=0,scriptcode,exitwhen true,退出当前循环 [R]\nScriptCode01=0,scriptcode,call DisableTrigger(bj_cineSceneBeingSkipped),禁用ESC跳过电影消息 [R]\nScriptCode02=0,scriptcode,call EnableTrigger(bj_cineSceneBeingSkipped),启用ESC跳过电影消息 [R]\n\n// Players\nPlayer00=0,player,Player(0),WESTRING_PLAYER_00\nPlayerALL=0,player,Player(n),任意玩家\nPlayer01=0,player,Player(1),WESTRING_PLAYER_01\nPlayer02=0,player,Player(2),WESTRING_PLAYER_02\nPlayer03=0,player,Player(3),WESTRING_PLAYER_03\nPlayer04=0,player,Player(4),WESTRING_PLAYER_04\nPlayer05=0,player,Player(5),WESTRING_PLAYER_05\nPlayer06=0,player,Player(6),WESTRING_PLAYER_06\nPlayer07=0,player,Player(7),WESTRING_PLAYER_07\nPlayer08=0,player,Player(8),WESTRING_PLAYER_08\nPlayer09=0,player,Player(9),WESTRING_PLAYER_09\nPlayer10=0,player,Player(10),WESTRING_PLAYER_10\nPlayer11=0,player,Player(11),WESTRING_PLAYER_11\nPlayerNA=0,player,Player(PLAYER_NEUTRAL_AGGRESSIVE),WESTRING_PLAYER_NA\nPlayerNV=0,player,Player(bj_PLAYER_NEUTRAL_VICTIM),WESTRING_PLAYER_NV\nPlayerNE=0,player,Player(bj_PLAYER_NEUTRAL_EXTRA),WESTRING_PLAYER_NE\nPlayerNP=0,player,Player(PLAYER_NEUTRAL_PASSIVE),WESTRING_PLAYER_NP\n\n// Forces\nForce00=0,force,bj_FORCE_PLAYER[0],WESTRING_FORCE_00\nForce01=0,force,bj_FORCE_PLAYER[1],WESTRING_FORCE_01\nForce02=0,force,bj_FORCE_PLAYER[2],WESTRING_FORCE_02\nForce03=0,force,bj_FORCE_PLAYER[3],WESTRING_FORCE_03\nForce04=0,force,bj_FORCE_PLAYER[4],WESTRING_FORCE_04\nForce05=0,force,bj_FORCE_PLAYER[5],WESTRING_FORCE_05\nForce06=0,force,bj_FORCE_PLAYER[6],WESTRING_FORCE_06\nForce07=0,force,bj_FORCE_PLAYER[7],WESTRING_FORCE_07\nForce08=0,force,bj_FORCE_PLAYER[8],WESTRING_FORCE_08\nForce09=0,force,bj_FORCE_PLAYER[9],WESTRING_FORCE_09\nForce10=0,force,bj_FORCE_PLAYER[10],WESTRING_FORCE_10\nForce11=0,force,bj_FORCE_PLAYER[11],WESTRING_FORCE_11\nForceNA=0,force,bj_FORCE_PLAYER[PLAYER_NEUTRAL_AGGRESSIVE],WESTRING_FORCE_NA\nForceNV=0,force,bj_FORCE_PLAYER[bj_PLAYER_NEUTRAL_VICTIM],WESTRING_FORCE_NV\nForceNE=0,force,bj_FORCE_PLAYER[bj_PLAYER_NEUTRAL_EXTRA],WESTRING_FORCE_NE\nForceNP=0,force,bj_FORCE_PLAYER[PLAYER_NEUTRAL_PASSIVE],WESTRING_FORCE_NP\nbj_FORCE_ALL_PLAYERS=0,force,bj_FORCE_ALL_PLAYERS,全部玩家 [R]\n\n// Player colors\nColor00=0,playercolor,PLAYER_COLOR_RED,WESTRING_UNITCOLOR_00\nColor01=0,playercolor,PLAYER_COLOR_BLUE,WESTRING_UNITCOLOR_01\nColor02=0,playercolor,PLAYER_COLOR_CYAN,WESTRING_UNITCOLOR_02\nColor03=0,playercolor,PLAYER_COLOR_PURPLE,WESTRING_UNITCOLOR_03\nColor04=0,playercolor,PLAYER_COLOR_YELLOW,WESTRING_UNITCOLOR_04\nColor05=0,playercolor,PLAYER_COLOR_ORANGE,WESTRING_UNITCOLOR_05\nColor06=0,playercolor,PLAYER_COLOR_GREEN,WESTRING_UNITCOLOR_06\nColor07=0,playercolor,PLAYER_COLOR_PINK,WESTRING_UNITCOLOR_07\nColor08=0,playercolor,PLAYER_COLOR_LIGHT_GRAY,WESTRING_UNITCOLOR_08\nColor09=0,playercolor,PLAYER_COLOR_LIGHT_BLUE,WESTRING_UNITCOLOR_09\nColor10=0,playercolor,PLAYER_COLOR_AQUA,WESTRING_UNITCOLOR_10\nColor11=0,playercolor,PLAYER_COLOR_BROWN,WESTRING_UNITCOLOR_11\nColor12=1,playercolor,ConvertPlayerColor(12),WESTRING_UNITCOLOR_12\n\n// Races\nRaceHuman=0,race,RACE_HUMAN,WESTRING_TRIGRACE_HUMAN\nRaceOrc=0,race,RACE_ORC,WESTRING_TRIGRACE_ORC\nRaceUndead=0,race,RACE_UNDEAD,WESTRING_TRIGRACE_UNDEAD\nRaceNightElf=0,race,RACE_NIGHTELF,WESTRING_TRIGRACE_NIGHTELF\nRaceDemon=0,race,RACE_DEMON,WESTRING_TRIGRACE_DEMON\nRaceUnknown=0,race,ConvertRace(0),没有\nRaceOther=0,race,ConvertRace(7),其他\nRaceCreeps=0,race,ConvertRace(8),野外生物\nRaceCommoner=0,race,ConvertRace(9),平民\nRaceCritters=0,race,ConvertRace(10),动物\nRaceNaga=0,race,ConvertRace(11),娜迦\n\n\n// Item Classes\nItemTypeAny=1,itemtype,ITEM_TYPE_ANY,WESTRING_ITEMTYPE_ANY\nItemTypePermanent=1,itemtype,ITEM_TYPE_PERMANENT,WESTRING_ITEMTYPE_PERMANENT\nItemTypeCharged=1,itemtype,ITEM_TYPE_CHARGED,WESTRING_ITEMTYPE_CHARGED\nItemTypePowerup=1,itemtype,ITEM_TYPE_POWERUP,WESTRING_ITEMTYPE_POWERUP\nItemTypeArtifact=1,itemtype,ITEM_TYPE_ARTIFACT,WESTRING_ITEMTYPE_ARTIFACT\nItemTypePurchasable=1,itemtype,ITEM_TYPE_PURCHASABLE,WESTRING_ITEMTYPE_PURCHASABLE\nItemTypeCampaign=1,itemtype,ITEM_TYPE_CAMPAIGN,WESTRING_ITEMTYPE_CAMPAIGN\nItemTypeMiscellaneous=1,itemtype,ITEM_TYPE_MISCELLANEOUS,WESTRING_ITEMTYPE_MISCELLANEOUS\nItemTypeUnknown=1,itemtype,ITEM_TYPE_UNKNOWN,WESTRING_ITEMTYPE_UNKNOWN\n\n//HotKeyInt\nHotKeyIntNull=0,hotkeyint,0,无\nHotKeyIntA=0,hotkeyint,'A',A\nHotKeyIntB=0,hotkeyint,'B',B\nHotKeyIntC=0,hotkeyint,'C',C\nHotKeyIntD=0,hotkeyint,'D',D\nHotKeyIntE=0,hotkeyint,'E',E\nHotKeyIntF=0,hotkeyint,'F',F\nHotKeyIntG=0,hotkeyint,'G',G\nHotKeyIntH=0,hotkeyint,'H',H\nHotKeyIntI=0,hotkeyint,'I',I\nHotKeyIntJ=0,hotkeyint,'J',J\nHotKeyIntK=0,hotkeyint,'K',K\nHotKeyIntL=0,hotkeyint,'L',L\nHotKeyIntM=0,hotkeyint,'M',M\nHotKeyIntN=0,hotkeyint,'N',N\nHotKeyIntO=0,hotkeyint,'O',O\nHotKeyIntP=0,hotkeyint,'P',P\nHotKeyIntQ=0,hotkeyint,'Q',Q\nHotKeyIntR=0,hotkeyint,'R',R\nHotKeyIntS=0,hotkeyint,'S',S\nHotKeyIntT=0,hotkeyint,'T',T\nHotKeyIntU=0,hotkeyint,'U',U\nHotKeyIntV=0,hotkeyint,'V',V\nHotKeyIntW=0,hotkeyint,'W',W\nHotKeyIntX=0,hotkeyint,'X',X\nHotKeyIntY=0,hotkeyint,'Y',Y\nHotKeyIntZ=0,hotkeyint,'Z',Z\nHotKeyInttilde=0,hotkeyint,256,~\nHotKeyInt1=0,hotkeyint,'1',1\nHotKeyInt2=0,hotkeyint,'2',2\nHotKeyInt3=0,hotkeyint,'3',3\nHotKeyInt4=0,hotkeyint,'4',4\nHotKeyInt5=0,hotkeyint,'5',5\nHotKeyInt6=0,hotkeyint,'6',6\nHotKeyInt7=0,hotkeyint,'7',7\nHotKeyInt8=0,hotkeyint,'8',8\nHotKeyInt9=0,hotkeyint,'9',9\nHotKeyInt0=0,hotkeyint,'0',0\nHotKeyInt-=0,hotkeyint,273,-\nHotKeyIntequals=0,hotkeyint,272,=\nHotKeyInt\\=0,hotkeyint,276,\\\nHotKeyIntBackspace=0,hotkeyint,514,Backspace\nHotKeyInt[=0,hotkeyint,274,[\nHotKeyInt]=0,hotkeyint,275,]\nHotKeyInt;=0,hotkeyint,277,;\nHotKeyInt'=0,hotkeyint,278,'\nHotKeyIntcomma=0,hotkeyint,279,\",\"\nHotKeyInt.=0,hotkeyint,280,.\nHotKeyInt/=0,hotkeyint,281,/\nHotKeyIntF1=0,hotkeyint,768,F1\nHotKeyIntF2=0,hotkeyint,769,F2\nHotKeyIntF3=0,hotkeyint,770,F3\nHotKeyIntF4=0,hotkeyint,771,F4\nHotKeyIntF5=0,hotkeyint,772,F5\nHotKeyIntF6=0,hotkeyint,773,F6\nHotKeyIntF7=0,hotkeyint,774,F7\nHotKeyIntF8=0,hotkeyint,775,F8\nHotKeyIntF9=0,hotkeyint,776,F9\nHotKeyIntF10=0,hotkeyint,777,F10\nHotKeyIntF11=0,hotkeyint,778,F11\nHotKeyIntF12=0,hotkeyint,779,F12\nHotKeyIntEsc=0,hotkeyint,512,Esc\nHotKeyIntTab=0,hotkeyint,515,Tab\nHotKeyIntCapsLock=0,hotkeyint,526,CapsLock\nHotKeyIntLeft=0,hotkeyint,516,Left\nHotKeyIntRight=0,hotkeyint,518,Right\nHotKeyIntUp=0,hotkeyint,517,Up\nHotKeyIntDown=0,hotkeyint,519,Down\nHotKeyIntPrintScreen=0,hotkeyint,530,PrintScreen\nHotKeyIntScrollLock=0,hotkeyint,528,ScrollLock\nHotKeyIntPause=0,hotkeyint,529,Pause\nHotKeyIntInsert=0,hotkeyint,520,Insert\nHotKeyIntDelete=0,hotkeyint,521,Delete\nHotKeyIntHome=0,hotkeyint,522,Home\nHotKeyIntEnd=0,hotkeyint,523,End\nHotKeyIntPageUp=0,hotkeyint,524,PageUp\nHotKeyIntPageDown=0,hotkeyint,525,PageDown\nHotKeyIntNumpad1=0,hotkeyint,258,Numpad1\nHotKeyIntNumpad2=0,hotkeyint,259,Numpad2\nHotKeyIntNumpad3=0,hotkeyint,260,Numpad3\nHotKeyIntNumpad4=0,hotkeyint,261,Numpad4\nHotKeyIntNumpad5=0,hotkeyint,262,Numpad5\nHotKeyIntNumpad6=0,hotkeyint,263,Numpad6\nHotKeyIntNumpad7=0,hotkeyint,264,Numpad7\nHotKeyIntNumpad8=0,hotkeyint,265,Numpad8\nHotKeyIntNumpad9=0,hotkeyint,266,Numpad9\nHotKeyIntNumpad0=0,hotkeyint,257,Numpad0\nHotKeyIntNumLock=0,hotkeyint,527,NumLock\nHotKeyIntNumpad/=0,hotkeyint,270,Numpad/\nHotKeyIntNumpad*=0,hotkeyint,269,Numpad*\nHotKeyIntNumpad-=0,hotkeyint,268,Numpad-\nHotKeyIntNumpad+=0,hotkeyint,267,Numpad+\nHotKeyIntNumpad.=0,hotkeyint,271,Numpad.\n\n\n// Boolean\nbj_lastLoadPreloadSLResult=0,boolean,bj_lastLoadPreloadSLResult,最后读取的存档为有效 [YDWE]\n\n//最萌小汐\nUnit.MoveSuccess=0,boolean,Unit.MoveSuccess,上次移动完全成功 <单位库>\nUnit.IsOrderedByScript=0,boolean,Unit.IsOrderedByScript,指令是触发器发布的 <单位库>\n\n// Units\nUnitNull=0,unit,null,WESTRING_TRIGUNIT_NULL\nbj_lastCreatedUnit=0,unit,bj_lastCreatedUnit,最后创建的单位 [R]\nbj_lastLoadedUnit=0,unit,bj_lastLoadedUnit,最后读取的单位 [R]\nbj_lastReplacedUnit=0,unit,bj_lastReplacedUnit,最后替换的单位 [R]\nbj_lastHauntedGoldMine=0,unit,bj_lastHauntedGoldMine,最后创建的不死族金矿 [R]\nbj_lastPoolAbstractedUnit=0,unit,bj_lastPoolAbstractedUnit,最后从单位池中取出的单位 [YDWE]\nbj_lastAbilityCastingUnit=0,unit,bj_lastAbilityCastingUnit,最后施放特殊技能的单位 [YDWE]\nbj_lastAbilityTargetUnit=0,unit,bj_lastAbilityTargetUnit,最后被特殊技能命中的单位 [YDWE]\nUnit.lastSkillBar=0,unit,Unit.lastSkillBar,最后创建的施法进度条 <单位库>\nEvent.u_from=0,unit,Event.u_from[Event.index],事件来源 <事件库>\nEvent.u_to=0,unit,Event.u_to[Event.index],事件目标 <事件库>\n\n// Unit pool\nbj_lastCreatedUnitPool=0,unitpool,bj_lastCreatedUnitPool,最后创建的单位池 [YDWE]\n\n// Unit-Types\nUnitTypeNull=0,unitcode,0,WESTRING_TRIGUNITTYPE_NULL\n\n//Group\nbj_lastCreatedGroup=0,group,bj_lastCreatedGroup,最后创建的单位组 [R]\n\n// Items\nItemNull=0,item,null,WESTRING_TRIGITEM_NULL\nbj_lastCreatedItem=0,item,bj_lastCreatedItem,最后创建的物品 [R]\nbj_lastRemovedItem=0,item,bj_lastRemovedItem,最后丢弃的物品 [R]\nbj_lastMovedItemInItemSlot=0,item,bj_lastMovedItemInItemSlot,最后在物品栏中移动的物品 [YDWE]\n\n// item pool\nbj_lastCreatedItemPool=0,itempool,bj_lastCreatedItemPool,最后创建的物品池 [YDWE]\n\n// Destructables\nDestructableNull=0,destructable,null,WESTRING_TRIGDESTRUCTABLE_NULL\nbj_lastCreatedDestructable=0,destructable,bj_lastCreatedDestructable,最后创建的可破坏物 [R]\n\n// Quest\nbj_lastCreatedQuest=0,quest,bj_lastCreatedQuest,最后创建的任务 [R]\n\n// Questitem\nbj_lastCreatedQuestItem=0,questitem,bj_lastCreatedQuestItem,最后创建的任务项目 [R]\n\n// DefeatCondition\nbj_lastCreatedDefeatCondition=0,defeatcondition,bj_lastCreatedDefeatCondition,最后创建的失败条件 [R]\n\n//Leaderboard\nbj_lastCreatedLeaderboard=0,leaderboard,bj_lastCreatedLeaderboard,最后创建的排行榜 [R]\n\n//multiboard\nbj_lastCreatedMultiboard=0,multiboard,bj_lastCreatedMultiboard,最后创建的多面板 [R]\n\n//Timer\nbj_lastStartedTimer=0,timer,bj_lastStartedTimer,最后启用的计时器 [R]\nydl_timer=0,timer,ydl_timer,最后启动的逆天计时器\n\n// TimerDialog\nbj_lastCreatedTimerDialog=0,timerdialog,bj_lastCreatedTimerDialog,最后创建的计时器窗口 [R]\n\n// Button\nbj_lastCreatedButton=0,button,bj_lastCreatedButton,最后创建的对话框按钮 [R]\n\n// Rects\nRectNull=0,rect,null,WESTRING_TRIGRECT_NULL\nbj_mapInitialPlayableArea=0,rect,bj_mapInitialPlayableArea,可用地图区域 [R]\nbj_mapInitialCameraBounds=0,rect,bj_mapInitialCameraBounds,初始可用镜头区域 [R]\n\n// Effect\nbj_lastCreatedEffect=0,effect,bj_lastCreatedEffect,最后创建的特效 [R]\n\n// Lightning\nbj_lastCreatedLightning=0,lightning,bj_lastCreatedLightning,最后创建的闪电效果 [R]\n\n// Image\nbj_lastCreatedImage=0,image,bj_lastCreatedImage,最后创建的图像 [R]\n\n// Ubersplat\nbj_lastCreatedUbersplat=0,ubersplat,bj_lastCreatedUbersplat,最后创建的地面纹理变化 [R]\n\n// WeatherEffect\nbj_lastCreatedWeatherEffect=0,weathereffect,bj_lastCreatedWeatherEffect,最后创建的天气效果 [R]\n\n// TerrainDeformation\nbj_lastCreatedTerrainDeformation=0,terraindeformation,bj_lastCreatedTerrainDeformation,最后创建的地形变化 [R]\n\n// FogModifier\nbj_lastCreatedFogModifier=0,fogmodifier,bj_lastCreatedFogModifier,最后创建的可见度修正器 [R]\n\n// GameCache\nbj_lastCreatedGameCache=0,gamecache,bj_lastCreatedGameCache,最后创建的游戏缓存 [R]\n\n//TextTag\nbj_lastCreatedTextTag=0,texttag,bj_lastCreatedTextTag,最后创建的漂浮文字 [R]\n\n// Sounds\nSoundNull=0,sound,null,WESTRING_TRIGSOUND_NULL\nbj_lastPlayedSound=0,sound,bj_lastPlayedSound,最后播放的音效 [R]\n\n// Music\nMusicFileMusic=0,musicfile,`music`,WESTRING_TRIGMUSICFILE_MUSIC\nbj_lastPlayedMusic=0,musicfile,bj_lastPlayedMusic,最后播放的音乐 [R]\n\n//AttackType\nbj_lastSetAttackType=0,attacktype,bj_lastSetAttackType,最后设置的攻击类型 [YDWE]\n\n//DamageType\nbj_lastSetDamageType=0,damagetype,bj_lastSetDamageType,最后设置的伤害类型 [YDWE]\n\n//WeaponType\nbj_lastSetWeaponType=0,weapontype,bj_lastSetWeaponType,最后设置的武器类型 [YDWE]\n\n// Limit operators\nLimitOpEqual=0,limitop,EQUAL,WESTRING_LIMITOP_EQUAL\nLimitOpNotEqual=0,limitop,NOT_EQUAL,WESTRING_LIMITOP_NOTEQUAL\nLimitOpLessThan=0,limitop,LESS_THAN,WESTRING_LIMITOP_LESSTHAN\nLimitOpLessThanOrEqual=0,limitop,LESS_THAN_OR_EQUAL,WESTRING_LIMITOP_LESSTHANOREQUAL\nLimitOpGreaterThan=0,limitop,GREATER_THAN,WESTRING_LIMITOP_GREATERTHAN\nLimitOpGreaterThanOrEqual=0,limitop,GREATER_THAN_OR_EQUAL,WESTRING_LIMITOP_GREATERTHANOREQUAL\n\n// Game results\nGameResultWin=0,playergameresult,PLAYER_GAME_RESULT_VICTORY,WESTRING_VICTORY\nGameResultLose=0,playergameresult,PLAYER_GAME_RESULT_DEFEAT,WESTRING_DEFEAT\nGameResultDraw=0,playergameresult,PLAYER_GAME_RESULT_TIE,WESTRING_DRAW\n\n// Map flags\nMapFlagUseHandicaps=0,mapflag,MAP_USE_HANDICAPS,WESTRING_MAPFLAG_USEHANDICAPS\nMapFlagObservers=0,mapflag,MAP_OBSERVERS,WESTRING_MAPFLAG_OBSERVERS\nMapFlagObserversChat=0,mapflag,MAP_OBSERVERS_ON_DEATH,WESTRING_MAPFLAG_OBSERVERSONDEATH\nMapFlagResourceTradingLock=0,mapflag,MAP_LOCK_RESOURCE_TRADING,WESTRING_MAPFLAG_RESOURCETRADINGLOCK\nMapFlagResourceTradingAllies=0,mapflag,MAP_RESOURCE_TRADING_ALLIES_ONLY,WESTRING_MAPFLAG_RESOURCETRADINGALLIES\nMapFlagAllianceChangesLock=0,mapflag,MAP_LOCK_ALLIANCE_CHANGES,WESTRING_MAPFLAG_ALLIANCECHANGESLOCK\nMapFlagAllianceChangesHidden=0,mapflag,MAP_ALLIANCE_CHANGES_HIDDEN,WESTRING_MAPFLAG_ALLIANCECHANGESHIDDEN\n//MapFlagLockSpeed=0,mapflag,MAP_LOCK_SPEED,锁定游戏速度 [R]\nMapFlagMapReloaded=1,mapflag,MAP_RELOADED,WESTRING_MAPFLAG_MAPRELOADED\nMapFlagRandomHeroes=1,mapflag,MAP_RANDOM_HERO,WESTRING_MAPFLAG_RANDOM_HERO\nMapFlagRandomRaces=1,mapflag,MAP_RANDOM_RACES,WESTRING_MAPFLAG_RANDOM_RACES\nMapFlagFogHideTerrain=1,mapflag,MAP_FOG_HIDE_TERRAIN,WESTRING_MAPFLAG_FOG_HIDE_TERRAIN\nMapFlagFogMapExplored=1,mapflag,MAP_FOG_MAP_EXPLORED,WESTRING_MAPFLAG_FOG_MAP_EXPLORED\nMapFlagFogAlwaysVisible=1,mapflag,MAP_FOG_ALWAYS_VISIBLE,WESTRING_MAPFLAG_FOG_ALWAYS_VISIBLE\n\n\n// Player states\nPlayerStateGold=0,playerstate,PLAYER_STATE_RESOURCE_GOLD,WESTRING_PSTATE_GOLD\nPlayerStateLumber=0,playerstate,PLAYER_STATE_RESOURCE_LUMBER,WESTRING_PSTATE_LUMBER\nPlayerStateHeroTokens=0,playerstate,PLAYER_STATE_RESOURCE_HERO_TOKENS,WESTRING_PSTATE_HEROTOKENS\nPlayerStateGoldUpkeepRate=0,playerstate,PLAYER_STATE_GOLD_UPKEEP_RATE,WESTRING_PSTATE_UPKEEPGOLD\nPlayerStateLumberUpkeepRate=0,playerstate,PLAYER_STATE_LUMBER_UPKEEP_RATE,WESTRING_PSTATE_UPKEEPLUMBER\nPlayerStateGoldGathered=0,playerstate,PLAYER_STATE_GOLD_GATHERED,WESTRING_PSTATE_GOLDGATHERED\nPlayerStateLumberGathered=0,playerstate,PLAYER_STATE_LUMBER_GATHERED,WESTRING_PSTATE_LUMBER_GATHERED\nPlayerStateFoodUsed=0,playerstate,PLAYER_STATE_RESOURCE_FOOD_USED,WESTRING_PSTATE_FOODUSED\nPlayerStateFoodCap=0,playerstate,PLAYER_STATE_RESOURCE_FOOD_CAP,WESTRING_PSTATE_FOODCAP\nPlayerStateFoodLimit=0,playerstate,PLAYER_STATE_FOOD_CAP_CEILING,WESTRING_PSTATE_FOODCAPLIMIT\nPlayerStateGameResult=0,playerstate,PLAYER_STATE_GAME_RESULT,WESTRING_PSTATE_GAMERESULT\n\n// Player states - resources only\nPlayerResourceGold=1,playerresource,PLAYER_STATE_RESOURCE_GOLD,WESTRING_PRESOURCE_GOLD\nPlayerResourceLumber=1,playerresource,PLAYER_STATE_RESOURCE_LUMBER,WESTRING_PRESOURCE_LUMBER\n\n// Player scores\nPlayerScoreUnitsTrained=1,playerscore,PLAYER_SCORE_UNITS_TRAINED,WESTRING_PSCORE_UNITSTRAINED\nPlayerScoreUnitsKilled=1,playerscore,PLAYER_SCORE_UNITS_KILLED,WESTRING_PSCORE_UNITSKILLED\nPlayerScoreStructBuilt=1,playerscore,PLAYER_SCORE_STRUCT_BUILT,WESTRING_PSCORE_STRUCTBUILT\nPlayerScoreStructRazed=1,playerscore,PLAYER_SCORE_STRUCT_RAZED,WESTRING_PSCORE_STRUCTRAZED\nPlayerScoreTechPercent=1,playerscore,PLAYER_SCORE_TECH_PERCENT,WESTRING_PSCORE_TECHPERCENT\nPlayerScoreFoodProd=1,playerscore,PLAYER_SCORE_FOOD_MAXPROD,WESTRING_PSCORE_FOODPROD\nPlayerScoreFoodUsed=1,playerscore,PLAYER_SCORE_FOOD_MAXUSED,WESTRING_PSCORE_FOODUSED\nPlayerScoreHeroesKilled=1,playerscore,PLAYER_SCORE_HEROES_KILLED,WESTRING_PSCORE_HEROESKILLED\nPlayerScoreItemsGained=1,playerscore,PLAYER_SCORE_ITEMS_GAINED,WESTRING_PSCORE_ITEMSGAINED\nPlayerScoreMercsHired=1,playerscore,PLAYER_SCORE_MERCS_HIRED,WESTRING_PSCORE_MERCSHIRED\nPlayerScoreGoldTotal=1,playerscore,PLAYER_SCORE_GOLD_MINED_TOTAL,WESTRING_PSCORE_GOLDTOTAL\nPlayerScoreGoldUpkeep=1,playerscore,PLAYER_SCORE_GOLD_MINED_UPKEEP,WESTRING_PSCORE_GOLDUPKEEP\nPlayerScoreGoldLostUpkeep=1,playerscore,PLAYER_SCORE_GOLD_LOST_UPKEEP,WESTRING_PSCORE_GOLDLOSTUPKEEP\nPlayerScoreGoldLostTax=1,playerscore,PLAYER_SCORE_GOLD_LOST_TAX,WESTRING_PSCORE_GOLDLOSTTAX\nPlayerScoreGoldGiven=1,playerscore,PLAYER_SCORE_GOLD_GIVEN,WESTRING_PSCORE_GOLDGIVEN\nPlayerScoreGoldReceived=1,playerscore,PLAYER_SCORE_GOLD_RECEIVED,WESTRING_PSCORE_GOLDRECEIVED\nPlayerScoreLumberTotal=1,playerscore,PLAYER_SCORE_LUMBER_TOTAL,WESTRING_PSCORE_LUMBERTOTAL\nPlayerScoreLumberLostUpkeep=1,playerscore,PLAYER_SCORE_LUMBER_LOST_UPKEEP,WESTRING_PSCORE_LUMBERLOSTUPKEEP\nPlayerScoreLumberLostTax=1,playerscore,PLAYER_SCORE_LUMBER_LOST_TAX,WESTRING_PSCORE_LUMBERLOSTTAX\nPlayerScoreLumberGiven=1,playerscore,PLAYER_SCORE_LUMBER_GIVEN,WESTRING_PSCORE_LUMBERGIVEN\nPlayerScoreLumberReceived=1,playerscore,PLAYER_SCORE_LUMBER_RECEIVED,WESTRING_PSCORE_LUMBERECEIVED\nPlayerScoreUnitTotal=1,playerscore,PLAYER_SCORE_UNIT_TOTAL,WESTRING_PSCORE_UNITTOTAL\nPlayerScoreHeroTotal=1,playerscore,PLAYER_SCORE_HERO_TOTAL,WESTRING_PSCORE_HEROTOTAL\nPlayerScoreResourceTotal=1,playerscore,PLAYER_SCORE_RESOURCE_TOTAL,WESTRING_PSCORE_RESOURCETOTAL\nPlayerScoreTotal=1,playerscore,PLAYER_SCORE_TOTAL,WESTRING_PSCORE_TOTAL\n\n// Player flags\nPlayerFlagUnfollowable=0,playerflag,PLAYER_STATE_UNFOLLOWABLE,WESTRING_PFLAG_UNFOLLOWABLE\nPlayerFlagGivesBounty=0,playerflag,PLAYER_STATE_GIVES_BOUNTY,WESTRING_PFLAG_GIVESBOUNTY\nPlayerFlagAlliedVictory=0,playerflag,PLAYER_STATE_ALLIED_VICTORY,WESTRING_PFLAG_ALLIEDVICTORY\n\n// Gate states\nGateOperationClosed=0,gateoperation,bj_GATEOPERATION_CLOSE,WESTRING_GATEOPERATION_CLOSE\nGateOperationOpen=0,gateoperation,bj_GATEOPERATION_OPEN,WESTRING_GATEOPERATION_OPEN\nGateOperationDestroyed=0,gateoperation,bj_GATEOPERATION_DESTROY,WESTRING_GATEOPERATION_DESTROY\n\n// Elevator wall operations\nElevatorWallOpClose=1,elevatorwallop,false,WESTRING_ELEVATORWALLOP_CLOSE\nElevatorWallOpOpen=1,elevatorwallop,true,WESTRING_ELEVATORWALLOP_OPEN\n\n// Elevator wall choices\nElevatorWallTypeAll=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_ALL,WESTRING_ELEVATORWALLTYPE_ALL\nElevatorWallTypeEast=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_EAST,WESTRING_ELEVATORWALLTYPE_EAST\nElevatorWallTypeNorth=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_NORTH,WESTRING_ELEVATORWALLTYPE_NORTH\nElevatorWallTypeSouth=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_SOUTH,WESTRING_ELEVATORWALLTYPE_SOUTH\nElevatorWallTypeWest=1,elevatorwalltype,bj_ELEVATOR_WALL_TYPE_WEST,WESTRING_ELEVATORWALLTYPE_WEST\n\n// Usage options\nUseSkipOptionUse=0,useskipoption,true,WESTRING_USESKIPOPTION_USE\nUseSkipOptionSkip=0,useskipoption,false,WESTRING_USESKIPOPTION_SKIP\n\n// Selection option\nSelDeselOptionSel=0,seldeseloption,true,WESTRING_SELDESELOPTION_SEL\nSelDeselOptionDesel=0,seldeseloption,false,WESTRING_SELDESELOPTION_DESEL\n\n// AI Captain types\nAICaptainAttack=1,aicaptaintype,true,WESTRING_AICAPTAIN_ATTACK\nAICaptainDefense=1,aicaptaintype,false,WESTRING_AICAPTAIN_DEFENSE\n\n// AI Command Pop options\nAICommandPop=1,aicommandpop,true,WESTRING_AICOMMAND_REMOVE\nAICommandLeave=1,aicommandpop,false,WESTRING_AICOMMAND_LEAVE\n\n// Cache value types\nCacheValueTypeBoolean=1,cachevaluetype,bj_GAMECACHE_BOOLEAN,WESTRING_CACHEVALUETYPE_BOOLEAN\nCacheValueTypeInteger=1,cachevaluetype,bj_GAMECACHE_INTEGER,WESTRING_CACHEVALUETYPE_INTEGER\nCacheValueTypeReal=1,cachevaluetype,bj_GAMECACHE_REAL,WESTRING_CACHEVALUETYPE_REAL\nCacheValueTypeUnit=1,cachevaluetype,bj_GAMECACHE_UNIT,WESTRING_CACHEVALUETYPE_UNIT\nCacheValueTypeString=1,cachevaluetype,bj_GAMECACHE_STRING,WESTRING_CACHEVALUETYPE_STRING\n\n// Hashtable value types (localization stolen from gamecache)\nHashtableValueTypeBoolean=1,hashtablevaluetype,bj_HASHTABLE_BOOLEAN,WESTRING_CACHEVALUETYPE_BOOLEAN\nHashtableValueTypeInteger=1,hashtablevaluetype,bj_HASHTABLE_INTEGER,WESTRING_CACHEVALUETYPE_INTEGER\nHashtableValueTypeReal=1,hashtablevaluetype,bj_HASHTABLE_REAL,WESTRING_CACHEVALUETYPE_REAL\nHashtableValueTypeString=1,hashtablevaluetype,bj_HASHTABLE_STRING,WESTRING_CACHEVALUETYPE_STRING\nHashtableValueTypeHandle=1,hashtablevaluetype,bj_HASHTABLE_HANDLE,WESTRING_CACHEVALUETYPE_HANDLE\nbj_lastCreatedHashtable=0,hashtable,bj_lastCreatedHashtable,最后创建的哈希表 [C]\n\n// Map Control\nMapControlNone=0,mapcontrol,MAP_CONTROL_NONE,WESTRING_MAPCONTROL_NONE\nMapControlUser=0,mapcontrol,MAP_CONTROL_USER,WESTRING_MAPCONTROL_USER\nMapControlComputer=0,mapcontrol,MAP_CONTROL_COMPUTER,WESTRING_MAPCONTROL_COMPUTER\nMapControlRescuable=0,mapcontrol,MAP_CONTROL_RESCUABLE,WESTRING_MAPCONTROL_RESCUABLE\nMapControlNeutral=0,mapcontrol,MAP_CONTROL_NEUTRAL,WESTRING_MAPCONTROL_NEUTRAL\nMapControlCreep=0,mapcontrol,MAP_CONTROL_CREEP,WESTRING_MAPCONTROL_CREEP\n\n// Player slot states\nPlayerSlotStateEmpty=0,playerslotstate,PLAYER_SLOT_STATE_EMPTY,WESTRING_PSLOT_EMPTY\nPlayerSlotStatePlaying=0,playerslotstate,PLAYER_SLOT_STATE_PLAYING,WESTRING_PSLOT_PLAYING\nPlayerSlotStateLeft=0,playerslotstate,PLAYER_SLOT_STATE_LEFT,WESTRING_PSLOT_LEFT\n\n// Player unit events\nPlayerUnitEventDeath=0,playerunitevent,EVENT_PLAYER_UNIT_DEATH,WESTRING_PUEVENT_DEATH\nPlayerUnitEventDecay=0,playerunitevent,EVENT_PLAYER_UNIT_DECAY,WESTRING_PUEVENT_DECAY\nPlayerUnitEventChangesOwner=1,playerunitevent,EVENT_PLAYER_UNIT_CHANGE_OWNER,WESTRING_PUEVENT_CHANGESOWNER\nPlayerUnitEventHero_Level=0,playerunitevent,EVENT_PLAYER_HERO_LEVEL,WESTRING_PUEVENT_HEROLEVEL\nPlayerUnitEventHero_Skill=0,playerunitevent,EVENT_PLAYER_HERO_SKILL,WESTRING_PUEVENT_HEROSKILL\nPlayerUnitEventHero_Revivable=0,playerunitevent,EVENT_PLAYER_HERO_REVIVABLE,WESTRING_PUEVENT_HEROREVIVABLE\nPlayerUnitEventHeroUseItem=0,playerunitevent,EVENT_PLAYER_UNIT_USE_ITEM,WESTRING_PUEVENT_HEROUSEITEM\nPlayerUnitEventHeroPickUpItem=0,playerunitevent,EVENT_PLAYER_UNIT_PICKUP_ITEM,WESTRING_PUEVENT_HEROPICKUPITEM\nPlayerUnitEventHeroDropItem=0,playerunitevent,EVENT_PLAYER_UNIT_DROP_ITEM,WESTRING_PUEVENT_HERODROPITEM\nPlayerUnitEventSell=1,playerunitevent,EVENT_PLAYER_UNIT_SELL,WESTRING_PUEVENT_SELL\nPlayerUnitEventSellItem=1,playerunitevent,EVENT_PLAYER_UNIT_SELL_ITEM,WESTRING_PUEVENT_SELLITEM\nPlayerUnitEventPawnItem=1,playerunitevent,EVENT_PLAYER_UNIT_PAWN_ITEM,WESTRING_PUEVENT_PAWNITEM\nPlayerUnitEventAttacked=0,playerunitevent,EVENT_PLAYER_UNIT_ATTACKED,WESTRING_PUEVENT_ATTACKED\nPlayerUnitEventRescued=0,playerunitevent,EVENT_PLAYER_UNIT_RESCUED,WESTRING_PUEVENT_RESCUED\nPlayerUnitEventSummoned=0,playerunitevent,EVENT_PLAYER_UNIT_SUMMON,WESTRING_PUEVENT_SUMMONED\nPlayerUnitEventSpellChannel=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_CHANNEL,WESTRING_PUEVENT_SPELLCHANNEL\nPlayerUnitEventSpellCast=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_CAST,WESTRING_PUEVENT_SPELLCAST\nPlayerUnitEventSpellEndCast=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_ENDCAST,WESTRING_PUEVENT_SPELLENDCAST\nPlayerUnitEventSpellEffect=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_EFFECT,WESTRING_PUEVENT_SPELLEFFECT\nPlayerUnitEventSpellFinish=1,playerunitevent,EVENT_PLAYER_UNIT_SPELL_FINISH,WESTRING_PUEVENT_SPELLFINISH\nPlayerUnitEventLoaded=0,playerunitevent,EVENT_PLAYER_UNIT_LOADED,WESTRING_PUEVENT_LOADED\nPlayerUnitEventTrain_Start=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_START,WESTRING_PUEVENT_TRAINSTART\nPlayerUnitEventTrain_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_CANCEL,WESTRING_PUEVENT_TRAINCANCEL\nPlayerUnitEventTrain_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_TRAIN_FINISH,WESTRING_PUEVENT_TRAINFINISH\nPlayerUnitEventConstruct_Start=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_START,WESTRING_PUEVENT_CONSTRUCTSTART\nPlayerUnitEventConstruct_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL,WESTRING_PUEVENT_CONSTRUCTCANCEL\nPlayerUnitEventConstruct_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_CONSTRUCT_FINISH,WESTRING_PUEVENT_CONSTRUCTFINISH\nPlayerUnitEventReviveStart=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_START,WESTRING_PUEVENT_REVIVESTART\nPlayerUnitEventReviveCancel=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_CANCEL,WESTRING_PUEVENT_REVIVECANCEL\nPlayerUnitEventReviveFinish=0,playerunitevent,EVENT_PLAYER_HERO_REVIVE_FINISH,WESTRING_PUEVENT_REVIVEFINISH\nPlayerUnitEventUpgrade_Start=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_START,WESTRING_PUEVENT_UPGRADESTART\nPlayerUnitEventUpgrade_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_CANCEL,WESTRING_PUEVENT_UPGRADECANCEL\nPlayerUnitEventUpgrade_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_UPGRADE_FINISH,WESTRING_PUEVENT_UPGRADEFINISH\nPlayerUnitEventResearch_Start=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_START,WESTRING_PUEVENT_RESEARCHSTART\nPlayerUnitEventResearch_Cancel=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_CANCEL,WESTRING_PUEVENT_RESEARCHCANCEL\nPlayerUnitEventResearch_Finish=0,playerunitevent,EVENT_PLAYER_UNIT_RESEARCH_FINISH,WESTRING_PUEVENT_RESEARCHFINISH\nPlayerUnitEventIssued_Unit_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER,WESTRING_PUEVENT_ISSUEDUNITORDER\nPlayerUnitEventIssued_Point_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,WESTRING_PUEVENT_ISSUEDPOINTORDER\nPlayerUnitEventIssued_Order=0,playerunitevent,EVENT_PLAYER_UNIT_ISSUED_ORDER,WESTRING_PUEVENT_ISSUEDORDER\n\n// Unit events\nUnitEventDeath=0,unitevent,EVENT_UNIT_DEATH,WESTRING_UEVENT_DEATH\nUnitEventDecay=0,unitevent,EVENT_UNIT_DECAY,WESTRING_UEVENT_DECAY\nUnitEventChangesOwner=1,unitevent,EVENT_UNIT_CHANGE_OWNER,WESTRING_UEVENT_CHANGESOWNER\nUnitEventDamaged=0,unitevent,EVENT_UNIT_DAMAGED,WESTRING_UEVENT_DAMAGED\nUnitEventHeroLevel=0,unitevent,EVENT_UNIT_HERO_LEVEL,WESTRING_UEVENT_HEROLEVEL\nUnitEventHeroSkill=0,unitevent,EVENT_UNIT_HERO_SKILL,WESTRING_UEVENT_HEROSKILL\nUnitEventHeroRevivable=0,unitevent,EVENT_UNIT_HERO_REVIVABLE,WESTRING_UEVENT_HEROREVIVABLE\nUnitEventHeroUseItem=0,unitevent,EVENT_UNIT_USE_ITEM,WESTRING_UEVENT_HEROUSEITEM\nUnitEventHeroPickUpItem=0,unitevent,EVENT_UNIT_PICKUP_ITEM,WESTRING_UEVENT_HEROPICKUPITEM\nUnitEventHeroDropItem=0,unitevent,EVENT_UNIT_DROP_ITEM,WESTRING_UEVENT_HERODROPITEM\nUnitEventSell=1,unitevent,EVENT_UNIT_SELL,WESTRING_UEVENT_SELL\nUnitEventSellItem=1,unitevent,EVENT_UNIT_SELL_ITEM,WESTRING_UEVENT_SELLITEM\nUnitEventPawnItem=1,unitevent,EVENT_UNIT_PAWN_ITEM,WESTRING_UEVENT_PAWNITEM\nUnitEventAttacked=0,unitevent,EVENT_UNIT_ATTACKED,WESTRING_UEVENT_ATTACKED\nUnitEventRescued=0,unitevent,EVENT_UNIT_RESCUED,WESTRING_UEVENT_RESCUED\nUnitEventSelected=0,unitevent,EVENT_UNIT_SELECTED,WESTRING_UEVENT_SELECTED\nUnitEventDeselected=0,unitevent,EVENT_UNIT_DESELECTED,WESTRING_UEVENT_DESELECTED\nUnitEventSummon=0,unitevent,EVENT_UNIT_SUMMON,\"召唤一个单位 [R]\"\nUnitEventSpellChannel=1,unitevent,EVENT_UNIT_SPELL_CHANNEL,WESTRING_UEVENT_SPELLCHANNEL\nUnitEventSpellCast=1,unitevent,EVENT_UNIT_SPELL_CAST,WESTRING_UEVENT_SPELLCAST\nUnitEventSpellEndCast=1,unitevent,EVENT_UNIT_SPELL_ENDCAST,WESTRING_UEVENT_SPELLENDCAST\nUnitEventSpellEffect=1,unitevent,EVENT_UNIT_SPELL_EFFECT,WESTRING_UEVENT_SPELLEFFECT\nUnitEventSpellFinish=1,unitevent,EVENT_UNIT_SPELL_FINISH,WESTRING_UEVENT_SPELLFINISH\nUnitEventLoaded=0,unitevent,EVENT_UNIT_LOADED,WESTRING_UEVENT_LOADED\nUnitEventAcquiredTarget=0,unitevent,EVENT_UNIT_ACQUIRED_TARGET,WESTRING_UEVENT_ACQUIREDTARGET\nUnitEventTargetInRange=0,unitevent,EVENT_UNIT_TARGET_IN_RANGE,WESTRING_UEVENT_TARGETINRANGE\nUnitEventTrainStart=0,unitevent,EVENT_UNIT_TRAIN_START,WESTRING_UEVENT_TRAINSTART\nUnitEventTrainCancel=0,unitevent,EVENT_UNIT_TRAIN_CANCEL,WESTRING_UEVENT_TRAINCANCEL\nUnitEventTrainFinish=0,unitevent,EVENT_UNIT_TRAIN_FINISH,WESTRING_UEVENT_TRAINFINISH\nUnitEventReviveStart=0,unitevent,EVENT_UNIT_HERO_REVIVE_START,WESTRING_UEVENT_REVIVESTART\nUnitEventReviveCancel=0,unitevent,EVENT_UNIT_HERO_REVIVE_CANCEL,WESTRING_UEVENT_REVIVECANCEL\nUnitEventReviveFinish=0,unitevent,EVENT_UNIT_HERO_REVIVE_FINISH,WESTRING_UEVENT_REVIVEFINISH\nUnitEventUpgradeStart=0,unitevent,EVENT_UNIT_UPGRADE_START,WESTRING_UEVENT_UPGRADESTART\nUnitEventUpgradeCancel=0,unitevent,EVENT_UNIT_UPGRADE_CANCEL,WESTRING_UEVENT_UPGRADECANCEL\nUnitEventUpgradeFinish=0,unitevent,EVENT_UNIT_UPGRADE_FINISH,WESTRING_UEVENT_UPGRADEFINISH\nUnitEventResearchStart=0,unitevent,EVENT_UNIT_RESEARCH_START,WESTRING_UEVENT_RESEARCHSTART\nUnitEventResearchCancel=0,unitevent,EVENT_UNIT_RESEARCH_CANCEL,WESTRING_UEVENT_RESEARCHCANCEL\nUnitEventResearchFinish=0,unitevent,EVENT_UNIT_RESEARCH_FINISH,WESTRING_UEVENT_RESEARCHFINISH\nUnitEventIssueUnitOrder=0,unitevent,EVENT_UNIT_ISSUED_TARGET_ORDER,WESTRING_UEVENT_ISSUEUNITORDER\nUnitEventIssuePointOrder=0,unitevent,EVENT_UNIT_ISSUED_POINT_ORDER,WESTRING_UEVENT_ISSUEPOINTORDER\nUnitEventIssueOrder=0,unitevent,EVENT_UNIT_ISSUED_ORDER,WESTRING_UEVENT_ISSUEORDER\n\n// Unit states (read-only)\nUnitStateLife=0,unitstate,UNIT_STATE_LIFE,WESTRING_USTATE_LIFE\nUnitStateMaxLife=0,unitstate,UNIT_STATE_MAX_LIFE,WESTRING_USTATE_MAXLIFE\nUnitStateMana=0,unitstate,UNIT_STATE_MANA,WESTRING_USTATE_MANA\nUnitStateMaxMana=0,unitstate,UNIT_STATE_MAX_MANA,WESTRING_USTATE_MAXMANA\nUnitStateDamageDice=0,unitstate,ConvertUnitState(0x10),\"骰子数量 [JAPI]\"\nUnitStateDamageSide=0,unitstate,ConvertUnitState(0x11),\"骰子面数 [JAPI]\"\nUnitStateDamageBase=0,unitstate,ConvertUnitState(0x12),\"基础伤害 [JAPI]\"\nUnitStateDamageBonus=0,unitstate,ConvertUnitState(0x13),\"附加伤害 [JAPI]\"\nUnitStateDamageMix=0,unitstate,ConvertUnitState(0x14),\"攻击最小值 [JAPI]\"\nUnitStateDamageMax=0,unitstate,ConvertUnitState(0x15),\"攻击最大值 [JAPI]\"\nUnitStateDamageRange=0,unitstate,ConvertUnitState(0x16),\"攻击范围 [JAPI]\"\nUnitStateArmor=0,unitstate,ConvertUnitState(0x20),\"护甲 [JAPI]\"\n\n// UnitStatesSec\nUnitStateLifeSec=0,unitstatesec,UNIT_STATE_LIFE,WESTRING_USTATE_LIFE\nUnitStateManaSec=0,unitstatesec,UNIT_STATE_MANA,WESTRING_USTATE_MANA\nUnitStateDamageDiceSec=0,unitstatesec,ConvertUnitState(0x10),\"骰子数量 [JAPI]\"\nUnitStateDamageSideSec=0,unitstatesec,ConvertUnitState(0x11),\"骰子面数 [JAPI]\"\nUnitStateDamageBaseSec=0,unitstatesec,ConvertUnitState(0x12),\"基础伤害 [JAPI]\"\nUnitStateDamageBonusSec=0,unitstatesec,ConvertUnitState(0x13),\"附加伤害 [JAPI]\"\nUnitStateDamageRangeSec=0,unitstatesec,ConvertUnitState(0x16),\"攻击范围 [JAPI]\"\nUnitStateArmorSec=0,unitstatesec,ConvertUnitState(0x20),\"护甲 [JAPI]\"\n\n// Keyboard Event Types\nKeyEventTypeDepress=1,keyeventtype,bj_KEYEVENTTYPE_DEPRESS,WESTRING_KEYEVENTTYPE_DEPRESS\nKeyEventTypeRelease=1,keyeventtype,bj_KEYEVENTTYPE_RELEASE,WESTRING_KEYEVENTTYPE_RELEASE\n\n// Keyboard Event Keys\nKeyEventKeyLeft=1,keyeventkey,bj_KEYEVENTKEY_LEFT,WESTRING_KEYEVENTKEY_LEFT\nKeyEventKeyRight=1,keyeventkey,bj_KEYEVENTKEY_RIGHT,WESTRING_KEYEVENTKEY_RIGHT\nKeyEventKeyDown=1,keyeventkey,bj_KEYEVENTKEY_DOWN,WESTRING_KEYEVENTKEY_DOWN\nKeyEventKeyUp=1,keyeventkey,bj_KEYEVENTKEY_UP,WESTRING_KEYEVENTKEY_UP\n\n// Unit types\nUnitTypeStructure=0,unittype,UNIT_TYPE_STRUCTURE,WESTRING_UNITTYPE_STRUCTURE\nUnitTypeHero=0,unittype,UNIT_TYPE_HERO,WESTRING_UNITTYPE_HERO\nUnitTypeDead=0,unittype,UNIT_TYPE_DEAD,死亡的 [R]\nUnitTypeGround=0,unittype,UNIT_TYPE_GROUND,WESTRING_UNITTYPE_GROUND\nUnitTypeFlying=0,unittype,UNIT_TYPE_FLYING,WESTRING_UNITTYPE_FLYING\nUnitTypeAttacksGround=0,unittype,UNIT_TYPE_ATTACKS_GROUND,WESTRING_UNITTYPE_ATTACKSGROUND\nUnitTypeAttacksFlying=0,unittype,UNIT_TYPE_ATTACKS_FLYING,WESTRING_UNITTYPE_ATTACKSFLYING\nUnitTypeMeleeAttacker=0,unittype,UNIT_TYPE_MELEE_ATTACKER,WESTRING_UNITTYPE_MELEEATTACKER\nUnitTypeRangedAttacker=0,unittype,UNIT_TYPE_RANGED_ATTACKER,WESTRING_UNITTYPE_RANGEDATTACKER\nUnitTypeSummoned=0,unittype,UNIT_TYPE_SUMMONED,WESTRING_UNITTYPE_SUMMONED\nUnitTypePlagued=0,unittype,UNIT_TYPE_PLAGUED,WESTRING_UNITTYPE_PLAGUED\nUnitTypeSnared=0,unittype,UNIT_TYPE_SNARED,WESTRING_UNITTYPE_SNARED\nUnitTypeStunned=0,unittype,UNIT_TYPE_STUNNED,WESTRING_UNITTYPE_STUNNED\nUnitTypeGiant=0,unittype,UNIT_TYPE_GIANT,泰坦族(无法改变高度) [R]\nUnitTypeTauren=0,unittype,UNIT_TYPE_TAUREN,牛头人(弹幕，不会被圆形选取选取选取到) [R]\nUnitTypeUndead=0,unittype,UNIT_TYPE_UNDEAD,WESTRING_UNITTYPE_UNDEAD\nUnitTypeMechanical=0,unittype,UNIT_TYPE_MECHANICAL,WESTRING_UNITTYPE_MECHANICAL\nUnitTypeAncient=0,unittype,UNIT_TYPE_ANCIENT,WESTRING_UNITTYPE_ANCIENT\nUnitTypePeon=0,unittype,UNIT_TYPE_PEON,WESTRING_UNITTYPE_PEON\nUnitTypeTownHall=0,unittype,UNIT_TYPE_TOWNHALL,WESTRING_UNITTYPE_TOWNHALL\nUnitTypeSapper=0,unittype,UNIT_TYPE_SAPPER,WESTRING_UNITTYPE_SAPPER\nUnitTypePoisoned=0,unittype,UNIT_TYPE_POISONED,WESTRING_UNITTYPE_POISONED\nUnitTypePolymorphed=0,unittype,UNIT_TYPE_POLYMORPHED,WESTRING_UNITTYPE_POLYMORPHED\nUnitTypeSleeping=0,unittype,UNIT_TYPE_SLEEPING,WESTRING_UNITTYPE_SLEEPING\nUnitTypeResistant=1,unittype,UNIT_TYPE_RESISTANT,WESTRING_UNITTYPE_RESISTANT\nUnitTypeEthereal=1,unittype,UNIT_TYPE_ETHEREAL,WESTRING_UNITTYPE_ETHEREAL\nUnitTypeMagicImmune=0,unittype,UNIT_TYPE_MAGIC_IMMUNE,WESTRING_UNITTYPE_MAGICIMMUNE\n\n//UnitTypeAddAble\nUnitTypeSummonedAdd=0,unittypeaddable,UNIT_TYPE_SUMMONED,WESTRING_UNITTYPE_SUMMONED\nUnitTypeUndeadAdd=0,unittypeaddable,UNIT_TYPE_UNDEAD,WESTRING_UNITTYPE_UNDEAD\nUnitTypeMechanicalAdd=0,unittypeaddable,UNIT_TYPE_MECHANICAL,WESTRING_UNITTYPE_MECHANICAL\nUnitTypeAncientAdd=0,unittypeaddable,UNIT_TYPE_ANCIENT,WESTRING_UNITTYPE_ANCIENT\nUnitTypePeonAdd=0,unittypeaddable,UNIT_TYPE_PEON,WESTRING_UNITTYPE_PEON\nUnitTypeTownHallAdd=0,unittypeaddable,UNIT_TYPE_TOWNHALL,WESTRING_UNITTYPE_TOWNHALL\nUnitTypeSapperAdd=0,unittypeaddable,UNIT_TYPE_SAPPER,WESTRING_UNITTYPE_SAPPER\nUnitTypeGiantAdd=0,unittypeaddable,UNIT_TYPE_GIANT,泰坦族(无法改变高度)\nUnitTypeTaurenAdd=0,unittypeaddable,UNIT_TYPE_TAUREN,牛头人(只会被逆天选取选取到)\n\n// Game speeds\nGameSpeedSlowest=0,gamespeed,MAP_SPEED_SLOWEST,WESTRING_GAMESPEED_SLOWEST\nGameSpeedSlow=0,gamespeed,MAP_SPEED_SLOW,WESTRING_GAMESPEED_SLOW\nGameSpeedNormal=0,gamespeed,MAP_SPEED_NORMAL,WESTRING_GAMESPEED_NORMAL\nGameSpeedFast=0,gamespeed,MAP_SPEED_FAST,WESTRING_GAMESPEED_FAST\nGameSpeedFastest=0,gamespeed,MAP_SPEED_FASTEST,WESTRING_GAMESPEED_FASTEST\n\n// Game difficulties\nGameDifficultyEasy=0,gamedifficulty,MAP_DIFFICULTY_EASY,WESTRING_GAMEDIFFICULTY_EASY\nGameDifficultyNormal=0,gamedifficulty,MAP_DIFFICULTY_NORMAL,WESTRING_GAMEDIFFICULTY_NORMAL\nGameDifficultyHard=0,gamedifficulty,MAP_DIFFICULTY_HARD,WESTRING_GAMEDIFFICULTY_HARD\n\n// Melee AI difficulties\nAIDifficultyNewbie=0,aidifficulty,AI_DIFFICULTY_NEWBIE,WESTRING_AIDIFFICULTY_NEWBIE\nAIDifficultyNormal=0,aidifficulty,AI_DIFFICULTY_NORMAL,WESTRING_AIDIFFICULTY_NORMAL\nAIDifficultyInsane=0,aidifficulty,AI_DIFFICULTY_INSANE,WESTRING_AIDIFFICULTY_INSANE\n\n// Map densities\nMapDensityNone=0,mapdensity,MAP_DENSITY_NONE,WESTRING_MAPDENSITY_NONE\nMapDensityLight=0,mapdensity,MAP_DENSITY_LIGHT,WESTRING_MAPDENSITY_LIGHT\nMapDensityMedium=0,mapdensity,MAP_DENSITY_MEDIUM,WESTRING_MAPDENSITY_MEDIUM\nMapDensityHeavy=0,mapdensity,MAP_DENSITY_HEAVY,WESTRING_MAPDENSITY_HEAVY\n\n// Alliance settings\nAllianceSettingUnallied=0,alliancesetting,bj_ALLIANCE_UNALLIED,WESTRING_ALLIANCE_UNALLIED\nAllianceSettingUnalliedVision=0,alliancesetting,bj_ALLIANCE_UNALLIED_VISION,WESTRING_ALLIANCE_UNALLIEDVISION\nAllianceSettingNeutral=0,alliancesetting,bj_ALLIANCE_NEUTRAL,WESTRING_ALLIANCE_NEUTRAL\nAllianceSettingNeutralVision=1,alliancesetting,bj_ALLIANCE_NEUTRAL_VISION,WESTRING_ALLIANCE_NEUTRAL_VISION\nAllianceSettingAllied=0,alliancesetting,bj_ALLIANCE_ALLIED,WESTRING_ALLIANCE_ALLIED\nAllianceSettingAlliedVision=0,alliancesetting,bj_ALLIANCE_ALLIED_VISION,WESTRING_ALLIANCE_ALLIEDVISION\nAllianceSettingAlliedUnits=0,alliancesetting,bj_ALLIANCE_ALLIED_UNITS,WESTRING_ALLIANCE_ALLIEDUNITS\nAllianceSettingAlliedAdvUnits=0,alliancesetting,bj_ALLIANCE_ALLIED_ADVUNITS,WESTRING_ALLIANCE_ALLIEDADVUNITS\n\n// Alliance types\nAllianceTypePassive=0,alliancetype,ALLIANCE_PASSIVE,WESTRING_ALLIANCE_PASSIVE\nAllianceTypeSharedVision=0,alliancetype,ALLIANCE_SHARED_VISION,WESTRING_ALLIANCE_SHAREDVISION\nAllianceTypeSharedControl=0,alliancetype,ALLIANCE_SHARED_CONTROL,WESTRING_ALLIANCE_SHAREDCONTROL\nAllianceTypeSharedFullControl=0,alliancetype,ALLIANCE_SHARED_ADVANCED_CONTROL,WESTRING_ALLIANCE_SHAREDFULLCONTROL\nAllianceTypeXP=0,alliancetype,ALLIANCE_SHARED_XP,WESTRING_ALLIANCE_XP\nAllianceTypeSpells=0,alliancetype,ALLIANCE_SHARED_SPELLS,WESTRING_ALLIANCE_SPELLS\nAllianceTypeHelpRequest=0,alliancetype,ALLIANCE_HELP_REQUEST,WESTRING_ALLIANCE_HELPREQUEST\nAllianceTypeHelpResponse=0,alliancetype,ALLIANCE_HELP_RESPONSE,WESTRING_ALLIANCE_HELPRESPONSE\n\n// Attack types\nAttackTypeNormal=1,attacktype,ATTACK_TYPE_NORMAL,WESTRING_UE_ATTACKTYPE_SPELLS\nAttackTypeMelee=1,attacktype,ATTACK_TYPE_MELEE,WESTRING_UE_ATTACKTYPE_NORMAL\nAttackTypePierce=1,attacktype,ATTACK_TYPE_PIERCE,WESTRING_UE_ATTACKTYPE_PIERCE\nAttackTypeSiege=1,attacktype,ATTACK_TYPE_SIEGE,WESTRING_UE_ATTACKTYPE_SIEGE\nAttackTypeMagic=1,attacktype,ATTACK_TYPE_MAGIC,WESTRING_UE_ATTACKTYPE_MAGIC\nAttackTypeChaos=1,attacktype,ATTACK_TYPE_CHAOS,WESTRING_UE_ATTACKTYPE_CHAOS\nAttackTypeHero=1,attacktype,ATTACK_TYPE_HERO,WESTRING_UE_ATTACKTYPE_HERO\n\n// Damage types\nDamageTypeUnknown=1,damagetype,DAMAGE_TYPE_UNKNOWN,WESTRING_DAMAGE_TYPE_UNKNOWN\nDamageTypeNormal=1,damagetype,DAMAGE_TYPE_NORMAL,WESTRING_DAMAGE_TYPE_NORMAL\nDamageTypeEnhanced=1,damagetype,DAMAGE_TYPE_ENHANCED,WESTRING_DAMAGE_TYPE_ENHANCED\nDamageTypeFire=1,damagetype,DAMAGE_TYPE_FIRE,WESTRING_DAMAGE_TYPE_FIRE\nDamageTypeCold=1,damagetype,DAMAGE_TYPE_COLD,WESTRING_DAMAGE_TYPE_COLD\nDamageTypeLightning=1,damagetype,DAMAGE_TYPE_LIGHTNING,WESTRING_DAMAGE_TYPE_LIGHTNING\nDamageTypePoison=1,damagetype,DAMAGE_TYPE_POISON,WESTRING_DAMAGE_TYPE_POISON\nDamageTypeDisease=1,damagetype,DAMAGE_TYPE_DISEASE,WESTRING_DAMAGE_TYPE_DISEASE\nDamageTypeDivine=1,damagetype,DAMAGE_TYPE_DIVINE,WESTRING_DAMAGE_TYPE_DIVINE\nDamageTypeMagic=1,damagetype,DAMAGE_TYPE_MAGIC,WESTRING_DAMAGE_TYPE_MAGIC\nDamageTypeSonic=1,damagetype,DAMAGE_TYPE_SONIC,WESTRING_DAMAGE_TYPE_SONIC\nDamageTypeAcid=1,damagetype,DAMAGE_TYPE_ACID,WESTRING_DAMAGE_TYPE_ACID\nDamageTypeForce=1,damagetype,DAMAGE_TYPE_FORCE,WESTRING_DAMAGE_TYPE_FORCE\nDamageTypeDeath=1,damagetype,DAMAGE_TYPE_DEATH,WESTRING_DAMAGE_TYPE_DEATH\nDamageTypeMind=1,damagetype,DAMAGE_TYPE_MIND,WESTRING_DAMAGE_TYPE_MIND\nDamageTypePlant=1,damagetype,DAMAGE_TYPE_PLANT,WESTRING_DAMAGE_TYPE_PLANT\nDamageTypeDefensive=1,damagetype,DAMAGE_TYPE_DEFENSIVE,WESTRING_DAMAGE_TYPE_DEFENSIVE\nDamageTypeDemolition=1,damagetype,DAMAGE_TYPE_DEMOLITION,WESTRING_DAMAGE_TYPE_DEMOLITION\nDamageTypeSlowPoison=1,damagetype,DAMAGE_TYPE_SLOW_POISON,WESTRING_DAMAGE_TYPE_SLOW_POISON\nDamageTypeSpiritLink=1,damagetype,DAMAGE_TYPE_SPIRIT_LINK,WESTRING_DAMAGE_TYPE_SPIRIT_LINK\nDamageTypeShadowStrike=1,damagetype,DAMAGE_TYPE_SHADOW_STRIKE,WESTRING_DAMAGE_TYPE_SHADOW_STRIKE\nDamageTypeUniversal=1,damagetype,DAMAGE_TYPE_UNIVERSAL,WESTRING_DAMAGE_TYPE_UNIVERSAL\n\n// Weapon types\nWEAPON_TYPE_WHOKNOWS=1,weapontype,WEAPON_TYPE_WHOKNOWS,无\nWeaponTypeMetalLightChop=1,weapontype,WEAPON_TYPE_METAL_LIGHT_CHOP,WESTRING_UE_COMBATSOUND_METALLIGHTCHOP\nWeaponTypeMetalMediumChop=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_CHOP,WESTRING_UE_COMBATSOUND_METALMEDIUMCHOP\nWeaponTypeMetalHeavyChop=1,weapontype,WEAPON_TYPE_METAL_HEAVY_CHOP,WESTRING_UE_COMBATSOUND_METALHEAVYCHOP\nWeaponTypeMetalLightSlice=1,weapontype,WEAPON_TYPE_METAL_LIGHT_SLICE,WESTRING_UE_COMBATSOUND_METALLIGHTSLICE\nWeaponTypeMetalMediumSlice=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_SLICE,WESTRING_UE_COMBATSOUND_METALMEDIUMSLICE\nWeaponTypeMetalHeavySlice=1,weapontype,WEAPON_TYPE_METAL_HEAVY_SLICE,WESTRING_UE_COMBATSOUND_METALHEAVYSLICE\nWeaponTypeMetalMediumBash=1,weapontype,WEAPON_TYPE_METAL_MEDIUM_BASH,WESTRING_UE_COMBATSOUND_METALMEDIUMBASH\nWeaponTypeMetalHeavyBash=1,weapontype,WEAPON_TYPE_METAL_HEAVY_BASH,WESTRING_UE_COMBATSOUND_METALHEAVYBASH\nWeaponTypeWoodLightBash=1,weapontype,WEAPON_TYPE_WOOD_LIGHT_BASH,WESTRING_UE_COMBATSOUND_WOODLIGHTBASH\nWeaponTypeWoodMediumBash=1,weapontype,WEAPON_TYPE_WOOD_MEDIUM_BASH,WESTRING_UE_COMBATSOUND_WOODMEDIUMBASH\nWeaponTypeWoodHeavyBash=1,weapontype,WEAPON_TYPE_WOOD_HEAVY_BASH,WESTRING_UE_COMBATSOUND_WOODHEAVYBASH\nWeaponTypeAxeMediumChop=1,weapontype,WEAPON_TYPE_AXE_MEDIUM_CHOP,WESTRING_UE_COMBATSOUND_AXEMEDIUMCHOP\nWeaponTypeRockHeavyBash=1,weapontype,WEAPON_TYPE_ROCK_HEAVY_BASH,WESTRING_UE_COMBATSOUND_ROCKHEAVYBASH\n\nPathingTypeAny=1,pathingtype,PATHING_TYPE_ANY,WESTRING_PATHINGTYPE_ANY\nPathingTypeWalkability=1,pathingtype,PATHING_TYPE_WALKABILITY,WESTRING_PATHINGTYPE_WALKABILITY\nPathingTypeFlyability=1,pathingtype,PATHING_TYPE_FLYABILITY,WESTRING_PATHINGTYPE_FLYABILITY\nPathingTypeBuildability=1,pathingtype,PATHING_TYPE_BUILDABILITY,WESTRING_PATHINGTYPE_BUILDABILITY\nPathingTypePeonHarvestPathing=1,pathingtype,PATHING_TYPE_PEONHARVESTPATHING,WESTRING_PATHINGTYPE_PEONHARVESTPATHING\nPathingTypeBlightPathing=1,pathingtype,PATHING_TYPE_BLIGHTPATHING,WESTRING_PATHINGTYPE_BLIGHTPATHING\nPathingTypeFloatability=1,pathingtype,PATHING_TYPE_FLOATABILITY,WESTRING_PATHINGTYPE_FLOATABILITY\nPathingTypeAmphibiousPathing=1,pathingtype,PATHING_TYPE_AMPHIBIOUSPATHING,WESTRING_PATHINGTYPE_AMPHIBIOUSPATHING\n\n// Camera fields\nCameraFieldTargetDistance=0,camerafield,CAMERA_FIELD_TARGET_DISTANCE,WESTRING_CAMERA_TARGETDISTANCE\nCameraFieldFarZ=0,camerafield,CAMERA_FIELD_FARZ,WESTRING_CAMERA_FARZ\nCameraFieldAOA=0,camerafield,CAMERA_FIELD_ANGLE_OF_ATTACK,WESTRING_CAMERA_AOA\nCameraFieldFOV=0,camerafield,CAMERA_FIELD_FIELD_OF_VIEW,WESTRING_CAMERA_FOV\nCameraFieldRoll=0,camerafield,CAMERA_FIELD_ROLL,WESTRING_CAMERA_ROLL\nCameraFieldRotation=0,camerafield,CAMERA_FIELD_ROTATION,WESTRING_CAMERA_ROTATION\nCameraFieldZOffset=1,camerafield,CAMERA_FIELD_ZOFFSET,WESTRING_CAMERA_ZOFFSET\n\n// Animation rarity controls\nRarityControlFrequent=0,raritycontrol,RARITY_FREQUENT,WESTRING_RARITY_FREQUENT\nRarityControlRare=0,raritycontrol,RARITY_RARE,WESTRING_RARITY_RARE\n\n// Blending Methods\nBlendModeNone=0,blendmode,BLEND_MODE_NONE,WESTRING_BLENDMODE_NONE\nBlendModeBlend=0,blendmode,BLEND_MODE_BLEND,WESTRING_BLENDMODE_BLEND\nBlendModeAdditive=0,blendmode,BLEND_MODE_ADDITIVE,WESTRING_BLENDMODE_ADDITIVE\nBlendModeModulate=0,blendmode,BLEND_MODE_MODULATE,WESTRING_BLENDMODE_MODULATE\nBlendModeModulate2x=0,blendmode,BLEND_MODE_MODULATE_2X,WESTRING_BLENDMODE_MODULATE_2X\nBlendModeKeyAlpha=0,blendmode,BLEND_MODE_KEYALPHA,WESTRING_BLENDMODE_KEYALPHA\n\n// Volume Groups\nVolumeGroupAmbient=0,volumegroup,SOUND_VOLUMEGROUP_AMBIENTSOUNDS,WESTRING_VOLUMEGROUP_AMBIENTSOUNDS\nVolumeGroupSpells=0,volumegroup,SOUND_VOLUMEGROUP_SPELLS,WESTRING_VOLUMEGROUP_SPELLS\nVolumeGroupCombat=0,volumegroup,SOUND_VOLUMEGROUP_COMBAT,WESTRING_VOLUMEGROUP_COMBAT\nVolumeGroupFire=0,volumegroup,SOUND_VOLUMEGROUP_FIRE,WESTRING_VOLUMEGROUP_FIRE\nVolumeGroupMusic=0,volumegroup,SOUND_VOLUMEGROUP_MUSIC,WESTRING_VOLUMEGROUP_MUSIC\nVolumeGroupUnitMovement=0,volumegroup,SOUND_VOLUMEGROUP_UNITMOVEMENT,WESTRING_VOLUMEGROUP_UNITMOVEMENT\nVolumeGroupUnitSounds=0,volumegroup,SOUND_VOLUMEGROUP_UNITSOUNDS,WESTRING_VOLUMEGROUP_UNITSOUNDS\nVolumeGroupUI=0,volumegroup,SOUND_VOLUMEGROUP_UI,WESTRING_VOLUMEGROUP_UI\n\nEffectTypeEffect=1,effecttype,EFFECT_TYPE_EFFECT,WESTRING_EFFECT_TYPE_EFFECT\nEffectTypeTarget=1,effecttype,EFFECT_TYPE_TARGET,WESTRING_EFFECT_TYPE_TARGET\nEffectTypeCaster=1,effecttype,EFFECT_TYPE_CASTER,WESTRING_EFFECT_TYPE_CASTER\nEffectTypeSpecial=1,effecttype,EFFECT_TYPE_SPECIAL,WESTRING_EFFECT_TYPE_SPECIAL\nEffectTypeAreaEffect=1,effecttype,EFFECT_TYPE_AREA_EFFECT,WESTRING_EFFECT_TYPE_AREA_EFFECT\nEffectTypeMissile=1,effecttype,EFFECT_TYPE_MISSILE,WESTRING_EFFECT_TYPE_MISSILE\nEffectTypeLightning=1,effecttype,EFFECT_TYPE_LIGHTNING,WESTRING_EFFECT_TYPE_LIGHTNING\n\nSoundTypeEffect=1,soundtype,SOUND_TYPE_EFFECT,WESTRING_SOUND_TYPE_EFFECT\nSoundTypeEffectLooped=1,soundtype,SOUND_TYPE_EFFECT_LOOPED,WESTRING_SOUND_TYPE_EFFECT_LOOPED\n\n// Fog states\nFogStateMasked=0,fogstate,FOG_OF_WAR_MASKED,WESTRING_FOGSTATE_MASKED\nFogStateFogged=0,fogstate,FOG_OF_WAR_FOGGED,WESTRING_FOGSTATE_FOGGED\nFogStateVisible=0,fogstate,FOG_OF_WAR_VISIBLE,WESTRING_FOGSTATE_VISIBLE\n\n// Fog styles\nFogStyleLinear=0,fogstyle,0,WESTRING_FOGSTYLE_LINEAR\nFogStyleExp1=0,fogstyle,1,WESTRING_FOGSTYLE_EXP1\nFogStyleExp2=0,fogstyle,2,WESTRING_FOGSTYLE_EXP2\n\n// Timed-life buff codes\nTimedLifeBuffCodeAnimateDead=1,timedlifebuffcode,'BUan',WESTRING_TIMEDLIFEBUFFCODE_ANIMATEDEAD\nTimedLifeBuffCodePlagueWard=1,timedlifebuffcode,'Bapl',WESTRING_TIMEDLIFEBUFFCODE_PLAGUEWARD\nTimedLifeBuffCodeForceOfNature=1,timedlifebuffcode,'BEfn',WESTRING_TIMEDLIFEBUFFCODE_FORCEOFNATURE\nTimedLifeBuffCodeGeneric=1,timedlifebuffcode,'BTLF',WESTRING_TIMEDLIFEBUFFCODE_GENERIC\nTimedLifeBuffCodeHealingWard=1,timedlifebuffcode,'Bhwd',WESTRING_TIMEDLIFEBUFFCODE_HEALINGWARD\nTimedLifeBuffCodeRaiseDead=1,timedlifebuffcode,'Brai',WESTRING_TIMEDLIFEBUFFCODE_RAISEDEAD\nTimedLifeBuffCodeWaterElemental=1,timedlifebuffcode,'BHwe',WESTRING_TIMEDLIFEBUFFCODE_WATERELEMENTAL\n\n// Item status codes\nItemStatusHidden=1,itemstatus,bj_ITEM_STATUS_HIDDEN,WESTRING_ITEMSTATUS_HIDDEN\nItemStatusOwned=1,itemstatus,bj_ITEM_STATUS_OWNED,WESTRING_ITEMSTATUS_OWNED\nItemStatusInvulnerable=1,itemstatus,bj_ITEM_STATUS_INVULNERABLE,WESTRING_ITEMSTATUS_INVULNERABLE\nItemStatusPowerup=1,itemstatus,bj_ITEM_STATUS_POWERUP,WESTRING_ITEMSTATUS_POWERUP\nItemStatusSellable=1,itemstatus,bj_ITEM_STATUS_SELLABLE,WESTRING_ITEMSTATUS_SELLABLE\nItemStatusPawnable=1,itemstatus,bj_ITEM_STATUS_PAWNABLE,WESTRING_ITEMSTATUS_PAWNABLE\n\n// Itemcode status codes\nItemcodeStatusPowerup=1,itemcodestatus,bj_ITEMCODE_STATUS_POWERUP,WESTRING_ITEMCODESTATUS_POWERUP\nItemcodeStatusSellable=1,itemcodestatus,bj_ITEMCODE_STATUS_SELLABLE,WESTRING_ITEMCODESTATUS_SELLABLE\nItemcodeStatusPawnable=1,itemcodestatus,bj_ITEMCODE_STATUS_PAWNABLE,WESTRING_ITEMCODESTATUS_PAWNABLE\n\n// Minimap ping styles\nMinimapPingStyleSimple=1,minimappingstyle,bj_MINIMAPPINGSTYLE_SIMPLE,WESTRING_MINIMAPPINGSTYLE_SIMPLE\nMinimapPingStyleFlashy=1,minimappingstyle,bj_MINIMAPPINGSTYLE_FLASHY,WESTRING_MINIMAPPINGSTYLE_FLASHY\nMinimapPingStyleAttack=1,minimappingstyle,bj_MINIMAPPINGSTYLE_ATTACK,WESTRING_MINIMAPPINGSTYLE_ATTACK\n\n// Corpse creation styles\nCorpseTypeFlesh=1,corpsetype,bj_CORPSETYPE_FLESH,WESTRING_CORPSETYPE_FLESH\nCorpseTypeBone=1,corpsetype,bj_CORPSETYPE_BONE,WESTRING_CORPSETYPE_BONE\n\n// String case option\nStringCaseLower=1,stringcaseoption,false,WESTRING_STRINGCASE_LOWER\nStringCaseUpper=1,stringcaseoption,true,WESTRING_STRINGCASE_UPPER\n\n// Change color option\nChangeColorTrue=0,colorchangeoption,true,WESTRING_CHANGECOLOR_CHANGE\nChangeColorFalse=0,colorchangeoption,false,WESTRING_CHANGECOLOR_RETAIN\n\n// Player Change Color option\nPlayerChangeColorChange=0,playerchangecoloroption,true,WESTRING_SETPLAYERCOLOR_CHANGE\nPlayerChangeColorRetain=0,playerchangecoloroption,false,WESTRING_SETPLAYERCOLOR_RETAIN\n\n// Chat match types\nChatMatchTypeExact=0,chatmatchtype,true,WESTRING_CHATMATCH_EXACT\nChatMatchTypeSubstring=0,chatmatchtype,false,WESTRING_CHATMATCH_SUBSTRING\n\n// UnitFacing bones\nUnitFacingBoneHead=0,unitfacingbone,`bone_head`,WESTRING_UNITFACINGBONE_HEAD\nUnitFacingBoneChest=0,unitfacingbone,`bone_chest`,WESTRING_UNITFACINGBONE_CHEST\n\n// Include option\nInclusionInclude=0,includeoption,true,WESTRING_INCLUSION_INCLUDE\nInclusionExclude=0,includeoption,false,WESTRING_INCLUSION_EXCLUDE\n\n// IncludeOptionNot\nInclusionIncludeNot=0,includeoptionnot,false,WESTRING_INCLUSION_INCLUDE\nInclusionExcludeNot=0,includeoptionnot,true,WESTRING_INCLUSION_EXCLUDE\n\n// Camera Pan option\nCameraApply=0,cameraapplyoption,true,WESTRING_CAMERAAPPLYOPTION_APPLY\nCameraApplyNoPan=0,cameraapplyoption,false,WESTRING_CAMERAAPPLYOPTION_APPLYNOPAN\n\n// Camera Orientation option\nCameraOrientationNormal=0,cameraorientationoption,false,WESTRING_CAMERAORIENTATION_NORMAL\nCameraOrientationInherit=0,cameraorientationoption,true,WESTRING_CAMERAORIENTATION_INHERIT\n\n// Invulnerability option\nInvulnerabilityInvulnerable=0,invulnerableoption,true,WESTRING_INVULNERABILITY_INVULNERABLE\nInvulnerabilityVulnerable=0,invulnerableoption,false,WESTRING_INVULNERABILITY_VULNERABLE\n\n// Availability option\nAvailabilityOptionAvailable=0,availabilityoption,true,WESTRING_AVAILABILITY_AVAILABLE\nAvailabilityOptionUnavailable=0,availabilityoption,false,WESTRING_AVAILABILITY_UNAVAILABLE\n\n// ShowHide option\nShowHideHide=0,showhideoption,false,WESTRING_SHOWHIDE_HIDE\nShowHideShow=0,showhideoption,true,WESTRING_SHOWHIDE_SHOW\n\n// Minimize option\nMinimize=1,minimizeoption,true,WESTRING_MINIMIZEOPTION_MINIMIZE\nMaximize=1,minimizeoption,false,WESTRING_MINIMIZEOPTION_MAXIMIZE\n\n// Sky Model\nSkyModelNone=0,skymodelstring,null,WESTRING_SKYMODEL_NONE\nSkyModelSky08=0,skymodelstring,`Environment\\\\Sky\\\\BlizzardSky\\\\BlizzardSky.mdl`,WESTRING_SKYMODEL_SKY08\nSkyModelSky02=0,skymodelstring,`Environment\\\\Sky\\\\DalaranSky\\\\DalaranSky.mdl`,WESTRING_SKYMODEL_SKY02\nSkyModelSky06=0,skymodelstring,`Environment\\\\Sky\\\\FelwoodSky\\\\FelwoodSky.mdl`,WESTRING_SKYMODEL_SKY06\nSkyModelSky07=0,skymodelstring,`Environment\\\\Sky\\\\FoggedSky\\\\FoggedSky.mdl`,WESTRING_SKYMODEL_SKY07\nSkyModelSky01=0,skymodelstring,`Environment\\\\Sky\\\\Sky\\\\SkyLight.mdl`,WESTRING_SKYMODEL_SKY01\nSkyModelSky03=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronFallSky\\\\LordaeronFallSky.mdl`,WESTRING_SKYMODEL_SKY03\nSkyModelSky04=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronSummerSky\\\\LordaeronSummerSky.mdl`,WESTRING_SKYMODEL_SKY04\nSkyModelSky05=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSky\\\\LordaeronWinterSky.mdl`,WESTRING_SKYMODEL_SKY05\nSkyModelSky09=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyBrightGreen\\\\LordaeronWinterSkyBrightGreen.mdl`,WESTRING_SKYMODEL_SKY09\nSkyModelSky10=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyPink\\\\LordaeronWinterSkyPink.mdl`,WESTRING_SKYMODEL_SKY10\nSkyModelSky11=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyPurple\\\\LordaeronWinterSkyPurple.mdl`,WESTRING_SKYMODEL_SKY11\nSkyModelSky12=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyRed\\\\LordaeronWinterSkyRed.mdl`,WESTRING_SKYMODEL_SKY12\nSkyModelSky13=0,skymodelstring,`Environment\\\\Sky\\\\LordaeronWinterSkyYellow\\\\LordaeronWinterSkyYellow.mdl`,WESTRING_SKYMODEL_SKY13\nSkyModelSky14=1,skymodelstring,`Environment\\\\Sky\\\\Outland_Sky\\\\Outland_Sky.mdl`,WESTRING_SKYMODEL_SKY14\n\n// Cinematic filter textures\nCineFilterTextureWhite=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\White_mask.blp`,WESTRING_CINEFILTERTEX_WHITE\nCineFilterTextureBlack=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Black_mask.blp`,WESTRING_CINEFILTERTEX_BLACK\nCineFilterTextureHaze=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\HazeFilter_mask.blp`,WESTRING_CINEFILTERTEX_HAZE\nCineFilterTextureGroundFog=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\GroundFog_mask.blp`,WESTRING_CINEFILTERTEX_GROUNDFOG\nCineFilterTextureHazeAndFog=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\HazeAndFogFilter_Mask.blp`,WESTRING_CINEFILTERTEX_HAZEANDFOG\nCineFilterTextureDiagonal=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\DiagonalSlash_mask.blp`,WESTRING_CINEFILTERTEX_DIAGONAL\nCineFilterTextureDream=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\DreamFilter_Mask.blp`,WESTRING_CINEFILTERTEX_DREAM\nCineFilterTextureScope=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Scope_Mask.blp`,WESTRING_CINEFILTERTEX_SCOPE\nCineFilterTexturePow=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\SpecialPowMask.blp`,WESTRING_CINEFILTERTEX_POW\nCineFilterTextureSplat=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\SpecialSplatMask.blp`,WESTRING_CINEFILTERTEX_SPLAT\nCineFilterTexturePanda=0,cinefiltertexture,`ReplaceableTextures\\\\CameraMasks\\\\Panda-n-Cub.blp`,WESTRING_CINEFILTERTEX_PANDA\n\n// Music themes\nMusicThemeArthas=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\ArthasTheme.mp3`,WESTRING_MUSICTHEME_ARTHAS\nMusicThemeBloodElf=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\BloodElfTheme.mp3`,WESTRING_MUSICTHEME_BLOODELF\nMusicThemeComradeship=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Comradeship.mp3`,WESTRING_MUSICTHEME_COMRADESHIP\nMusicThemeCredits=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Credits.mp3`,WESTRING_MUSICTHEME_CREDITS\nMusicThemeDarkAgents=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\DarkAgents.mp3`,WESTRING_MUSICTHEME_DARKAGENTS\nMusicThemeDarkVictory=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\DarkVictory.mp3`,WESTRING_MUSICTHEME_DARKVICTORY\nMusicThemeDoom=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Doom.mp3`,WESTRING_MUSICTHEME_DOOM\nMusicThemeHeroicVictory=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HeroicVictory.mp3`,WESTRING_MUSICTHEME_HEROIC_VICTORY\nMusicThemeHuman1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human1.mp3`,WESTRING_MUSICTHEME_HUMAN1\nMusicThemeHuman2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human2.mp3`,WESTRING_MUSICTHEME_HUMAN2\nMusicThemeHuman3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Human3.mp3`,WESTRING_MUSICTHEME_HUMAN3\nMusicThemeHumanX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanX1.mp3`,WESTRING_MUSICTHEME_HUMANX1\nMusicThemeDefeatHuman=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_HUMAN\nMusicThemeVictoryHuman=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\HumanVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_HUMAN\nMusicThemeIllidan=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\IllidansTheme.mp3`,WESTRING_MUSICTHEME_ILLIDAN\nMusicThemeLichKing=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\LichKingTheme.mp3`,WESTRING_MUSICTHEME_LICHKING\nMusicThemeMainScreen=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\MainScreen.mp3`,WESTRING_MUSICTHEME_MAINSCREEN\nMusicThemeMainScreenX=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\War3XMainScreen.mp3`,WESTRING_MUSICTHEME_MAINSCREENX\nMusicThemeNaga=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NagaTheme.mp3`,WESTRING_MUSICTHEME_NAGA\nMusicThemeNightElf1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf1.mp3`,WESTRING_MUSICTHEME_NIGHTELF1\nMusicThemeNightElf2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf2.mp3`,WESTRING_MUSICTHEME_NIGHTELF2\nMusicThemeNightElf3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElf3.mp3`,WESTRING_MUSICTHEME_NIGHTELF3\nMusicThemeNightElfX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfX1.mp3`,WESTRING_MUSICTHEME_NIGHTELFX1\nMusicThemeDefeatNightElf=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_NIGHTELF\nMusicThemeVictoryNightElf=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\NightElfVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_NIGHTELF\nMusicThemeOrc1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc1.mp3`,WESTRING_MUSICTHEME_ORC1\nMusicThemeOrc2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc2.mp3`,WESTRING_MUSICTHEME_ORC2\nMusicThemeOrc3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Orc3.mp3`,WESTRING_MUSICTHEME_ORC3\nMusicThemeOrcX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcX1.mp3`,WESTRING_MUSICTHEME_ORCX1\nMusicThemeDefeatOrc=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_ORC\nMusicThemeOrcTheme=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcTheme.mp3`,WESTRING_MUSICTHEME_ORC_THEME\nMusicThemeVictoryOrc=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\OrcVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_ORC\nMusicThemePersuit=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\PursuitTheme.mp3`,WESTRING_MUSICTHEME_PURSUIT\nMusicThemeSadMystery=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\SadMystery.mp3`,WESTRING_MUSICTHEME_SADMYSTERY\nMusicThemeTension=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Tension.mp3`,WESTRING_MUSICTHEME_TENSION\nMusicThemeTragicConfrontation=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\TragicConfrontation.mp3`,WESTRING_MUSICTHEME_TRAGICCONFRONTATION\nMusicThemeUndead1=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead1.mp3`,WESTRING_MUSICTHEME_UNDEAD1\nMusicThemeUndead2=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead2.mp3`,WESTRING_MUSICTHEME_UNDEAD2\nMusicThemeUndead3=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\Undead3.mp3`,WESTRING_MUSICTHEME_UNDEAD3\nMusicThemeUndeadX1=1,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadX1.mp3`,WESTRING_MUSICTHEME_UNDEADX1\nMusicThemeDefeatUndead=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadDefeat.mp3`,WESTRING_MUSICTHEME_DEFEAT_UNDEAD\nMusicThemeVictoryUndead=0,musictheme,`Sound\\\\Music\\\\mp3Music\\\\UndeadVictory.mp3`,WESTRING_MUSICTHEME_VICTORY_UNDEAD\n\n// Daytime Ambient Themes\nAmbientThemeDayA=0,ambientthemeday,`AshenvaleDay`,WESTRING_AMBIENTTHEMEDAY_A\nAmbientThemeDayB=0,ambientthemeday,`BarrensDay`,WESTRING_AMBIENTTHEMEDAY_B\nAmbientThemeDayK=1,ambientthemeday,`BlackCitadelDay`,WESTRING_AMBIENTTHEMEDAY_K\nAmbientThemeDayY=0,ambientthemeday,`CityScapeDay`,WESTRING_AMBIENTTHEMEDAY_Y\nAmbientThemeDayX=0,ambientthemeday,`DalaranDay`,WESTRING_AMBIENTTHEMEDAY_X\nAmbientThemeDayJ=1,ambientthemeday,`DalaranRuinsDay`,WESTRING_AMBIENTTHEMEDAY_J\nAmbientThemeDayD=0,ambientthemeday,`DungeonDay`,WESTRING_AMBIENTTHEMEDAY_D\nAmbientThemeDayC=0,ambientthemeday,`FelwoodDay`,WESTRING_AMBIENTTHEMEDAY_C\nAmbientThemeDayI=1,ambientthemeday,`IceCrownDay`,WESTRING_AMBIENTTHEMEDAY_I\nAmbientThemeDayF=0,ambientthemeday,`LordaeronFallDay`,WESTRING_AMBIENTTHEMEDAY_F\nAmbientThemeDayL=0,ambientthemeday,`LordaeronSummerDay`,WESTRING_AMBIENTTHEMEDAY_L\nAmbientThemeDayW=0,ambientthemeday,`LordaeronWinterDay`,WESTRING_AMBIENTTHEMEDAY_W\nAmbientThemeDayN=0,ambientthemeday,`NorthrendDay`,WESTRING_AMBIENTTHEMEDAY_N\nAmbientThemeDayO=1,ambientthemeday,`BlackCitadelDay`,WESTRING_AMBIENTTHEMEDAY_O\nAmbientThemeDayZ=1,ambientthemeday,`SunkenRuinsDay`,WESTRING_AMBIENTTHEMEDAY_Z\nAmbientThemeDayV=0,ambientthemeday,`VillageDay`,WESTRING_AMBIENTTHEMEDAY_V\nAmbientThemeDayQ=0,ambientthemeday,`VillageFallDay`,WESTRING_AMBIENTTHEMEDAY_Q\n\n// Nighttime Ambient Themes\nAmbientThemeNightA=0,ambientthemenight,`AshenvaleNight`,WESTRING_AMBIENTTHEMENIGHT_A\nAmbientThemeNightB=0,ambientthemenight,`BarrensNight`,WESTRING_AMBIENTTHEMENIGHT_B\nAmbientThemeNightK=1,ambientthemenight,`BlackCitadelNight`,WESTRING_AMBIENTTHEMENIGHT_K\nAmbientThemeNightY=0,ambientthemenight,`CityScapeNight`,WESTRING_AMBIENTTHEMENIGHT_Y\nAmbientThemeNightX=0,ambientthemenight,`DalaranNight`,WESTRING_AMBIENTTHEMENIGHT_X\nAmbientThemeNightJ=1,ambientthemenight,`DalaranRuinsNight`,WESTRING_AMBIENTTHEMENIGHT_J\nAmbientThemeNightD=0,ambientthemenight,`DungeonNight`,WESTRING_AMBIENTTHEMENIGHT_D\nAmbientThemeNightC=0,ambientthemenight,`FelwoodNight`,WESTRING_AMBIENTTHEMENIGHT_C\nAmbientThemeNightI=1,ambientthemenight,`IceCrownNight`,WESTRING_AMBIENTTHEMENIGHT_I\nAmbientThemeNightF=0,ambientthemenight,`LordaeronFallNight`,WESTRING_AMBIENTTHEMENIGHT_F\nAmbientThemeNightL=0,ambientthemenight,`LordaeronSummerNight`,WESTRING_AMBIENTTHEMENIGHT_L\nAmbientThemeNightW=0,ambientthemenight,`LordaeronWinterNight`,WESTRING_AMBIENTTHEMENIGHT_W\nAmbientThemeNightN=0,ambientthemenight,`NorthrendNight`,WESTRING_AMBIENTTHEMENIGHT_N\nAmbientThemeNightO=1,ambientthemenight,`BlackCitadelNight`,WESTRING_AMBIENTTHEMENIGHT_O\nAmbientThemeNightZ=1,ambientthemenight,`SunkenRuinsNight`,WESTRING_AMBIENTTHEMENIGHT_Z\nAmbientThemeNightV=0,ambientthemenight,`VillageNight`,WESTRING_AMBIENTTHEMENIGHT_V\nAmbientThemeNightQ=0,ambientthemenight,`VillageFallNight`,WESTRING_AMBIENTTHEMENIGHT_Q\n\n// Unit State Method\nUnitStateMethodAbsolute=0,unitstatemethod,bj_UNIT_STATE_METHOD_ABSOLUTE,WESTRING_UNITSTATEMETHOD_ABSOLUTE\nUnitStateMethodRelative=0,unitstatemethod,bj_UNIT_STATE_METHOD_RELATIVE,WESTRING_UNITSTATEMETHOD_RELATIVE\nUnitStateMethodDefaults=0,unitstatemethod,bj_UNIT_STATE_METHOD_DEFAULTS,WESTRING_UNITSTATEMETHOD_DEFAULTS\nUnitStateMethodMaximum=0,unitstatemethod,bj_UNIT_STATE_METHOD_MAXIMUM,WESTRING_UNITSTATEMETHOD_MAXIMUM\n\n// CheckingIgnoring option\nCheckingIgnoringChecking=0,checkingignoringoption,true,WESTRING_CHECKINGIGNORINGOPTION_CHECKING\nCheckingIgnoringIgnoring=0,checkingignoringoption,false,WESTRING_CHECKINGIGNORINGOPTION_IGNORING\n\n// Pathing option\nPathingOn=0,pathingoption,true,WESTRING_PATHING_ON\nPathingOff=0,pathingoption,false,WESTRING_PATHING_OFF\n\n// Pawnable option\nPawnableOptionPawnable=1,pawnableoption,true,WESTRING_PAWNABLEOPTION_PAWNABLE\nPawnableOptionUnpawnable=1,pawnableoption,false,WESTRING_PAWNABLEOPTION_UNPAWNABLE\n\n// DropOnDeath option\nDropNoDropOptionDrop=0,dropnodropoption,true,WESTRING_DROPNODROPOPTION_DROP\nDropNoDropOptionNoDrop=0,dropnodropoption,false,WESTRING_DROPNODROPOPTION_NODROP\n\n// Droppable option\nDroppableOptionDrop=0,droppableoption,true,WESTRING_DROPPABLE_DROP\nDroppableOptionNoDrop=0,droppableoption,false,WESTRING_DROPPABLE_NODROP\n\n// BeforeAfter option\nBeforeAfterBefore=0,beforeafteroption,false,WESTRING_BEFOREAFTER_BEFORE\nBeforeAfterAfter=0,beforeafteroption,true,WESTRING_BEFOREAFTER_AFTER\n\n// OnOff option\nOnOffOn=0,onoffoption,true,WESTRING_ONOFF_ON\nOnOffOff=0,onoffoption,false,WESTRING_ONOFF_OFF\n\n// EnableDisable option\nEnableDisableEnable=0,enabledisableoption,true,WESTRING_ENABLEDISABLE_ENABLE\nEnableDisableDisable=0,enabledisableoption,false,WESTRING_ENABLEDISABLE_DISABLE\n\n// EnabledDisabled option\nEnabledDisabledEnabled=0,enableddisabledoption,true,WESTRING_ENABLEDDISABLED_ENABLED\nEnabledDisabledDisabled=0,enableddisabledoption,false,WESTRING_ENABLEDDISABLED_DISABLED\n\n// Rescuable option\nRescuableOptionRescuable=0,rescuableoption,true,WESTRING_RESCUABLEOPTION_RESCUABLE\nRescuableOptionUnrescuable=0,rescuableoption,false,WESTRING_RESCUABLEOPTION_UNRESCUABLE\n\n// AllowDont option\nAllowDontAllow=0,allowdontoption,true,WESTRING_ALLOWDONTOPTION_ALLOW\nAllowDontDont=0,allowdontoption,false,WESTRING_ALLOWDONTOPTION_DONT\n\n// FadeDont option\nFadeDontFade=0,fadedontoption,true,WESTRING_FADEDONTOPTION_FADE\nFadeDontDont=0,fadedontoption,false,WESTRING_FADEDONTOPTION_DONT\n\n// AddSetTo option\nAddSetToAdd=0,addsettooption,bj_TIMETYPE_ADD,WESTRING_ADDSETTOOPTION_ADD\nAddSetToSub=0,addsettooption,bj_TIMETYPE_SUB,WESTRING_ADDSETTOOPTION_SUB\nAddSetToSet=0,addsettooption,bj_TIMETYPE_SET,WESTRING_ADDSETTOOPTION_SET\n\n// Modify methods\nModifyMethodAdd=1,modifymethod,bj_MODIFYMETHOD_ADD,WESTRING_MODIFYMETHOD_ADD\nModifyMethodSub=1,modifymethod,bj_MODIFYMETHOD_SUB,WESTRING_MODIFYMETHOD_SUB\nModifyMethodSet=1,modifymethod,bj_MODIFYMETHOD_SET,WESTRING_MODIFYMETHOD_SET\n\n// WaitDont option\nWaitDontWait=0,waitdontoption,true,WESTRING_WAITDONTOPTION_WAIT\nWaitDontDont=0,waitdontoption,false,WESTRING_WAITDONTOPTION_DONT\n\n// CraterTypes\nCraterTypeTemporary=1,cratertype,false,WESTRING_CRATERTYPE_TEMPORARY\nCraterTypePermanent=1,cratertype,true,WESTRING_CRATERTYPE_PERMANENT\n\n// RippleTypes\nRippleTypeNormal=1,rippletype,false,WESTRING_RIPPLETYPE_NORMAL\nRippleTypeDepression=1,rippletype,true,WESTRING_RIPPLETYPE_DEPRESSION\n\n// CreateRemove option\nCreateRemoveCreate=0,createremoveoption,true,WESTRING_CREATEREMOVEOPTION_CREATE\nCreateRemoveRemove=0,createremoveoption,false,WESTRING_CREATEREMOVEOPTION_REMOVE\n\n// AddRemove option\nAddRemoveAdd=0,addremoveoption,true,WESTRING_ADDREMOVEOPTION_ADD\nAddRemoveRemove=0,addremoveoption,false,WESTRING_ADDREMOVEOPTION_REMOVE\n\n// QuestType option\nQuestTypeReqDiscovered=0,questtypeoption,bj_QUESTTYPE_REQ_DISCOVERED,WESTRING_QUESTTYPE_REQ_DISCOVERED\nQuestTypeOptDiscovered=0,questtypeoption,bj_QUESTTYPE_OPT_DISCOVERED,WESTRING_QUESTTYPE_OPT_DISCOVERED\nQuestTypeReqUndiscovered=0,questtypeoption,bj_QUESTTYPE_REQ_UNDISCOVERED,WESTRING_QUESTTYPE_REQ_UNDISCOVERED\nQuestTypeOptUndiscovered=0,questtypeoption,bj_QUESTTYPE_OPT_UNDISCOVERED,WESTRING_QUESTTYPE_OPT_UNDISCOVERED\n\n// QuestMessageType option\nQuestMessageTypeDiscovered=0,questmessagetype,bj_QUESTMESSAGE_DISCOVERED,WESTRING_QUESTMESSAGE_DISCOVERED\nQuestMessageTypeUpdated=0,questmessagetype,bj_QUESTMESSAGE_UPDATED,WESTRING_QUESTMESSAGE_UPDATED\nQuestMessageTypeCompleted=0,questmessagetype,bj_QUESTMESSAGE_COMPLETED,WESTRING_QUESTMESSAGE_COMPLETED\nQuestMessageTypeFailed=0,questmessagetype,bj_QUESTMESSAGE_FAILED,WESTRING_QUESTMESSAGE_FAILED\nQuestMessageTypeRequirement=0,questmessagetype,bj_QUESTMESSAGE_REQUIREMENT,WESTRING_QUESTMESSAGE_REQUIREMENT\nQuestMessageTypeMissionFailed=0,questmessagetype,bj_QUESTMESSAGE_MISSIONFAILED,WESTRING_QUESTMESSAGE_MISSIONFAILED\nQuestMessageTypeAlwaysHint=0,questmessagetype,bj_QUESTMESSAGE_ALWAYSHINT,WESTRING_QUESTMESSAGE_ALWAYSHINT\nQuestMessageTypeHint=0,questmessagetype,bj_QUESTMESSAGE_HINT,WESTRING_QUESTMESSAGE_HINT\nQuestMessageTypeSecret=0,questmessagetype,bj_QUESTMESSAGE_SECRET,WESTRING_QUESTMESSAGE_SECRET\nQuestMessageTypeWarning=1,questmessagetype,bj_QUESTMESSAGE_WARNING,WESTRING_QUESTMESSAGE_WARNING\nQuestMessageTypeUnitAcquired=0,questmessagetype,bj_QUESTMESSAGE_UNITACQUIRED,WESTRING_QUESTMESSAGE_UNITACQUIRED\nQuestMessageTypeUnitAvailable=0,questmessagetype,bj_QUESTMESSAGE_UNITAVAILABLE,WESTRING_QUESTMESSAGE_UNITAVAILABLE\nQuestMessageTypeItemAcquired=0,questmessagetype,bj_QUESTMESSAGE_ITEMACQUIRED,WESTRING_QUESTMESSAGE_ITEMACQUIRED\n\n// Hero Stats\nHeroStatStr=1,herostat,bj_HEROSTAT_STR,WESTRING_HEROSTAT_STR\nHeroStatAgi=1,herostat,bj_HEROSTAT_AGI,WESTRING_HEROSTAT_AGI\nHeroStatInt=1,herostat,bj_HEROSTAT_INT,WESTRING_HEROSTAT_INT\n\n// Completion option\nCompletionOptionCompleted=0,completionoption,true,WESTRING_COMPLETIONOPTION_COMPLETED\nCompletionOptionIncomplete=0,completionoption,false,WESTRING_COMPLETIONOPTION_INCOMPLETE\n\n// Failure option\nFailureOptionFailed=0,failureoption,true,WESTRING_FAILUREOPTION_FAILED\nFailureOptionNotFailed=0,failureoption,false,WESTRING_FAILUREOPTION_NOTFAILED\n\n// Discovered option\nDiscoveredOptionDiscovered=0,discoveredoption,true,WESTRING_DISCOVEREDOPTION_DISCOVERED\nDiscoveredOptionUndiscovered=0,discoveredoption,false,WESTRING_DISCOVEREDOPTION_UNDISCOVERED\n\n// PauseResume option\nPauseResumePause=0,pauseresumeoption,true,WESTRING_PAUSERESUMEOPTION_PAUSE\nPauseResumeResume=0,pauseresumeoption,false,WESTRING_PAUSERESUMEOPTION_RESUME\n\n// Periodic option\nPeriodicOptionOneTime=0,periodicoption,false,WESTRING_PERIODICOPTION_ONETIME\nPeriodicOptionPeriodic=0,periodicoption,true,WESTRING_PERIODICOPTION_PERIODIC\n\n// LeaderboardSort option\nLeaderboardSortByValue=0,leaderboardsortoption,bj_SORTTYPE_SORTBYVALUE,WESTRING_LEADERBOARDSORT_BYVALUE\nLeaderboardSortByPlayer=0,leaderboardsortoption,bj_SORTTYPE_SORTBYPLAYER,WESTRING_LEADERBOARDSORT_BYPLAYER\nLeaderboardSortByLabel=0,leaderboardsortoption,bj_SORTTYPE_SORTBYLABEL,WESTRING_LEADERBOARDSORT_BYLABEL\n\n// Ascending option\nAscendingOptionAscending=0,ascendingoption,true,WESTRING_ASCENDINGOPTION_ASCENDING\nAscendingOptionDescending=0,ascendingoption,false,WESTRING_ASCENDINGOPTION_DESCENDING\n\n// SleepWake option\nSleepWakeOptionSleep=0,sleepwakeoption,true,WESTRING_SLEEPWAKEOPTION_SLEEP\nSleepWakeOptionWake=0,sleepwakeoption,false,WESTRING_SLEEPWAKEOPTION_WAKE\n\n// PauseUnpause option\nPauseUnpauseOptionPause=0,pauseunpauseoption,true,WESTRING_PAUSEUNPAUSEOPTION_PAUSE\nPauseUnpauseOptionUnpause=0,pauseunpauseoption,false,WESTRING_PAUSEUNPAUSEOPTION_UNPAUSE\n\n// ShareDont option\nShareDontOptionShare=0,sharedontoption,true,WESTRING_SHAREDONTOPTION_SHARE\nShareDontOptionDont=0,sharedontoption,false,WESTRING_SHAREDONTOPTION_DONT\n\n// InOut option\nFadeTypeOptionFadeOutIn=0,fadetypeoption,bj_CINEFADETYPE_FADEOUTIN,WESTRING_FADETYPEOPTION_FADEOUTIN\nFadeTypeOptionFadeOut=0,fadetypeoption,bj_CINEFADETYPE_FADEOUT,WESTRING_FADETYPEOPTION_FADEOUT\nFadeTypeOptionFadeIn=0,fadetypeoption,bj_CINEFADETYPE_FADEIN,WESTRING_FADETYPEOPTION_FADEIN\n\n// Buff Types\nBuffTypeAll=0,bufftype,bj_REMOVEBUFFS_ALL,WESTRING_BUFFTYPE_ALL\nBuffTypeNonTLife=1,bufftype,bj_REMOVEBUFFS_NONTLIFE,WESTRING_BUFFTYPE_NONTLIFE\nBuffTypePositive=0,bufftype,bj_REMOVEBUFFS_POSITIVE,WESTRING_BUFFTYPE_POSITIVE\nBuffTypeNegative=0,bufftype,bj_REMOVEBUFFS_NEGATIVE,WESTRING_BUFFTYPE_NEGATIVE\n\n// Buff Polarity options\nBuffPolarityPositive=1,buffpolarity,bj_BUFF_POLARITY_POSITIVE,WESTRING_BUFF_POLARITY_POSITIVE\nBuffPolarityNegative=1,buffpolarity,bj_BUFF_POLARITY_NEGATIVE,WESTRING_BUFF_POLARITY_NEGATIVE\nBuffPolarityEither=1,buffpolarity,bj_BUFF_POLARITY_EITHER,WESTRING_BUFF_POLARITY_EITHER\n\n// Buff Resistance types\nBuffResistMagic=1,buffresist,bj_BUFF_RESIST_MAGIC,WESTRING_BUFF_RESIST_MAGIC\nBuffResistPhysical=1,buffresist,bj_BUFF_RESIST_PHYSICAL,WESTRING_BUFF_RESIST_PHYSICAL\nBuffResistEither=1,buffresist,bj_BUFF_RESIST_EITHER,WESTRING_BUFF_RESIST_EITHER\nBuffResistBoth=1,buffresist,bj_BUFF_RESIST_BOTH,WESTRING_BUFF_RESIST_BOTH\n\n// Camera Bounds Adjustment Type\nCameraBoundsAdjustAdd=0,cameraboundsadjusttype,bj_CAMERABOUNDS_ADJUST_ADD,WESTRING_CAMERABOUNDSADJUST_ADD\nCameraBoundsAdjustSub=0,cameraboundsadjusttype,bj_CAMERABOUNDS_ADJUST_SUB,WESTRING_CAMERABOUNDSADJUST_SUB\n\n// Availability Option\nAvailableOptionAvailable=0,availableoption,true,WESTRING_AVAILABLEOPTION_AVAILABLE\nAvailableOptionUnavailable=0,availableoption,false,WESTRING_AVAILABLEOPTION_UNAVAILABLE\n\n// Explode Option\nExplodeDontExplode=0,explodedontoption,true,WESTRING_EXPLODEDONTOPTION_EXPLODE\nExplodeDontDont=0,explodedontoption,false,WESTRING_EXPLODEDONTOPTION_DONT\n\n// SuspendResume Option\nSuspendResumeSuspend=0,suspendresumeoption,true,WESTRING_SUSPENDRESUMEOPTION_SUSPEND\nSuspendResumeResume=0,suspendresumeoption,true,WESTRING_SUSPENDRESUMEOPTION_RESUME\n\nSuspendResumeSuspend_R=0,suspendresumeoption_R,true,WESTRING_SUSPENDRESUMEOPTION_SUSPEND\nSuspendResumeResume_R=0,suspendresumeoption_R,false,WESTRING_SUSPENDRESUMEOPTION_RESUME\n\n// Tournament Game Event Types\nGameEventTourneySoon=1,gameevent,EVENT_GAME_TOURNAMENT_FINISH_SOON,WESTRING_GAMEEVENT_TOURNAMENTFINISHSOON\nGameEventTourneyNow=1,gameevent,EVENT_GAME_TOURNAMENT_FINISH_NOW,WESTRING_GAMEEVENT_TOURNAMENTFINISHNOW\n\n//NearestOnlyOption\nNearestOnlyOn=0,nearestonlyoption,true,只选取最近的一个单位\nNearestOnlyOff=0,nearestonlyoption,false,选取范围内所有单位\n\n//IsNotOption\nIsNotIs=0,isnotoption,true,是\nIsNotNot=0,isnotoption,false,不是\n\n//LockUnLockOption\nLockUnLockLock=0,lockunlockoption,true,锁定\nLockUnLockUnLock=0,lockunlockoption,false,解除锁定\n\n//VertOnlyOption\nVertOnlyOn=0,vertonlyoption,true,垂直晃动\nVertOnlyOff=0,vertonlyoption,false,水平晃动\n\n//pingstyle\nPingStyleNormal=0,pingstyle,true,惊叹号\nPingStyleExtra=0,pingstyle,false,普通\n\n//sharevisionoption=0,0,0,共享视野选项,boolean\nShareVisionShare=0,sharevisionoption,true,共享\nShareVisionNot=0,sharevisionoption,false,不共享\n\n//converunitoption\nConverUnitConver=0,converunitoption,true,覆盖\nConverUnitNot=0,converunitoption,false,不覆盖\n\n// OnOffIntoption\nOnOffIntOn=0,onoffintoption,1,WESTRING_ONOFF_ON\nOnOffIntOff=0,onoffintoption,0,WESTRING_ONOFF_OFF\n\n// OnOffNotoption\nOnOffNotOn=0,onoffnotoption,true,WESTRING_ONOFF_OFF\nOnOffNotOff=0,onoffnotoption,false,WESTRING_ONOFF_ON\n\n// Mission Index\n// Tutorial\nMissionIndexT00=0,missionindex,bj_MISSION_INDEX_T00,WESTRING_MISSION_INDEX_T00\nMissionIndexT01=0,missionindex,bj_MISSION_INDEX_T01,WESTRING_MISSION_INDEX_T01\n// Human\nMissionIndexH00=0,missionindex,bj_MISSION_INDEX_H00,WESTRING_MISSION_INDEX_H00\nMissionIndexH01=0,missionindex,bj_MISSION_INDEX_H01,WESTRING_MISSION_INDEX_H01\nMissionIndexH02=0,missionindex,bj_MISSION_INDEX_H02,WESTRING_MISSION_INDEX_H02\nMissionIndexH03=0,missionindex,bj_MISSION_INDEX_H03,WESTRING_MISSION_INDEX_H03\nMissionIndexH04=0,missionindex,bj_MISSION_INDEX_H04,WESTRING_MISSION_INDEX_H04\nMissionIndexH05=0,missionindex,bj_MISSION_INDEX_H05,WESTRING_MISSION_INDEX_H05\nMissionIndexH06=0,missionindex,bj_MISSION_INDEX_H06,WESTRING_MISSION_INDEX_H06\nMissionIndexH07=0,missionindex,bj_MISSION_INDEX_H07,WESTRING_MISSION_INDEX_H07\nMissionIndexH08=0,missionindex,bj_MISSION_INDEX_H08,WESTRING_MISSION_INDEX_H08\nMissionIndexH09=0,missionindex,bj_MISSION_INDEX_H09,WESTRING_MISSION_INDEX_H09\nMissionIndexH10=0,missionindex,bj_MISSION_INDEX_H10,WESTRING_MISSION_INDEX_H10\nMissionIndexH11=0,missionindex,bj_MISSION_INDEX_H11,WESTRING_MISSION_INDEX_H11\n// Undead\nMissionIndexU00=0,missionindex,bj_MISSION_INDEX_U00,WESTRING_MISSION_INDEX_U00\nMissionIndexU01=0,missionindex,bj_MISSION_INDEX_U01,WESTRING_MISSION_INDEX_U01\nMissionIndexU02=0,missionindex,bj_MISSION_INDEX_U02,WESTRING_MISSION_INDEX_U02\nMissionIndexU03=0,missionindex,bj_MISSION_INDEX_U03,WESTRING_MISSION_INDEX_U03\nMissionIndexU05=0,missionindex,bj_MISSION_INDEX_U05,WESTRING_MISSION_INDEX_U05\nMissionIndexU07=0,missionindex,bj_MISSION_INDEX_U07,WESTRING_MISSION_INDEX_U07\nMissionIndexU08=0,missionindex,bj_MISSION_INDEX_U08,WESTRING_MISSION_INDEX_U08\nMissionIndexU09=0,missionindex,bj_MISSION_INDEX_U09,WESTRING_MISSION_INDEX_U09\nMissionIndexU10=0,missionindex,bj_MISSION_INDEX_U10,WESTRING_MISSION_INDEX_U10\nMissionIndexU11=0,missionindex,bj_MISSION_INDEX_U11,WESTRING_MISSION_INDEX_U11\n// Orc\nMissionIndexO00=0,missionindex,bj_MISSION_INDEX_O00,WESTRING_MISSION_INDEX_O00\nMissionIndexO01=0,missionindex,bj_MISSION_INDEX_O01,WESTRING_MISSION_INDEX_O01\nMissionIndexO02=0,missionindex,bj_MISSION_INDEX_O02,WESTRING_MISSION_INDEX_O02\nMissionIndexO03=0,missionindex,bj_MISSION_INDEX_O03,WESTRING_MISSION_INDEX_O03\nMissionIndexO04=0,missionindex,bj_MISSION_INDEX_O04,WESTRING_MISSION_INDEX_O04\nMissionIndexO05=0,missionindex,bj_MISSION_INDEX_O05,WESTRING_MISSION_INDEX_O05\nMissionIndexO06=0,missionindex,bj_MISSION_INDEX_O06,WESTRING_MISSION_INDEX_O06\nMissionIndexO07=0,missionindex,bj_MISSION_INDEX_O07,WESTRING_MISSION_INDEX_O07\nMissionIndexO08=0,missionindex,bj_MISSION_INDEX_O08,WESTRING_MISSION_INDEX_O08\nMissionIndexO09=0,missionindex,bj_MISSION_INDEX_O09,WESTRING_MISSION_INDEX_O09\nMissionIndexO10=0,missionindex,bj_MISSION_INDEX_O10,WESTRING_MISSION_INDEX_O10\n// Night Elf\nMissionIndexN00=0,missionindex,bj_MISSION_INDEX_N00,WESTRING_MISSION_INDEX_N00\nMissionIndexN01=0,missionindex,bj_MISSION_INDEX_N01,WESTRING_MISSION_INDEX_N01\nMissionIndexN02=0,missionindex,bj_MISSION_INDEX_N02,WESTRING_MISSION_INDEX_N02\nMissionIndexN03=0,missionindex,bj_MISSION_INDEX_N03,WESTRING_MISSION_INDEX_N03\nMissionIndexN04=0,missionindex,bj_MISSION_INDEX_N04,WESTRING_MISSION_INDEX_N04\nMissionIndexN05=0,missionindex,bj_MISSION_INDEX_N05,WESTRING_MISSION_INDEX_N05\nMissionIndexN06=0,missionindex,bj_MISSION_INDEX_N06,WESTRING_MISSION_INDEX_N06\nMissionIndexN07=0,missionindex,bj_MISSION_INDEX_N07,WESTRING_MISSION_INDEX_N07\n// Expansion Night Elf\nMissionIndexXN00=1,missionindex,bj_MISSION_INDEX_XN00,WESTRING_MISSION_INDEX_XN00\nMissionIndexXN01=1,missionindex,bj_MISSION_INDEX_XN01,WESTRING_MISSION_INDEX_XN01\nMissionIndexXN02=1,missionindex,bj_MISSION_INDEX_XN02,WESTRING_MISSION_INDEX_XN02\nMissionIndexXN03=1,missionindex,bj_MISSION_INDEX_XN03,WESTRING_MISSION_INDEX_XN03\nMissionIndexXN04=1,missionindex,bj_MISSION_INDEX_XN04,WESTRING_MISSION_INDEX_XN04\nMissionIndexXN05=1,missionindex,bj_MISSION_INDEX_XN05,WESTRING_MISSION_INDEX_XN05\nMissionIndexXN06=1,missionindex,bj_MISSION_INDEX_XN06,WESTRING_MISSION_INDEX_XN06\nMissionIndexXN07=1,missionindex,bj_MISSION_INDEX_XN07,WESTRING_MISSION_INDEX_XN07\nMissionIndexXN08=1,missionindex,bj_MISSION_INDEX_XN08,WESTRING_MISSION_INDEX_XN08\nMissionIndexXN09=1,missionindex,bj_MISSION_INDEX_XN09,WESTRING_MISSION_INDEX_XN09\nMissionIndexXN10=1,missionindex,bj_MISSION_INDEX_XN10,WESTRING_MISSION_INDEX_XN10\n// Expansion Human\nMissionIndexXH00=1,missionindex,bj_MISSION_INDEX_XH00,WESTRING_MISSION_INDEX_XH00\nMissionIndexXH01=1,missionindex,bj_MISSION_INDEX_XH01,WESTRING_MISSION_INDEX_XH01\nMissionIndexXH02=1,missionindex,bj_MISSION_INDEX_XH02,WESTRING_MISSION_INDEX_XH02\nMissionIndexXH03=1,missionindex,bj_MISSION_INDEX_XH03,WESTRING_MISSION_INDEX_XH03\nMissionIndexXH04=1,missionindex,bj_MISSION_INDEX_XH04,WESTRING_MISSION_INDEX_XH04\nMissionIndexXH05=1,missionindex,bj_MISSION_INDEX_XH05,WESTRING_MISSION_INDEX_XH05\nMissionIndexXH06=1,missionindex,bj_MISSION_INDEX_XH06,WESTRING_MISSION_INDEX_XH06\nMissionIndexXH07=1,missionindex,bj_MISSION_INDEX_XH07,WESTRING_MISSION_INDEX_XH07\nMissionIndexXH08=1,missionindex,bj_MISSION_INDEX_XH08,WESTRING_MISSION_INDEX_XH08\nMissionIndexXH09=1,missionindex,bj_MISSION_INDEX_XH09,WESTRING_MISSION_INDEX_XH09\n// Expansion Undead\nMissionIndexXU00=1,missionindex,bj_MISSION_INDEX_XU00,WESTRING_MISSION_INDEX_XU00\nMissionIndexXU01=1,missionindex,bj_MISSION_INDEX_XU01,WESTRING_MISSION_INDEX_XU01\nMissionIndexXU02=1,missionindex,bj_MISSION_INDEX_XU02,WESTRING_MISSION_INDEX_XU02\nMissionIndexXU03=1,missionindex,bj_MISSION_INDEX_XU03,WESTRING_MISSION_INDEX_XU03\nMissionIndexXU04=1,missionindex,bj_MISSION_INDEX_XU04,WESTRING_MISSION_INDEX_XU04\nMissionIndexXU05=1,missionindex,bj_MISSION_INDEX_XU05,WESTRING_MISSION_INDEX_XU05\nMissionIndexXU06=1,missionindex,bj_MISSION_INDEX_XU06,WESTRING_MISSION_INDEX_XU06\nMissionIndexXU07=1,missionindex,bj_MISSION_INDEX_XU07,WESTRING_MISSION_INDEX_XU07\nMissionIndexXU08=1,missionindex,bj_MISSION_INDEX_XU08,WESTRING_MISSION_INDEX_XU08\nMissionIndexXU09=1,missionindex,bj_MISSION_INDEX_XU09,WESTRING_MISSION_INDEX_XU09\nMissionIndexXU10=1,missionindex,bj_MISSION_INDEX_XU10,WESTRING_MISSION_INDEX_XU10\nMissionIndexXU11=1,missionindex,bj_MISSION_INDEX_XU11,WESTRING_MISSION_INDEX_XU11\nMissionIndexXU12=1,missionindex,bj_MISSION_INDEX_XU12,WESTRING_MISSION_INDEX_XU12\nMissionIndexXU13=1,missionindex,bj_MISSION_INDEX_XU13,WESTRING_MISSION_INDEX_XU13\n// Expansion Orc\nMissionIndexXO00=1,missionindex,bj_MISSION_INDEX_XO00,WESTRING_MISSION_INDEX_XO00\n\n// Campaign Index\nCampaignIndexT=0,campaignindex,bj_CAMPAIGN_INDEX_T,WESTRING_CAMPAIGN_INDEX_T\nCampaignIndexH=0,campaignindex,bj_CAMPAIGN_INDEX_H,WESTRING_CAMPAIGN_INDEX_H\nCampaignIndexU=0,campaignindex,bj_CAMPAIGN_INDEX_U,WESTRING_CAMPAIGN_INDEX_U\nCampaignIndexO=0,campaignindex,bj_CAMPAIGN_INDEX_O,WESTRING_CAMPAIGN_INDEX_O\nCampaignIndexN=0,campaignindex,bj_CAMPAIGN_INDEX_N,WESTRING_CAMPAIGN_INDEX_N\nCampaignIndexXN=1,campaignindex,bj_CAMPAIGN_INDEX_XN,WESTRING_CAMPAIGN_INDEX_XN\nCampaignIndexXH=1,campaignindex,bj_CAMPAIGN_INDEX_XH,WESTRING_CAMPAIGN_INDEX_XH\nCampaignIndexXU=1,campaignindex,bj_CAMPAIGN_INDEX_XU,WESTRING_CAMPAIGN_INDEX_XU\nCampaignIndexXO=1,campaignindex,bj_CAMPAIGN_INDEX_XO,WESTRING_CAMPAIGN_INDEX_XO\n\n// Cinematic Index\nCinematicIndexTOP=0,cinematicindex,bj_CINEMATICINDEX_TOP,WESTRING_CINEMATICTYPE_TOP\nCinematicIndexHOP=0,cinematicindex,bj_CINEMATICINDEX_HOP,WESTRING_CINEMATICTYPE_HOP\nCinematicIndexHED=0,cinematicindex,bj_CINEMATICINDEX_HED,WESTRING_CINEMATICTYPE_HED\nCinematicIndexUED=0,cinematicindex,bj_CINEMATICINDEX_UED,WESTRING_CINEMATICTYPE_UED\nCinematicIndexOED=0,cinematicindex,bj_CINEMATICINDEX_OED,WESTRING_CINEMATICTYPE_OED\nCinematicIndexNED=0,cinematicindex,bj_CINEMATICINDEX_NED,WESTRING_CINEMATICTYPE_NED\nCinematicIndexXOP=1,cinematicindex,bj_CINEMATICINDEX_XOP,WESTRING_CINEMATICTYPE_XOP\nCinematicIndexXED=1,cinematicindex,bj_CINEMATICINDEX_XED,WESTRING_CINEMATICTYPE_XED\n\n// Trigger Unit-Targeted Unit Orders\nydl_trigger=0,trigger,ydl_trigger,最后注册的逆天触发器\n\n// Common\nUnitOrderAttackUnitnull=0,unitorderutarg,null,无\nUnitOrderAttackUnit=0,unitorderutarg,`attack`,WESTRING_UNITORDERUTARG_ATTACK\nUnitOrderAttackUnitOnce=0,unitorderutarg,`attackonce`,WESTRING_UNITORDERUTARG_ATTACKONCE\nUnitOrderMoveUnit=0,unitorderutarg,`move`,WESTRING_UNITORDERUTARG_MOVE\nUnitOrderAIMoveUnit=0,unitorderutarg,`AImove`,AImove [R]\nUnitOrderSmartUnit=1,unitorderutarg,`smart`,WESTRING_UNITORDERUTARG_SMART\nUnitOrderSetRallyUnit=0,unitorderutarg,`setrally`,WESTRING_UNITORDERPTARG_SETRALLY\nUnitOrderPatrolUnit=0,unitorderutarg,`patrol`,WESTRING_UNITORDERPTARG_PATROL\nUnitOrderHarvest=0,unitorderutarg,`harvest`,WESTRING_UNITORDERUTARG_HARVEST\nUnitOrderRevive=0,unitorderutarg,`revive`,WESTRING_UNITORDERUTARG_REVIVE\nUnitOrderLoad=0,unitorderutarg,`load`,WESTRING_UNITORDERUTARG_LOAD\nUnitOrderUnload=0,unitorderutarg,`unload`,WESTRING_UNITORDERUTARG_UNLOAD\nUnitOrderBoard=0,unitorderutarg,`board`,WESTRING_UNITORDERUTARG_BOARD\nUnitOrderForceBoard=0,unitorderutarg,`forceboard`,WESTRING_UNITORDERUTARG_FORCEBOARD\n// Human\nUnitOrderRepair=0,unitorderutarg,`repair`,WESTRING_UNITORDERUTARG_REPAIR\nUnitOrderInnerFire=0,unitorderutarg,`innerfire`,WESTRING_UNITORDERUTARG_INNERFIRE\nUnitOrderDispel=0,unitorderutarg,`dispel`,WESTRING_UNITORDERUTARG_DISPEL\nUnitOrderHeal=0,unitorderutarg,`heal`,WESTRING_UNITORDERUTARG_HEAL\nUnitOrderSlow=0,unitorderutarg,`slow`,WESTRING_UNITORDERUTARG_SLOW\nUnitOrderInvisibility=0,unitorderutarg,`invisibility`,WESTRING_UNITORDERUTARG_INVISIBILITY\nUnitOrderPolymorph=0,unitorderutarg,`polymorph`,WESTRING_UNITORDERUTARG_POLYMORPH\nUnitOrderControlMagic=1,unitorderutarg,`controlmagic`,WESTRING_UNITORDERUTARG_CONTROLMAGIC\nUnitOrderSpellSteal=1,unitorderutarg,`spellsteal`,WESTRING_UNITORDERUTARG_SPELLSTEAL\nUnitOrderAerialShackles=1,unitorderutarg,`magicleash`,WESTRING_UNITORDERUTARG_AERIALSHACKLES\nUnitOrderMassTeleport=0,unitorderutarg,`massteleport`,WESTRING_UNITORDERUTARG_MASSTELEPORT\nUnitOrderBanish=1,unitorderutarg,`banish`,WESTRING_UNITORDERUTARG_BANISH\nUnitOrderSiphonMana=1,unitorderutarg,`drain`,WESTRING_UNITORDERUTARG_SIPHONMANA\nUnitOrderThunderBolt=0,unitorderutarg,`thunderbolt`,WESTRING_UNITORDERUTARG_THUNDERBOLT\nUnitOrderHolyBolt=0,unitorderutarg,`holybolt`,WESTRING_UNITORDERUTARG_HOLYBOLT\n// Orc\nUnitOrderRepairO=0,unitorderutarg,`repair`,WESTRING_UNITORDERUTARG_REPAIRO\nUnitOrderEnsnare=0,unitorderutarg,`ensnare`,WESTRING_UNITORDERUTARG_ENSNARE\nUnitOrderUnstableConcoction=1,unitorderutarg,`unstableconcoction`,WESTRING_UNITORDERUTARG_UNSTABLECONCOCTION\nUnitOrderPurge=0,unitorderutarg,`purge`,WESTRING_UNITORDERUTARG_PURGE\nUnitOrderLightningShield=0,unitorderutarg,`lightningshield`,WESTRING_UNITORDERUTARG_LIGHTNINGSHIELD\nUnitOrderBloodlust=0,unitorderutarg,`bloodlust`,WESTRING_UNITORDERUTARG_BLOODLUST\nUnitOrderSpiritLink=1,unitorderutarg,`spiritlink`,WESTRING_UNITORDERUTARG_SPIRITLINK\nUnitOrderAncestralSpiritTarg=1,unitorderutarg,`ancestralspirittarg`,兽族灵魂行者 - 先祖幽灵(无效)\nUnitOrderDevour=0,unitorderutarg,`devour`,WESTRING_UNITORDERUTARG_DEVOUR\nUnitOrderChainLightning=0,unitorderutarg,`chainlightning`,WESTRING_UNITORDERUTARG_CHAINLIGHTNING\nUnitOrderHealingWave=1,unitorderutarg,`healingwave`,WESTRING_UNITORDERUTARG_HEALINGWAVE\nUnitOrderHex=1,unitorderutarg,`hex`,WESTRING_UNITORDERUTARG_HEX\n\n// Night Elf\nUnitOrderRenew=0,unitorderutarg,`renew`,WESTRING_UNITORDERUTARG_RENEW\nUnitOrderEntangle=0,unitorderutarg,`entangle`,WESTRING_UNITORDERUTARG_ENTANGLE\nUnitOrderEntangleInstant=0,unitorderutarg,`entangleinstant`,WESTRING_UNITORDERUTARG_ENTANGLEINSTANT\nUnitOrderReplenish=0,unitorderutarg,`recharge`,WESTRING_UNITORDERUTARG_REPLENISH\nUnitOrderMountHippogryph=0,unitorderutarg,`mounthippogryph`,WESTRING_UNITORDERUTARG_MOUNTHIPPOGRYPH\nUnitOrderLoadArcher=0,unitorderutarg,`coupletarget`,WESTRING_UNITORDERUTARG_LOADARCHER\nUnitOrderAutoDispel=0,unitorderutarg,`autodispel`,WESTRING_UNITORDERUTARG_AUTODISPEL\nUnitOrderFaerieFire=0,unitorderutarg,`faeriefire`,WESTRING_UNITORDERUTARG_FAERIEFIRE\nUnitOrderCyclone=0,unitorderutarg,`cyclone`,WESTRING_UNITORDERUTARG_CYCLONE\nUnitOrderRejuvination=0,unitorderutarg,`rejuvination`,WESTRING_UNITORDERUTARG_REJUVINATION\nUnitOrderVengeance=1,unitorderutarg,`vengeance`,WESTRING_UNITORDERUTARG_VENGEANCE\nUnitOrderManaBurn=0,unitorderutarg,`manaburn`,WESTRING_UNITORDERUTARG_MANABURN\nUnitOrderEntanglingRoots=0,unitorderutarg,`entanglingroots`,WESTRING_UNITORDERUTARG_ENTANGLINGROOTS\nUnitOrderShadowStrike=1,unitorderutarg,`shadowstrike`,WESTRING_UNITORDERUTARG_SHADOWSTRIKE\n// Undead\nUnitOrderRestoration=0,unitorderutarg,`restoration`,WESTRING_UNITORDERUTARG_RESTORE\nUnitOrderSacrificeAcolyte=0,unitorderutarg,`sacrifice`,WESTRING_UNITORDERUTARG_SACRIFICEACOLYTE\nUnitOrderSacrifice=0,unitorderutarg,`requestsacrifice`,WESTRING_UNITORDERUTARG_SACRIFICE\nUnitOrderUnsummon=0,unitorderutarg,`unsummon`,WESTRING_UNITORDERUTARG_UNSUMMON\nUnitOrderWeb=0,unitorderutarg,`web`,WESTRING_UNITORDERUTARG_WEB\nUnitOrderRaiseDead=0,unitorderutarg,`raisedead`,WESTRING_UNITORDERUTARG_RAISEDEAD\nUnitOrderUnholyFrenzy=0,unitorderutarg,`unholyfrenzy`,WESTRING_UNITORDERUTARG_UNHOLYFRENZY\nUnitOrderCripple=0,unitorderutarg,`cripple`,WESTRING_UNITORDERUTARG_CRIPPLE\nUnitOrderCurse=0,unitorderutarg,`curse`,WESTRING_UNITORDERUTARG_CURSE\nUnitOrderAntiMagicShell=0,unitorderutarg,`antimagicshell`,WESTRING_UNITORDERUTARG_ANTIMAGICSHELL\nUnitOrderPossession=0,unitorderutarg,`possession`,WESTRING_UNITORDERUTARG_POSSESSION\nUnitOrderAbsorbMana=1,unitorderutarg,`absorb`,WESTRING_UNITORDERUTARG_ABSORBMANA\nUnitOrderFlamingAttack=1,unitorderutarg,`flamingattacktarg`,WESTRING_UNITORDERUTARG_FLAMINGATTACK\nUnitOrderImpale=1,unitorderutarg,`impale`,WESTRING_UNITORDERUTARG_IMPALE\nUnitOrderCarrionScarabs=1,unitorderutarg,`carrionscarabs`,WESTRING_UNITORDERUTARG_CARRIONSCARABS\nUnitOrderDeathCoil=0,unitorderutarg,`deathcoil`,WESTRING_UNITORDERUTARG_DEATHCOIL\nUnitOrderDeathPact=0,unitorderutarg,`deathpact`,WESTRING_UNITORDERUTARG_DEATHPACT\nUnitOrderSleep=0,unitorderutarg,`sleep`,WESTRING_UNITORDERUTARG_SLEEP\nUnitOrderFrostNova=0,unitorderutarg,`frostnova`,WESTRING_UNITORDERUTARG_FROSTNOVA\nUnitOrderFrostArmor=0,unitorderutarg,`frostarmor`,WESTRING_UNITORDERUTARG_FROSTARMOR\nUnitOrderDarkRitual=0,unitorderutarg,`darkritual`,WESTRING_UNITORDERUTARG_DARKRITUAL\n// Neutral\nUnitTargetOrderBreathOfFrost=1,unitorderutarg,`breathoffrost`,中立 - 霜冻吐息 [R]\nUnitOrderCreepDevour=1,unitorderutarg,`creepdevour`,WESTRING_UNITORDERUTARG_CREEPDEVOUR\nUnitOrderFirebolt=0,unitorderutarg,`firebolt`,WESTRING_UNITORDERUTARG_FIREBOLT\nUnitOrderCreepHeal=0,unitorderutarg,`creepheal`,WESTRING_UNITORDERUTARG_CREEPHEAL\nUnitOrderCreepThunderBolt=0,unitorderutarg,`creepthunderbolt`,WESTRING_UNITORDERUTARG_CREEPTHUNDERBOLT\nUnitOrderParasite=1,unitorderutarg,`parasite`,WESTRING_UNITORDERUTARG_PARASITE\nUnitOrderSelfDestructUnit=1,unitorderutarg,`selfdestruct`,WESTRING_UNITORDERUTARG_SELFDESTRUCT\nUnitOrderBlackArrow=1,unitorderutarg,`blackarrow`,WESTRING_UNITORDERUTARG_BLACKARROW\nUnitOrderCharm=1,unitorderutarg,`charm`,WESTRING_UNITORDERUTARG_CHARM\nUnitOrderLifeDrain=1,unitorderutarg,`drain`,WESTRING_UNITORDERUTARG_LIFEDRAIN\nUnitOrderColdArrow=1,unitorderutarg,`coldarrowstarg`,WESTRING_UNITORDERUTARG_COLDARROW\nUnitOrderForkedLightning=1,unitorderutarg,`forkedlightning`,WESTRING_UNITORDERUTARG_FORKEDLIGHTNING\nUnitOrderStrongDrink=1,unitorderutarg,`drunkenhaze`,WESTRING_UNITORDERUTARG_STRONGDRINK\nUnitOrderDoom=1,unitorderutarg,`doom`,WESTRING_UNITORDERUTARG_DOOM\nUnitOrderAcidBomb=1,unitorderutarg,`acidbomb`,WESTRING_UNITORDERUTARG_ACIDBOMB\nUnitOrderTransmute=1,unitorderutarg,`transmute`,WESTRING_UNITORDERUTARG_TRANSMUTE\nUnitOrderSoulBurn=1,unitorderutarg,`soulburn`,WESTRING_UNITORDERUTARG_SOULBURN\nUnitOrderPoisonArrow=0,unitorderutarg,`poisonarrowstarg`,WESTRING_UNITORDERUTARG_POISONARROW\nUnitOrderIncinerateArrow=1,unitorderutarg,`incineratearrow`,WESTRING_UNITORDERUTARG_INCINERATEARROW\n// Special\nUnitOrderFingerOfDeath=0,unitorderutarg,`fingerofdeath`,WESTRING_UNITORDERUTARG_FINGEROFDEATH\nUnitOrderDarkConversion=0,unitorderutarg,`darkconversion`,WESTRING_UNITORDERUTARG_DARKCONVERSION\nUnitOrderSoulPreservation=0,unitorderutarg,`soulpreservation`,WESTRING_UNITORDERUTARG_SOULPRESERVATION\nUnitOrderDarkConversionFast=0,unitorderutarg,`darkconversion`,WESTRING_UNITORDERUTARG_DARKCONVERSIONFAST\nUnitOrderNeutralInterAct=0,unitorderutarg,`neutralinteract`,中立商店 - 选择单位 [R]\n\n// Trigger Point-Targeted Unit Orders\n// Common\nUnitOrderAttacknull=0,unitorderptarg,null,无\nUnitOrderAttack=0,unitorderptarg,`attack`,WESTRING_UNITORDERPTARG_ATTACK\nUnitOrderAttackGround=0,unitorderptarg,`attackground`,WESTRING_UNITORDERPTARG_ATTACKGROUND\nUnitOrderMove=0,unitorderptarg,`move`,WESTRING_UNITORDERPTARG_MOVE\nUnitOrderAIMove=0,unitorderptarg,`AImove`,AImove [R]\nUnitOrderPatrol=0,unitorderptarg,`patrol`,WESTRING_UNITORDERPTARG_PATROL\nUnitOrderSmartPoint=1,unitorderptarg,`smart`,WESTRING_UNITORDERPTARG_SMART\nUnitOrderSetRally=0,unitorderptarg,`setrally`,WESTRING_UNITORDERPTARG_SETRALLY\nUnitOrderUnloadAll=0,unitorderptarg,`unloadall`,WESTRING_UNITORDERPTARG_UNLOADALL\n// Human\nUnitOrderFlare=0,unitorderptarg,`flare`,WESTRING_UNITORDERPTARG_FLARE\nUnitOrderCloudOfFog=1,unitorderptarg,`cloudoffog`,WESTRING_UNITORDERPTARG_CLOUDOFFOG\nUnitOrderBlizzard=0,unitorderptarg,`blizzard`,WESTRING_UNITORDERPTARG_BLIZZARD\nUnitOrderFlameStrike=1,unitorderptarg,`flamestrike`,WESTRING_UNITORDERPTARG_FLAMESTRIKE\n// Orc\nUnitOrderSentryWard=0,unitorderptarg,`evileye`,WESTRING_UNITORDERPTARG_SENTRYWARD\nUnitOrderStasisTrap=0,unitorderptarg,`stasistrap`,WESTRING_UNITORDERPTARG_STASISTRAP\nUnitOrderHealingWard=0,unitorderptarg,`healingward`,WESTRING_UNITORDERPTARG_HEALINGWARD\nUnitOrderDisenchant=1,unitorderptarg,`disenchant`,WESTRING_UNITORDERPTARG_DISENCHANT\nUnitOrderFarSight=0,unitorderptarg,`farsight`,WESTRING_UNITORDERPTARG_FARSIGHT\nUnitOrderEarthquake=0,unitorderptarg,`earthquake`,WESTRING_UNITORDERPTARG_EARTHQUAKE\nUnitOrderSerpentWard=1,unitorderptarg,`ward`,WESTRING_UNITORDERPTARG_SERPENTWARD\nUnitOrderShockwave=0,unitorderptarg,`shockwave`,WESTRING_UNITORDERPTARG_SHOCKWAVE\n// Night Elf\nUnitOrderRoot=0,unitorderptarg,`root`,WESTRING_UNITORDERPTARG_ROOT\nUnitOrderDetonate=0,unitorderptarg,`detonate`,WESTRING_UNITORDERPTARG_DETONATE\nUnitOrderForceOfNature=0,unitorderptarg,`forceofnature`,WESTRING_UNITORDERPTARG_FORCEOFNATURE\nUnitOrderStarfall=0,unitorderptarg,`obsolete`,WESTRING_UNITORDERPTARG_STARFALL\nUnitOrderBlink=1,unitorderptarg,`blink`,WESTRING_UNITORDERPTARG_BLINK\n// Undead\nUnitOrderDevourMagic=1,unitorderptarg,`devourmagic`,WESTRING_UNITORDERPTARG_DEVOURMAGIC\nUnitOrderImpalePoint=1,unitorderptarg,`impale`,WESTRING_UNITORDERPTARG_IMPALE\nUnitOrderCarrionSwarm=0,unitorderptarg,`carrionswarm`,WESTRING_UNITORDERPTARG_CARRIONSWARM\nUnitOrderDarkSummoning=0,unitorderptarg,`dreadlordinferno`,WESTRING_UNITORDERPTARG_DARKSUMMONING\nUnitOrderDeathAndDecay=0,unitorderptarg,`deathanddecay`,WESTRING_UNITORDERPTARG_DEATHANDDECAY\n// Neutral\nUnitOrderBreathOfFrost=1,unitorderptarg,`breathoffrost`,WESTRING_UNITORDERPTARG_BREATHOFFROST\nUnitOrderMonsoon=1,unitorderptarg,`monsoon`,WESTRING_UNITORDERPTARG_MONSOON\nUnitOrderSelfDestruct=0,unitorderptarg,`selfdestruct`,WESTRING_UNITORDERPTARG_SELFDESTRUCT\nUnitOrderInferno=0,unitorderptarg,`inferno`,WESTRING_UNITORDERPTARG_INFERNO\nUnitOrderStampede=1,unitorderptarg,`stampede`,WESTRING_UNITORDERPTARG_STAMPEDE\nUnitOrderSilence=1,unitorderptarg,`silence`,WESTRING_UNITORDERPTARG_SILENCE\nUnitOrderTornado=1,unitorderptarg,`tornado`,WESTRING_UNITORDERPTARG_TORNADO\nUnitOrderBreathOfFire=1,unitorderptarg,`breathoffire`,WESTRING_UNITORDERPTARG_BREATHOFFIRE\nUnitOrderHeroRainOfFire=1,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_HERORAINOFFIRE\nUnitOrderHealingSpray=1,unitorderptarg,`healingspray`,WESTRING_UNITORDERPTARG_HEALINGSPRAY\nUnitOrderClusterRockets=1,unitorderptarg,`clusterrockets`,WESTRING_UNITORDERPTARG_CLUSTERROCKETS\nUnitOrderSummonFactory=1,unitorderptarg,`summonfactory`,WESTRING_UNITORDERPTARG_SUMMONFACTORY\nUnitOrderVolcano=1,unitorderptarg,`volcano`,WESTRING_UNITORDERPTARG_VOLCANO\n// Special\nUnitOrderDarkPortal=0,unitorderptarg,`darkportal`,WESTRING_UNITORDERPTARG_DARKPORTAL\nUnitOrderRainOfChaos=0,unitorderptarg,`rainofchaos`,WESTRING_UNITORDERPTARG_RAINOFCHAOS\nUnitOrderRainOfFire=0,unitorderptarg,`rainoffire`,WESTRING_UNITORDERPTARG_RAINOFFIRE\nUnitOrderDarkSummoningOld=0,unitorderptarg,`darksummoning`,WESTRING_UNITORDERPTARG_DARKSUMMONINGOLD\nUnitOrderNeutralDetectAOE=0,unitorderptarg,`neutraldetectaoe`,地精实验室 - 侦查 [R]\n\n// Trigger Destructible-Targeted Unit Orders\n// Common\nUnitOrderAttackDestructible=0,unitorderdtarg,`attack`,WESTRING_UNITORDERDTARG_ATTACK\nUnitOrderAttackDestructibleOnce=0,unitorderdtarg,`attackonce`,WESTRING_UNITORDERUTARG_ATTACKONCE\nUnitOrderSmartDestructible=1,unitorderdtarg,`smart`,WESTRING_UNITORDERDTARG_SMART\nUnitOrderSetRallyDestructible=0,unitorderdtarg,`setrally`,WESTRING_UNITORDERPTARG_SETRALLY\nUnitOrderHarvestDestructible=0,unitorderdtarg,`harvest`,WESTRING_UNITORDERDTARG_HARVEST\nUnitOrderMoveDestructible=0,unitorderdtarg,`move`,WESTRING_UNITORDERPTARG_MOVE\nUnitOrderAIMoveDestructible=0,unitorderdtarg,`AImove`,AImove\n\n// Human\n// Orc\n// Night Elf\nUnitOrderConsumeTree=0,unitorderdtarg,`eattree`,WESTRING_UNITORDERDTARG_CONSUMETREE\nUnitOrderSentinel=0,unitorderdtarg,`sentinel`,WESTRING_UNITORDERDTARG_SENTINEL\nUnitOrderGrabTree=1,unitorderdtarg,`grabtree`,WESTRING_UNITORDERDTARG_GRABTREE\n// Undead\n// Neutral\n// Special\n\n// Trigger Item-Targeted Unit Orders\n// Common\nUnitOrderAttackItem=1,unitorderitarg,`attack`,WESTRING_UNITORDERITARG_ATTACK\nUnitOrderAttackItemOnce=1,unitorderitarg,`attackonce`,WESTRING_UNITORDERITARG_ATTACKONCE\nUnitOrderMoveItem=1,unitorderitarg,`move`,移动(无效)\nUnitOrderSmartItem=1,unitorderitarg,`smart`,WESTRING_UNITORDERITARG_SMART\nUnitOrderSetRallyItem=0,unitorderitarg,`setrally`,WESTRING_UNITORDERPTARG_SETRALLY\n\n// Trigger Immediate / Untargeted Unit Orders\n// Common\nUnitOrderStopnull=0,unitordernotarg,null,无\nUnitOrderStop=0,unitordernotarg,`stop`,WESTRING_UNITORDERNOTARG_STOP\nUnitOrderHoldPosition=0,unitordernotarg,`holdposition`,WESTRING_UNITORDERNOTARG_HOLDPOSITION\nUnitOrderAutoHarvestGold=0,unitordernotarg,`autoharvestgold`,WESTRING_UNITORDERNOTARG_AUTOHARVESTGOLD\nUnitOrderAutoHarvestLumber=0,unitordernotarg,`autoharvestlumber`,WESTRING_UNITORDERNOTARG_AUTOHARVESTLUMBER\nUnitOrderReturnResources=0,unitordernotarg,`returnresources`,WESTRING_UNITORDERNOTARG_RETURNRESOURCES\nUnitOrderBuild=1,unitordernotarg,`build`,WESTRING_UNITORDERNOTARG_BUILD\nUnitOrderLevelup=1,unitordernotarg,`levelup`,WESTRING_UNITORDERNOTARG_LEVELUP\n// Human\nUnitOrderHumanBuild=1,unitordernotarg,`humanbuild`,WESTRING_UNITORDERNOTARG_HUMANBUILD\nUnitOrderTownBellOn=0,unitordernotarg,`townbellon`,WESTRING_UNITORDERNOTARG_TOWNBELLON\nUnitOrderTownBellOff=0,unitordernotarg,`townbelloff`,WESTRING_UNITORDERNOTARG_TOWNBELLOFF\nUnitOrderMilitia=0,unitordernotarg,`militia`,WESTRING_UNITORDERNOTARG_MILITIA\nUnitOrderMilitiaOff=0,unitordernotarg,`militiaoff`,WESTRING_UNITORDERNOTARG_MILITIAOFF\nUnitOrderRepairOn=0,unitordernotarg,`repairon`,WESTRING_UNITORDERNOTARG_REPAIRON\nUnitOrderRepairOff=0,unitordernotarg,`repairoff`,WESTRING_UNITORDERNOTARG_REPAIROFF\nUnitOrderDefend=0,unitordernotarg,`defend`,WESTRING_UNITORDERNOTARG_DEFEND\nUnitOrderUnDefend=0,unitordernotarg,`undefend`,WESTRING_UNITORDERNOTARG_UNDEFEND\nUnitOrderHealOn=0,unitordernotarg,`healon`,WESTRING_UNITORDERNOTARG_HEALON\nUnitOrderHealOff=0,unitordernotarg,`healoff`,WESTRING_UNITORDERNOTARG_HEALOFF\nUnitOrderInnerFireOn=0,unitordernotarg,`innerfireon`,WESTRING_UNITORDERNOTARG_INNERFIREON\nUnitOrderInnerFireOff=0,unitordernotarg,`innerfireoff`,WESTRING_UNITORDERNOTARG_INNERFIREOFF\nUnitOrderSlowOn=0,unitordernotarg,`slowon`,WESTRING_UNITORDERNOTARG_SLOWON\nUnitOrderSlowOff=0,unitordernotarg,`slowoff`,WESTRING_UNITORDERNOTARG_SLOWOFF\nUnitOrderSpellStealOn=1,unitordernotarg,`spellstealon`,WESTRING_UNITORDERNOTARG_SPELLSTEALON\nUnitOrderSpellStealOff=1,unitordernotarg,`spellstealoff`,WESTRING_UNITORDERNOTARG_SPELLSTEALOFF\nUnitOrderMagicDefense=1,unitordernotarg,`magicdefense`,人族破法者 - 激活魔法防御 [R]\nUnitOrderMagicUnDefense=1,unitordernotarg,`magicundefense`,人族破法者 - 取消魔法防御 [R]\nUnitOrderWaterElemental=0,unitordernotarg,`waterelemental`,WESTRING_UNITORDERNOTARG_WATERELEMENTAL\nUnitOrderPhoenix=1,unitordernotarg,`summonphoenix`,WESTRING_UNITORDERNOTARG_PHOENIX\nUnitOrderThunderClap=0,unitordernotarg,`thunderclap`,WESTRING_UNITORDERNOTARG_THUNDERCLAP\nUnitOrderAvatar=0,unitordernotarg,`avatar`,WESTRING_UNITORDERNOTARG_AVATAR\nUnitOrderDivineShield=0,unitordernotarg,`divineshield`,WESTRING_UNITORDERNOTARG_DIVINESHIELD\nUnitOrderUnDivineShield=0,unitordernotarg,`undivineshield`,WESTRING_UNITORDERNOTARG_UNDIVINESHIELD\nUnitOrderResurrection=0,unitordernotarg,`resurrection`,WESTRING_UNITORDERNOTARG_RESURRECTION\n// Orc\nUnitOrderOrcBuild=1,unitordernotarg,`orcbuild`,WESTRING_UNITORDERNOTARG_ORCBUILD\nUnitOrderBattleStations=0,unitordernotarg,`battlestations`,WESTRING_UNITORDERNOTARG_BATTLESTATIONS\nUnitOrderStandDown=0,unitordernotarg,`standdown`,WESTRING_UNITORDERNOTARG_STANDDOWN\nUnitOrderRepairOOn=0,unitordernotarg,`repairon`,WESTRING_UNITORDERNOTARG_REPAIROON\nUnitOrderRepairOOff=0,unitordernotarg,`repairoff`,WESTRING_UNITORDERNOTARG_REPAIROOFF\nUnitOrderBerserk=1,unitordernotarg,`berserk`,WESTRING_UNITORDERNOTARG_BERSERK\nUnitOrderBloodlustOn=0,unitordernotarg,`bloodluston`,WESTRING_UNITORDERNOTARG_BLOODLUSTON\nUnitOrderBloodlustOff=0,unitordernotarg,`bloodlustoff`,WESTRING_UNITORDERNOTARG_BLOODLUSTOFF\nUnitOrderAncestralSpirit=1,unitordernotarg,`ancestralspirit`,WESTRING_UNITORDERNOTARG_ANCESTRALSPIRIT\nUnitOrderEtherealForm=1,unitordernotarg,`uncorporealform`,WESTRING_UNITORDERNOTARG_ETHEREALFORM\nUnitOrderCorporealForm=1,unitordernotarg,`corporealform`,WESTRING_UNITORDERNOTARG_CORPOREALFORM\nUnitOrderWindWalk=0,unitordernotarg,`windwalk`,WESTRING_UNITORDERNOTARG_WINDWALK\nUnitOrderMirrorImage=0,unitordernotarg,`mirrorimage`,WESTRING_UNITORDERNOTARG_MIRRORIMAGE\nUnitOrderWhirlWind=0,unitordernotarg,`whirlwind`,WESTRING_UNITORDERNOTARG_BLADESTORM\nUnitOrderSpiritWolf=0,unitordernotarg,`spiritwolf`,WESTRING_UNITORDERNOTARG_FERALSPIRIT\nUnitOrderVoodoo=1,unitordernotarg,`voodoo`,WESTRING_UNITORDERNOTARG_VOODOO\nUnitOrderStomp=0,unitordernotarg,`stomp`,WESTRING_UNITORDERNOTARG_WARSTOMP\n// Night Elf\nUnitOrderNightElfBuild=1,unitordernotarg,`nightelfbuild`,WESTRING_UNITORDERNOTARG_NIGHTELFBUILD\nUnitOrderUnRoot=0,unitordernotarg,`unroot`,WESTRING_UNITORDERNOTARG_UNROOT\nUnitOrderAutoEntangle=1,unitordernotarg,`autoentangle`,WESTRING_UNITORDERNOTARG_AUTOENTANGLE\nUnitOrderAutoEntangleInstant=1,unitordernotarg,`autoentangleinstant`,WESTRING_UNITORDERNOTARG_AUTOENTANGLEINSTANT\nUnitOrderReplenishOn=1,unitordernotarg,`rechargeon`,WESTRING_UNITORDERNOTARG_REPLENISHON\nUnitOrderReplenishOff=1,unitordernotarg,`rechargeoff`,WESTRING_UNITORDERNOTARG_REPLENISHOFF\nUnitOrderAmbush=0,unitordernotarg,`ambush`,WESTRING_UNITORDERNOTARG_HIDE\nUnitOrderRenewOn=0,unitordernotarg,`renewon`,WESTRING_UNITORDERNOTARG_RENEWON\nUnitOrderRenewOff=0,unitordernotarg,`renewoff`,WESTRING_UNITORDERNOTARG_RENEWOFF\nUnitOrderCoupleInstant1=1,unitordernotarg,`coupleinstant`,WESTRING_UNITORDERNOTARG_COUPLEINSTANT1\nUnitOrderCoupleInstant2=1,unitordernotarg,`coupleinstant`,WESTRING_UNITORDERNOTARG_COUPLEINSTANT2\nUnitOrderDecouple=1,unitordernotarg,`decouple`,WESTRING_UNITORDERNOTARG_DECOUPLE\nUnitOrderAutoDispelOn=0,unitordernotarg,`autodispelon`,WESTRING_UNITORDERNOTARG_AUTODISPELON\nUnitOrderAutoDispelOff=0,unitordernotarg,`autodispeloff`,WESTRING_UNITORDERNOTARG_AUTODISPELOFF\nUnitOrderFaerieFireOn=0,unitordernotarg,`faeriefireon`,WESTRING_UNITORDERNOTARG_FAERIEFIREON\nUnitOrderFaerieFireOff=0,unitordernotarg,`faeriefireoff`,WESTRING_UNITORDERNOTARG_FAERIEFIREOFF\nUnitOrderRavenForm=0,unitordernotarg,`ravenform`,WESTRING_UNITORDERNOTARG_RAVENFORM\nUnitOrderUnRavenForm=0,unitordernotarg,`unravenform`,WESTRING_UNITORDERNOTARG_UNRAVENFORM\nUnitOrderRoar=0,unitordernotarg,`roar`,WESTRING_UNITORDERNOTARG_ROAR\nUnitOrderBearForm=0,unitordernotarg,`bearform`,WESTRING_UNITORDERNOTARG_BEARFORM\nUnitOrderUnBearForm=0,unitordernotarg,`unbearform`,WESTRING_UNITORDERNOTARG_UNBEARFORM\nUnitOrderTaunt=1,unitordernotarg,`taunt`,WESTRING_UNITORDERNOTARG_TAUNT\nUnitOrderManaFlareOn=1,unitordernotarg,`manaflareon`,WESTRING_UNITORDERNOTARG_MANAFLAREON\nUnitOrderManaFlareOff=1,unitordernotarg,`manaflareoff`,WESTRING_UNITORDERNOTARG_MANAFLAREOFF\nUnitOrderPhaseShift=1,unitordernotarg,`phaseshift`,WESTRING_UNITORDERNOTARG_PHASESHIFT\nUnitOrderPhaseShiftOn=1,unitordernotarg,`phaseshifton`,WESTRING_UNITORDERNOTARG_PHASESHIFTON\nUnitOrderPhaseShiftOff=1,unitordernotarg,`phaseshiftoff`,WESTRING_UNITORDERNOTARG_PHASESHIFTOFF\nUnitOrderVengeanceInstant=1,unitordernotarg,`vengeanceinstant`,WESTRING_UNITORDERNOTARG_VENGEANCEINSTANT\nUnitOrderVengeanceOn=1,unitordernotarg,`vengeanceon`,WESTRING_UNITORDERNOTARG_VENGEANCEON\nUnitOrderVengeanceOff=1,unitordernotarg,`vengeanceoff`,WESTRING_UNITORDERNOTARG_VENGEANCEOFF\nUnitOrderImmolation=0,unitordernotarg,`immolation`,WESTRING_UNITORDERNOTARG_IMMOLATION\nUnitOrderUnImmolation=0,unitordernotarg,`unimmolation`,WESTRING_UNITORDERNOTARG_UNIMMOLATION\nUnitOrderMetamorphosis=0,unitordernotarg,`metamorphosis`,WESTRING_UNITORDERNOTARG_METAMORPHOSIS\nUnitOrderTranquility=0,unitordernotarg,`tranquility`,WESTRING_UNITORDERNOTARG_TRANQUILITY\nUnitOrderSearingArrows=0,unitordernotarg,`flamingarrows`,WESTRING_UNITORDERNOTARG_SEARINGARROWS\nUnitOrderUnSearingArrows=0,unitordernotarg,`unflamingarrows`,WESTRING_UNITORDERNOTARG_UNSEARINGARROWS\nUnitOrderScout=0,unitordernotarg,`scout`,WESTRING_UNITORDERNOTARG_SCOUT\nUnitOrderStarfall2=0,unitordernotarg,`starfall`,WESTRING_UNITORDERNOTARG_STARFALL\nUnitOrderFanOfKnives=1,unitordernotarg,`fanofknives`,WESTRING_UNITORDERNOTARG_FANOFKNIVES\nUnitOrderSpiritOfVengeance=1,unitordernotarg,`spiritofvengeance`,WESTRING_UNITORDERNOTARG_SPIRITOFVENGEANCE\n// Undead\nUnitOrderUndeadBuild=1,unitordernotarg,`undeadbuild`,WESTRING_UNITORDERNOTARG_UNDEADBUILD\nUnitOrderRestorationOn=0,unitordernotarg,`restorationon`,WESTRING_UNITORDERNOTARG_RESTOREON\nUnitOrderRestorationOff=0,unitordernotarg,`restorationoff`,WESTRING_UNITORDERNOTARG_RESTOREOFF\nUnitOrderCannibalize=0,unitordernotarg,`cannibalize`,WESTRING_UNITORDERNOTARG_CANNIBALIZE\nUnitOrderWebOn=0,unitordernotarg,`webon`,WESTRING_UNITORDERNOTARG_WEBON\nUnitOrderWebOff=0,unitordernotarg,`weboff`,WESTRING_UNITORDERNOTARG_WEBOFF\nUnitOrderBurrow=1,unitordernotarg,`burrow`,WESTRING_UNITORDERNOTARG_BURROW\nUnitOrderUnBurrow=1,unitordernotarg,`unburrow`,WESTRING_UNITORDERNOTARG_UNBURROW\nUnitOrderLoadCorpse=0,unitordernotarg,`loadcorpse`,WESTRING_UNITORDERNOTARG_LOADCORPSE\nUnitOrderUnloadAllCorpses=0,unitordernotarg,`unloadallcorpses`,WESTRING_UNITORDERNOTARG_UNLOADALLCORPSES\nUnitOrderStoneForm=0,unitordernotarg,`stoneform`,WESTRING_UNITORDERNOTARG_STONEFORM\nUnitOrderUnStoneForm=0,unitordernotarg,`unstoneform`,WESTRING_UNITORDERNOTARG_UNSTONEFORM\nUnitOrderRaiseDeadInstant=1,unitordernotarg,`instant`,WESTRING_UNITORDERNOTARG_RAISEDEAD\nUnitOrderRaiseDeadOn=0,unitordernotarg,`raisedeadon`,WESTRING_UNITORDERNOTARG_RAISEDEADON\nUnitOrderRaiseDeadOff=0,unitordernotarg,`raisedeadoff`,WESTRING_UNITORDERNOTARG_RAISEDEADOFF\nUnitOrderCurseOn=0,unitordernotarg,`curseon`,WESTRING_UNITORDERNOTARG_CURSEON\nUnitOrderCurseOff=0,unitordernotarg,`curseoff`,WESTRING_UNITORDERNOTARG_CURSEOFF\nUnitOrderFlamingAttackOn=1,unitordernotarg,`flamingattack`,WESTRING_UNITORDERNOTARG_FLAMINGATTACKON\nUnitOrderFlamingAttackOff=1,unitordernotarg,`unflamingattack`,WESTRING_UNITORDERNOTARG_FLAMINGATTACKOFF\nUnitOrderSphinxForm=1,unitordernotarg,`avengerform`,WESTRING_UNITORDERNOTARG_SPHINXFORM\nUnitOrderReplenishLife=1,unitordernotarg,`replenishlife`,WESTRING_UNITORDERNOTARG_REPLENISHLIFE\nUnitOrderReplenishLifeOn=1,unitordernotarg,`replenishlifeon`,WESTRING_UNITORDERNOTARG_REPLENISHLIFEON\nUnitOrderReplenishLifeOff=1,unitordernotarg,`replenishlifeoff`,WESTRING_UNITORDERNOTARG_REPLENISHLIFEOFF\nUnitOrderReplenishMana=1,unitordernotarg,`replenishmana`,WESTRING_UNITORDERNOTARG_REPLENISHMANA\nUnitOrderReplenishManaOn=1,unitordernotarg,`replenishmanaon`,WESTRING_UNITORDERNOTARG_REPLENISHMANAON\nUnitOrderReplenishManaOff=1,unitordernotarg,`replenishmanaoff`,WESTRING_UNITORDERNOTARG_REPLENISHMANAOFF\nUnitOrderCarrionScarabsInstant=1,unitordernotarg,`carrionscarabsinstant`,\"不死族地穴领主 - 召唤腐尸甲虫 [R]\"\nUnitOrderCarrionScarabsOn=1,unitordernotarg,`carrionscarabson`,WESTRING_UNITORDERNOTARG_CARRIONSCARABSON\nUnitOrderCarrionScarabsOff=1,unitordernotarg,`carrionscarabsoff`,WESTRING_UNITORDERNOTARG_CARRIONSCARABSOFF\nUnitOrderCarrionScarabsInstant=1,unitordernotarg,`carrionscarabsinstant`,WESTRING_UNITORDERNOTARG_CARRIONSCARABS\nUnitOrderLocustSwarm=1,unitordernotarg,`locustswarm`,WESTRING_UNITORDERNOTARG_LOCUSTSWARM\nUnitOrderAnimateDead=0,unitordernotarg,`animatedead`,WESTRING_UNITORDERNOTARG_ANIMATEDEAD\nUnitOrderFrostArmorOn=0,unitordernotarg,`frostarmoron`,WESTRING_UNITORDERNOTARG_FROSTARMORON\nUnitOrderFrostArmorOff=0,unitordernotarg,`frostarmoroff`,WESTRING_UNITORDERNOTARG_FROSTARMOROFF\n// Neutral\nUnitOrderNagaBuild=1,unitordernotarg,`nagabuild`,WESTRING_UNITORDERNOTARG_NAGABUILD\nUnitOrderSubmerge=1,unitordernotarg,`submerge`,娜迦 - 潜水 [R]\nUnitOrderUnSubmerge=1,unitordernotarg,`unsubmerge`,娜迦 - 取消潜水 [R]\nUnitOrderParasiteOn=1,unitordernotarg,`parasiteon`,娜迦海妖 - 激活寄生虫 [R]\nUnitOrderParasiteOff=1,unitordernotarg,`parasiteoff`,娜迦海妖 - 取消寄生虫 [R]\nUnitOrderCreepAnimateDead=0,unitordernotarg,`creepanimatedead`,WESTRING_UNITORDERNOTARG_CREEPANIMATEDEAD\nUnitOrderCreepHealOn=0,unitordernotarg,`creephealon`,WESTRING_UNITORDERNOTARG_CREEPHEALON\nUnitOrderCreepHealOff=0,unitordernotarg,`creephealoff`,WESTRING_UNITORDERNOTARG_CREEPHEALOFF\nUnitOrderRevenge=0,unitordernotarg,`revenge`,WESTRING_UNITORDERNOTARG_REVENGE\nUnitOrderCreepThunderClap=0,unitordernotarg,`creepthunderclap`,WESTRING_UNITORDERNOTARG_CREEPTHUNDERCLAP\nUnitOrderWateryMinion=1,unitordernotarg,`wateryminion`,WESTRING_UNITORDERNOTARG_WATERYMINION\nUnitOrderSelfDestructOn=1,unitordernotarg,`selfdestructon`,WESTRING_UNITORDERNOTARG_SELFDESTRUCTON\nUnitOrderSelfDestructOff=1,unitordernotarg,`selfdestructoff`,WESTRING_UNITORDERNOTARG_SELFDESTRUCTOFF\nUnitOrderSummonGrizzly=1,unitordernotarg,`summongrizzly`,WESTRING_UNITORDERNOTARG_SUMMONGRIZZLY\nUnitOrderSummonQuillbeast=1,unitordernotarg,`summonquillbeast`,WESTRING_UNITORDERNOTARG_SUMMONQUILLBEAST\nUnitOrderSummonWarEagle=1,unitordernotarg,`summonwareagle`,WESTRING_UNITORDERNOTARG_SUMMONWAREAGLE\nUnitOrderBlackArrowOn=1,unitordernotarg,`blackarrowon`,WESTRING_UNITORDERNOTARG_BLACKARROWON\nUnitOrderBlackArrowOff=1,unitordernotarg,`blackarrowoff`,WESTRING_UNITORDERNOTARG_BLACKARROWOFF\nUnitOrderColdArrowOn=1,unitordernotarg,`coldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWON\nUnitOrderColdArrowOff=1,unitordernotarg,`uncoldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWOFF\nUnitOrderManaShieldOn=1,unitordernotarg,`manashieldon`,WESTRING_UNITORDERNOTARG_MANASHIELDON\nUnitOrderManaShieldOff=1,unitordernotarg,`manashieldoff`,WESTRING_UNITORDERNOTARG_MANASHIELDOFF\nUnitOrderElementalFury=1,unitordernotarg,`elementalfury`,WESTRING_UNITORDERNOTARG_ELEMENTALFURY\nUnitOrderHowlOfTerror=1,unitordernotarg,`howlofterror`,WESTRING_UNITORDERNOTARG_HOWLOFTERROR\nUnitOrderPoisonArrows=0,unitordernotarg,`poisonarrows`,WESTRING_UNITORDERNOTARG_POISONARROWON\nUnitOrderUnPoisonArrows=0,unitordernotarg,`unpoisonarrows`,WESTRING_UNITORDERNOTARG_POISONARROWOFF\nUnitOrderChemicalRage=1,unitordernotarg,`chemicalrage`,WESTRING_UNITORDERNOTARG_CHEMICALRAGE\nUnitOrderRoboGoblin=1,unitordernotarg,`robogoblin`,WESTRING_UNITORDERNOTARG_ROBOGOBLIN\nUnitOrderUnRoboGoblin=1,unitordernotarg,`unrobogoblin`,WESTRING_UNITORDERNOTARG_UNROBOGOBLIN\nUnitOrderLavaMonster=1,unitordernotarg,`lavamonster`,WESTRING_UNITORDERNOTARG_LAVAMONSTER\nUnitOrderIncinerateArrowOn=1,unitordernotarg,`incineratearrowon`,WESTRING_UNITORDERNOTARG_INCINERATEARROWON\nUnitOrderIncinerateArrowOff=1,unitordernotarg,`incineratearrowoff`,WESTRING_UNITORDERNOTARG_INCINERATEARROWOFF\n// Special\nUnitOrderChannel=1,unitordernotarg,`channel`,WESTRING_UNITORDERNOTARG_CHANNEL\nUnitOrderMedivhRavenForm=0,unitordernotarg,`ravenform`,WESTRING_UNITORDERNOTARG_MEDIVHRAVENFORM\nUnitOrderMedivhUnRavenForm=0,unitordernotarg,`unravenform`,WESTRING_UNITORDERNOTARG_MEDIVHUNRAVENFORM\nUnitOrderRexxarBattleRoar=1,unitordernotarg,`battleroar`,WESTRING_UNITORDERNOTARG_REXXARBATTLEROAR\nUnitOrderColdArrows=0,unitordernotarg,`coldarrows`,WESTRING_UNITORDERNOTARG_COLDARROWS\nUnitOrderUnColdArrows=0,unitordernotarg,`uncoldarrows`,WESTRING_UNITORDERNOTARG_UNCOLDARROWS\n\n// OrderCode\n\n// Trigger Unit-Targeted Target Orders\n// Common\nOrderCodeAttackUnit=0,ordercodeutarg,851983,WESTRING_UNITORDERUTARG_ATTACK\nOrderCodeAttackUnitOnce=0,ordercodeutarg,851985,WESTRING_UNITORDERUTARG_ATTACKONCE\nOrderCodeMoveUnit=0,ordercodeutarg,851986,WESTRING_UNITORDERUTARG_MOVE\nOrderCodeAIMoveUnit=0,ordercodeutarg,851988,AImove\nOrderCodeSmartUnit=1,ordercodeutarg,851971,WESTRING_UNITORDERUTARG_SMART\nOrderCodeSetRallyUnit=0,ordercodeutarg,851980,WESTRING_UNITORDERPTARG_SETRALLY\nOrderCodePatrolUnit=0,ordercodeutarg,851990,WESTRING_UNITORDERPTARG_PATROL\nOrderCodeHarvest=0,ordercodeutarg,852018,WESTRING_UNITORDERUTARG_HARVEST\nOrderCodeRevive=0,ordercodeutarg,852039,WESTRING_UNITORDERUTARG_REVIVE\nOrderCodeLoad=0,ordercodeutarg,852046,WESTRING_UNITORDERUTARG_LOAD\nOrderCodeUnload=0,ordercodeutarg,852047,WESTRING_UNITORDERUTARG_UNLOAD\nOrderCodeBoard=0,ordercodeutarg,852043,WESTRING_UNITORDERUTARG_BOARD\nOrderCodeForceBoard=0,ordercodeutarg,852044,WESTRING_UNITORDERUTARG_FORCEBOARD\n// Human\nOrderCodeRepair=0,ordercodeutarg,852024,WESTRING_UNITORDERUTARG_REPAIR\nOrderCodeInnerFire=0,ordercodeutarg,852066,WESTRING_UNITORDERUTARG_INNERFIRE\nOrderCodeDispel=0,ordercodeutarg,852057,WESTRING_UNITORDERUTARG_DISPEL\nOrderCodeHeal=0,ordercodeutarg,852063,WESTRING_UNITORDERUTARG_HEAL\nOrderCodeSlow=0,ordercodeutarg,852075,WESTRING_UNITORDERUTARG_SLOW\nOrderCodeInvisibility=0,ordercodeutarg,852069,WESTRING_UNITORDERUTARG_INVISIBILITY\nOrderCodePolymorph=0,ordercodeutarg,852074,WESTRING_UNITORDERUTARG_POLYMORPH\nOrderCodeControlMagic=1,ordercodeutarg,852474,WESTRING_UNITORDERUTARG_CONTROLMAGIC\nOrderCodeSpellSteal=1,ordercodeutarg,852483,WESTRING_UNITORDERUTARG_SPELLSTEAL\nOrderCodeAerialShackles=1,ordercodeutarg,852480,WESTRING_UNITORDERUTARG_AERIALSHACKLES\nOrderCodeMassTeleport=0,ordercodeutarg,852093,WESTRING_UNITORDERUTARG_MASSTELEPORT\nOrderCodeBanish=1,ordercodeutarg,852486,WESTRING_UNITORDERUTARG_BANISH\nOrderCodeSiphonMana=1,ordercodeutarg,852487,WESTRING_UNITORDERUTARG_SIPHONMANA\nOrderCodeThunderBolt=0,ordercodeutarg,852095,WESTRING_UNITORDERUTARG_THUNDERBOLT\nOrderCodeHolyBolt=0,ordercodeutarg,852092,WESTRING_UNITORDERUTARG_HOLYBOLT\n// Orc\nOrderCodeRepairO=0,ordercodeutarg,852024,WESTRING_UNITORDERUTARG_REPAIRO\nOrderCodeEnsnare=0,ordercodeutarg,852106,WESTRING_UNITORDERUTARG_ENSNARE\nOrderCodeUnstableConcoction=1,ordercodeutarg,852500,WESTRING_UNITORDERUTARG_UNSTABLECONCOCTION\nOrderCodePurge=0,ordercodeutarg,852111,WESTRING_UNITORDERUTARG_PURGE\nOrderCodeLightningShield=0,ordercodeutarg,852110,WESTRING_UNITORDERUTARG_LIGHTNINGSHIELD\nOrderCodeBloodlust=0,ordercodeutarg,852101,WESTRING_UNITORDERUTARG_BLOODLUST\nOrderCodeSpiritLink=1,ordercodeutarg,854299,WESTRING_UNITORDERUTARG_SPIRITLINK\nOrderCodeDevour=0,ordercodeutarg,852104,WESTRING_UNITORDERUTARG_DEVOUR\nOrderCodeChainLightning=0,ordercodeutarg,852119,WESTRING_UNITORDERUTARG_CHAINLIGHTNING\nOrderCodeHealingWave=1,ordercodeutarg,852501,WESTRING_UNITORDERUTARG_HEALINGWAVE\nOrderCodeHex=1,ordercodeutarg,852502,WESTRING_UNITORDERUTARG_HEX\n\n// Night Elf\nOrderCodeRenew=0,ordercodeutarg,852161,WESTRING_UNITORDERUTARG_RENEW\nOrderCodeEntangle=0,ordercodeutarg,852147,WESTRING_UNITORDERUTARG_ENTANGLE\nOrderCodeEntangleInstant=0,ordercodeutarg,852148,WESTRING_UNITORDERUTARG_ENTANGLEINSTANT\nOrderCodeReplenish=0,ordercodeutarg,852157,WESTRING_UNITORDERUTARG_REPLENISH\nOrderCodeLoadArcher=0,ordercodeutarg,852507,WESTRING_UNITORDERUTARG_LOADARCHER\nOrderCodeAutoDispel=0,ordercodeutarg,852132,WESTRING_UNITORDERUTARG_AUTODISPEL\nOrderCodeFaerieFire=0,ordercodeutarg,852149,WESTRING_UNITORDERUTARG_FAERIEFIRE\nOrderCodeCyclone=0,ordercodeutarg,852144,WESTRING_UNITORDERUTARG_CYCLONE\nOrderCodeRejuvination=0,ordercodeutarg,852160,WESTRING_UNITORDERUTARG_REJUVINATION\nOrderCodeVengeance=1,ordercodeutarg,852521,WESTRING_UNITORDERUTARG_VENGEANCE\nOrderCodeManaBurn=0,ordercodeutarg,852179,WESTRING_UNITORDERUTARG_MANABURN\nOrderCodeEntanglingRoots=0,ordercodeutarg,852171,WESTRING_UNITORDERUTARG_ENTANGLINGROOTS\nOrderCodeShadowStrike=1,ordercodeutarg,852527,WESTRING_UNITORDERUTARG_SHADOWSTRIKE\n// Undead\nOrderCodeRestoration=0,ordercodeutarg,852202,WESTRING_UNITORDERUTARG_RESTORE\nOrderCodeSacrificeAcolyte=0,ordercodeutarg,852205,WESTRING_UNITORDERUTARG_SACRIFICEACOLYTE\nOrderCodeSacrifice=0,ordercodeutarg,852201,WESTRING_UNITORDERUTARG_SACRIFICE\nOrderCodeUnsummon=0,ordercodeutarg,852210,WESTRING_UNITORDERUTARG_UNSUMMON\nOrderCodeWeb=0,ordercodeutarg,852211,WESTRING_UNITORDERUTARG_WEB\nOrderCodeRaiseDead=0,ordercodeutarg,852197,WESTRING_UNITORDERUTARG_RAISEDEAD\nOrderCodeUnholyFrenzy=0,ordercodeutarg,852209,WESTRING_UNITORDERUTARG_UNHOLYFRENZY\nOrderCodeCripple=0,ordercodeutarg,852189,WESTRING_UNITORDERUTARG_CRIPPLE\nOrderCodeCurse=0,ordercodeutarg,852190,WESTRING_UNITORDERUTARG_CURSE\nOrderCodeAntiMagicShell=0,ordercodeutarg,852186,WESTRING_UNITORDERUTARG_ANTIMAGICSHELL\nOrderCodePossession=0,ordercodeutarg,852196,WESTRING_UNITORDERUTARG_POSSESSION\nOrderCodeAbsorbMana=1,ordercodeutarg,852529,WESTRING_UNITORDERUTARG_ABSORBMANA\nOrderCodeFlamingAttack=1,ordercodeutarg,852539,WESTRING_UNITORDERUTARG_FLAMINGATTACK\nOrderCodeImpale=1,ordercodeutarg,852555,WESTRING_UNITORDERUTARG_IMPALE\nOrderCodeCarrionScarabs=1,ordercodeutarg,852551,WESTRING_UNITORDERUTARG_CARRIONSCARABS\nOrderCodeDeathCoil=0,ordercodeutarg,852222,WESTRING_UNITORDERUTARG_DEATHCOIL\nOrderCodeDeathPact=0,ordercodeutarg,852223,WESTRING_UNITORDERUTARG_DEATHPACT\nOrderCodeSleep=0,ordercodeutarg,852227,WESTRING_UNITORDERUTARG_SLEEP\nOrderCodeFrostNova=0,ordercodeutarg,852226,WESTRING_UNITORDERUTARG_FROSTNOVA\nOrderCodeFrostArmor=0,ordercodeutarg,852225,WESTRING_UNITORDERUTARG_FROSTARMOR\nOrderCodeDarkRitual=0,ordercodeutarg,852219,WESTRING_UNITORDERUTARG_DARKRITUAL\n// Neutral\nOrderTargetCodeBreathOfFrost=1,ordercodeutarg,852560,WESTRING_UNITORDERPTARG_BREATHOFFROST\nOrderCodeCreepDevour=1,ordercodeutarg,852247,WESTRING_UNITORDERUTARG_CREEPDEVOUR\nOrderCodeFirebolt=0,ordercodeutarg,852231,WESTRING_UNITORDERUTARG_FIREBOLT\nOrderCodeCreepHeal=0,ordercodeutarg,852248,WESTRING_UNITORDERUTARG_CREEPHEAL\nOrderCodeCreepThunderBolt=0,ordercodeutarg,852252,WESTRING_UNITORDERUTARG_CREEPTHUNDERBOLT\nOrderCodeParasite=1,ordercodeutarg,852601,WESTRING_UNITORDERUTARG_PARASITE\nOrderCodeSelfDestructUnit=1,ordercodeutarg,852040,WESTRING_UNITORDERUTARG_SELFDESTRUCT\nOrderCodeBlackArrow=1,ordercodeutarg,852577,WESTRING_UNITORDERUTARG_BLACKARROW\nOrderCodeCharm=1,ordercodeutarg,852581,WESTRING_UNITORDERUTARG_CHARM\nOrderCodeLifeDrain=1,ordercodeutarg,852487,WESTRING_UNITORDERUTARG_LIFEDRAIN\nOrderCodeColdArrow=1,ordercodeutarg,852243,WESTRING_UNITORDERUTARG_COLDARROW\nOrderCodeForkedLightning=1,ordercodeutarg,852587,WESTRING_UNITORDERUTARG_FORKEDLIGHTNING\nOrderCodeStrongDrink=1,ordercodeutarg,852585,WESTRING_UNITORDERUTARG_STRONGDRINK\nOrderCodeDoom=1,ordercodeutarg,852583,WESTRING_UNITORDERUTARG_DOOM\nOrderCodeAcidBomb=1,ordercodeutarg,852662,WESTRING_UNITORDERUTARG_ACIDBOMB\nOrderCodeTransmute=1,ordercodeutarg,852665,WESTRING_UNITORDERUTARG_TRANSMUTE\nOrderCodeSoulBurn=1,ordercodeutarg,852668,WESTRING_UNITORDERUTARG_SOULBURN\nOrderCodePoisonArrow=0,ordercodeutarg,852254,WESTRING_UNITORDERUTARG_POISONARROW\nOrderCodeIncinerateArrow=1,ordercodeutarg,852670,WESTRING_UNITORDERUTARG_INCINERATEARROW\n// Special\nOrderCodeFingerOfDeath=0,ordercodeutarg,852230,WESTRING_UNITORDERUTARG_FINGEROFDEATH\nOrderCodeDarkConversion=0,ordercodeutarg,852228,WESTRING_UNITORDERUTARG_DARKCONVERSION\nOrderCodeSoulPreservation=0,ordercodeutarg,852242,WESTRING_UNITORDERUTARG_SOULPRESERVATION\nOrderCodeDarkConversionFast=0,ordercodeutarg,852228,WESTRING_UNITORDERUTARG_DARKCONVERSIONFAST\nOrderCodeNeutralInterAct=0,ordercodeutarg,852566,中立商店 - 选择单位\nOrderCodeItemIllusion=1,ordercodeutarg,852274,物品技能 - 幻象权杖\nOrderCodeItemChainDispel=1,ordercodeutarg,852615,物品技能 - 连锁驱逐\n\n// Trigger Point-Targeted Unit Orders\n// Common\nOrderCodeAttack=0,ordercodeptarg,851983,WESTRING_UNITORDERPTARG_ATTACK\nOrderCodeAttackGround=0,ordercodeptarg,851984,WESTRING_UNITORDERPTARG_ATTACKGROUND\nOrderCodeMove=0,ordercodeptarg,851986,WESTRING_UNITORDERPTARG_MOVE\nOrderCodeAIMove=0,ordercodeptarg,851988,AImove\nOrderCodePatrol=0,ordercodeptarg,851990,WESTRING_UNITORDERPTARG_PATROL\nOrderCodeSmartPoint=1,ordercodeptarg,851971,WESTRING_UNITORDERPTARG_SMART\nOrderCodeSetRally=0,ordercodeptarg,851980,WESTRING_UNITORDERPTARG_SETRALLY\nOrderCodeUnloadAll=0,ordercodeptarg,`852048`,WESTRING_UNITORDERPTARG_UNLOADALL\n// Human\nOrderCodeFlare=0,ordercodeptarg,852060,WESTRING_UNITORDERPTARG_FLARE\nOrderCodeCloudOfFog=1,ordercodeptarg,852473,WESTRING_UNITORDERPTARG_CLOUDOFFOG\nOrderCodeReveal=1,ordercodeptarg,852270,人族神秘之塔 - 显示\nOrderCodeBlizzard=0,ordercodeptarg,852089,WESTRING_UNITORDERPTARG_BLIZZARD\nOrderCodeFlameStrike=1,ordercodeptarg,852488,WESTRING_UNITORDERPTARG_FLAMESTRIKE\n// Orc\nOrderCodeSentryWard=0,ordercodeptarg,852105,WESTRING_UNITORDERPTARG_SENTRYWARD\nOrderCodeStasisTrap=0,ordercodeptarg,852114,WESTRING_UNITORDERPTARG_STASISTRAP\nOrderCodeHealingWard=0,ordercodeptarg,852109,WESTRING_UNITORDERPTARG_HEALINGWARD\nOrderCodeDisenchant=1,ordercodeptarg,852495,WESTRING_UNITORDERPTARG_DISENCHANT\nOrderCodeFarSight=0,ordercodeptarg,852122,WESTRING_UNITORDERPTARG_FARSIGHT\nOrderCodeEarthquake=0,ordercodeptarg,852121,WESTRING_UNITORDERPTARG_EARTHQUAKE\nOrderCodeSerpentWard=1,ordercodeptarg,852504,WESTRING_UNITORDERPTARG_SERPENTWARD\nOrderCodeShockwave=0,ordercodeptarg,852125,WESTRING_UNITORDERPTARG_SHOCKWAVE\n// Night Elf\nOrderCodeRoot=0,ordercodeptarg,852165,WESTRING_UNITORDERPTARG_ROOT\nOrderCodeDetonate=0,ordercodeptarg,852145,WESTRING_UNITORDERPTARG_DETONATE\nOrderCodeForceOfNature=0,ordercodeptarg,852176,WESTRING_UNITORDERPTARG_FORCEOFNATURE\nOrderCodeStarfall=0,ordercodeptarg,`obsolete`,WESTRING_UNITORDERPTARG_STARFALL\nOrderCodeBlink=1,ordercodeptarg,852525,WESTRING_UNITORDERPTARG_BLINK\n// Undead\nOrderCodeDevourMagic=1,ordercodeptarg,852536,WESTRING_UNITORDERPTARG_DEVOURMAGIC\nOrderCodeImpalePoint=1,ordercodeptarg,852555,WESTRING_UNITORDERPTARG_IMPALE\nOrderCodeCarrionSwarm=0,ordercodeptarg,852218,WESTRING_UNITORDERPTARG_CARRIONSWARM\nOrderCodeDarkSummoning=0,ordercodeptarg,852224,WESTRING_UNITORDERPTARG_DARKSUMMONING\nOrderCodeDeathAndDecay=0,ordercodeptarg,852221,WESTRING_UNITORDERPTARG_DEATHANDDECAY\n// Neutral\nOrderCodeBreathOfFrost=1,ordercodeptarg,852560,WESTRING_UNITORDERPTARG_BREATHOFFROST\nOrderCodeMonsoon=1,ordercodeptarg,852591,WESTRING_UNITORDERPTARG_MONSOON\nOrderCodeSelfDestruct=0,ordercodeptarg,852040,WESTRING_UNITORDERPTARG_SELFDESTRUCT\nOrderCodeInferno=0,ordercodeptarg,852232,WESTRING_UNITORDERPTARG_INFERNO\nOrderCodeStampede=1,ordercodeptarg,852593,WESTRING_UNITORDERPTARG_STAMPEDE\nOrderCodeSilence=1,ordercodeptarg,852592,WESTRING_UNITORDERPTARG_SILENCE\nOrderCodeTornado=1,ordercodeptarg,852597,WESTRING_UNITORDERPTARG_TORNADO\nOrderCodeBreathOfFire=1,ordercodeptarg,852580,WESTRING_UNITORDERPTARG_BREATHOFFIRE\nOrderCodeHeroRainOfFire=1,ordercodeptarg,852238,WESTRING_UNITORDERPTARG_HERORAINOFFIRE\nOrderCodeHealingSpray=1,ordercodeptarg,852664,WESTRING_UNITORDERPTARG_HEALINGSPRAY\nOrderCodeClusterRockets=1,ordercodeptarg,852652,WESTRING_UNITORDERPTARG_CLUSTERROCKETS\nOrderCodeSummonFactory=1,ordercodeptarg,852658,WESTRING_UNITORDERPTARG_SUMMONFACTORY\nOrderCodeVolcano=1,ordercodeptarg,852669,WESTRING_UNITORDERPTARG_VOLCANO\n// Special\nOrderCodeDarkPortal=0,ordercodeptarg,852229,WESTRING_UNITORDERPTARG_DARKPORTAL\nOrderCodeRainOfChaos=0,ordercodeptarg,852237,WESTRING_UNITORDERPTARG_RAINOFCHAOS\nOrderCodeRainOfFire=0,ordercodeptarg,852238,WESTRING_UNITORDERPTARG_RAINOFFIRE\nOrderCodeDarkSummoningOld=0,ordercodeptarg,852220,WESTRING_UNITORDERPTARG_DARKSUMMONINGOLD\nOrderCodeNeutralDetectAOE=0,ordercodeptarg,852023,地精实验室 - 侦查\n\n// Trigger Destructible-Targeted Unit Orders\n// Common\nOrderCodeAttackDestructible=0,ordercodedtarg,851983,WESTRING_UNITORDERDTARG_ATTACK\nOrderCodeAttackDestructibleOnce=0,ordercodedtarg,851985,WESTRING_UNITORDERUTARG_ATTACKONCE\nOrderCodeSmartDestructible=1,ordercodedtarg,851971,WESTRING_UNITORDERDTARG_SMART\nOrderCodeSetRallyDestructible=0,ordercodedtarg,851980,WESTRING_UNITORDERPTARG_SETRALLY\nOrderCodeHarvestDestructible=0,ordercodedtarg,852018,WESTRING_UNITORDERDTARG_HARVEST\nOrderCodeMoveDestructible=0,ordercodedtarg,851986,WESTRING_UNITORDERPTARG_MOVE\nOrderCodeAIMoveDestructible=0,ordercodedtarg,851988,AImove\n// Human\n// Orc\n// Night Elf\nOrderCodeConsumeTree=0,ordercodedtarg,852146,WESTRING_UNITORDERDTARG_CONSUMETREE\nOrderCodeSentinel=0,ordercodedtarg,852182,WESTRING_UNITORDERDTARG_SENTINEL\nOrderCodeGrabTree=1,ordercodedtarg,852511,WESTRING_UNITORDERDTARG_GRABTREE\n// Undead\n// Neutral\n// Special\n\n// Trigger Item-Targeted Unit Orders\n\n// Common\nOrderCodeAttackItem=1,ordercodeitarg,851983,WESTRING_UNITORDERITARG_ATTACK\nOrderCodeAttackItemOnce=1,ordercodeitarg,851985,WESTRING_UNITORDERITARG_ATTACKONCE\nOrderCodeSmartItem=1,ordercodeitarg,851988,WESTRING_UNITORDERITARG_SMART\nOrderCodeSetRallyItem=0,ordercodeitarg,851980,WESTRING_UNITORDERPTARG_SETRALLY\nOrderCodeMoveItem0=1,ordercodeitarg,852002,移动物品到第1格\nOrderCodeMoveItem1=1,ordercodeitarg,852003,移动物品到第2格\nOrderCodeMoveItem2=1,ordercodeitarg,852004,移动物品到第3格\nOrderCodeMoveItem3=1,ordercodeitarg,852005,移动物品到第4格\nOrderCodeMoveItem4=1,ordercodeitarg,852006,移动物品到第5格\nOrderCodeMoveItem5=1,ordercodeitarg,852007,移动物品到第6格\nOrderCodeRandomItem=1,ordercodeitarg,852622,物品技能 - 随机物品\n\n// Trigger Immediate / Untargeted Unit Orders\n// Common\nOrderCodeStop=0,ordercodenotarg,851972,WESTRING_UNITORDERNOTARG_STOP\nOrderCodeHoldPosition=0,ordercodenotarg,851993,WESTRING_UNITORDERNOTARG_HOLDPOSITION\nOrderCodeAutoHarvestGold=0,ordercodenotarg,852021,WESTRING_UNITORDERNOTARG_AUTOHARVESTGOLD\nOrderCodeAutoHarvestLumber=0,ordercodenotarg,852022,WESTRING_UNITORDERNOTARG_AUTOHARVESTLUMBER\nOrderCodeReturnResources=0,ordercodenotarg,852020,WESTRING_UNITORDERNOTARG_RETURNRESOURCES\nOrderCodeBuild=1,ordercodenotarg,851994,WESTRING_UNITORDERNOTARG_BUILD\nOrderCodeHeroSkill=1,ordercodenotarg,852000,打开技能菜单\nOrderCodeCancel=0,ordercodenotarg,851976,取消(训练、升级、研究)\nOrderCodeUseItem0=1,ordercodenotarg,852008,使用第1格物品(无效)\nOrderCodeUseItem1=1,ordercodenotarg,852009,使用第2格物品(无效)\nOrderCodeUseItem2=1,ordercodenotarg,852010,使用第3格物品(无效)\nOrderCodeUseItem3=1,ordercodenotarg,852011,使用第4格物品(无效)\nOrderCodeUseItem4=1,ordercodenotarg,852012,使用第5格物品(无效)\nOrderCodeUseItem5=1,ordercodenotarg,852013,使用第6格物品(无效)\n\n// Human\nOrderCodeHumanBuild=1,ordercodenotarg,851995,WESTRING_UNITORDERNOTARG_HUMANBUILD\nOrderCodeTownBellOn=0,ordercodenotarg,852082,WESTRING_UNITORDERNOTARG_TOWNBELLON\nOrderCodeTownBellOff=0,ordercodenotarg,852083,WESTRING_UNITORDERNOTARG_TOWNBELLOFF\nOrderCodeMilitia=0,ordercodenotarg,852072,WESTRING_UNITORDERNOTARG_MILITIA\nOrderCodeMilitiaOff=0,ordercodenotarg,852073,WESTRING_UNITORDERNOTARG_MILITIAOFF\nOrderCodeRepairOn=0,ordercodenotarg,852025,WESTRING_UNITORDERNOTARG_REPAIRON\nOrderCodeRepairOff=0,ordercodenotarg,852026,WESTRING_UNITORDERNOTARG_REPAIROFF\nOrderCodeDefend=0,ordercodenotarg,852055,WESTRING_UNITORDERNOTARG_DEFEND\nOrderCodeUnDefend=0,ordercodenotarg,852056,WESTRING_UNITORDERNOTARG_UNDEFEND\nOrderCodeHealOn=0,ordercodenotarg,852064,WESTRING_UNITORDERNOTARG_HEALON\nOrderCodeHealOff=0,ordercodenotarg,852065,WESTRING_UNITORDERNOTARG_HEALOFF\nOrderCodeInnerFireOn=0,ordercodenotarg,852067,WESTRING_UNITORDERNOTARG_INNERFIREON\nOrderCodeInnerFireOff=0,ordercodenotarg,852068,WESTRING_UNITORDERNOTARG_INNERFIREOFF\nOrderCodeSlowOn=0,ordercodenotarg,852076,WESTRING_UNITORDERNOTARG_SLOWON\nOrderCodeSlowOff=0,ordercodenotarg,852077,WESTRING_UNITORDERNOTARG_SLOWOFF\nOrderCodeSpellStealOn=1,ordercodenotarg,852484,WESTRING_UNITORDERNOTARG_SPELLSTEALON\nOrderCodeSpellStealOff=1,ordercodenotarg,852485,WESTRING_UNITORDERNOTARG_SPELLSTEALOFF\nOrderCodeMagicDefense=1,ordercodenotarg,852478,人族破法者 - 激活魔法防御\nOrderCodeMagicUnDefense=1,ordercodenotarg,852479,人族破法者 - 取消魔法防御\nOrderCodeWaterElemental=0,ordercodenotarg,852097,WESTRING_UNITORDERNOTARG_WATERELEMENTAL\nOrderCodePhoenix=1,ordercodenotarg,852489,WESTRING_UNITORDERNOTARG_PHOENIX\nOrderCodeThunderClap=0,ordercodenotarg,852096,WESTRING_UNITORDERNOTARG_THUNDERCLAP\nOrderCodeAvatar=0,ordercodenotarg,852086,WESTRING_UNITORDERNOTARG_AVATAR\nOrderCodeDivineShield=0,ordercodenotarg,852090,WESTRING_UNITORDERNOTARG_DIVINESHIELD\nOrderCodeUnDivineShield=0,ordercodenotarg,852091,WESTRING_UNITORDERNOTARG_UNDIVINESHIELD\nOrderCodeResurrection=0,ordercodenotarg,852094,WESTRING_UNITORDERNOTARG_RESURRECTION\n// Orc\nOrderCodeOrcBuild=1,ordercodenotarg,851996,WESTRING_UNITORDERNOTARG_ORCBUILD\nOrderCodeBattleStations=0,ordercodenotarg,852099,WESTRING_UNITORDERNOTARG_BATTLESTATIONS\nOrderCodeStandDown=0,ordercodenotarg,852113,WESTRING_UNITORDERNOTARG_STANDDOWN\nOrderCodeRepairOOn=0,ordercodenotarg,852025,WESTRING_UNITORDERNOTARG_REPAIROON\nOrderCodeRepairOOff=0,ordercodenotarg,852026,WESTRING_UNITORDERNOTARG_REPAIROOFF\nOrderCodeBerserk=1,ordercodenotarg,852100,WESTRING_UNITORDERNOTARG_BERSERK\nOrderCodeBloodlustOn=0,ordercodenotarg,852102,WESTRING_UNITORDERNOTARG_BLOODLUSTON\nOrderCodeBloodlustOff=0,ordercodenotarg,852103,WESTRING_UNITORDERNOTARG_BLOODLUSTOFF\nOrderCodeAncestralSpirit=1,ordercodenotarg,852490,WESTRING_UNITORDERNOTARG_ANCESTRALSPIRIT\nOrderCodeEtherealForm=1,ordercodenotarg,852494,WESTRING_UNITORDERNOTARG_ETHEREALFORM\nOrderCodeCorporealForm=1,ordercodenotarg,852493,WESTRING_UNITORDERNOTARG_CORPOREALFORM\nOrderCodeWindWalk=0,ordercodenotarg,852129,WESTRING_UNITORDERNOTARG_WINDWALK\nOrderCodeMirrorImage=0,ordercodenotarg,852123,WESTRING_UNITORDERNOTARG_MIRRORIMAGE\nOrderCodeWhirlWind=0,ordercodenotarg,852128,WESTRING_UNITORDERNOTARG_BLADESTORM\nOrderCodeSpiritWolf=0,ordercodenotarg,852126,WESTRING_UNITORDERNOTARG_FERALSPIRIT\nOrderCodeVoodoo=1,ordercodenotarg,852503,WESTRING_UNITORDERNOTARG_VOODOO\nOrderCodeStomp=0,ordercodenotarg,852127,WESTRING_UNITORDERNOTARG_WARSTOMP\n// Night Elf\nOrderCodeNightElfBuild=1,ordercodenotarg,851997,WESTRING_UNITORDERNOTARG_NIGHTELFBUILD\nOrderCodeUnRoot=0,ordercodenotarg,852166,WESTRING_UNITORDERNOTARG_UNROOT\nOrderCodeAutoEntangle=1,ordercodenotarg,852505,WESTRING_UNITORDERNOTARG_AUTOENTANGLE\nOrderCodeAutoEntangleInstant=1,ordercodenotarg,852506,WESTRING_UNITORDERNOTARG_AUTOENTANGLEINSTANT\nOrderCodeReplenishOn=1,ordercodenotarg,852158,WESTRING_UNITORDERNOTARG_REPLENISHON\nOrderCodeReplenishOff=1,ordercodenotarg,852159,WESTRING_UNITORDERNOTARG_REPLENISHOFF\nOrderCodeAmbush=0,ordercodenotarg,852131,WESTRING_UNITORDERNOTARG_HIDE\nOrderCodeRenewOn=0,ordercodenotarg,852162,WESTRING_UNITORDERNOTARG_RENEWON\nOrderCodeRenewOff=0,ordercodenotarg,852163,WESTRING_UNITORDERNOTARG_RENEWOFF\nOrderCodeCoupleInstant1=1,ordercodenotarg,852508,WESTRING_UNITORDERNOTARG_COUPLEINSTANT1\nOrderCodeCoupleInstant2=1,ordercodenotarg,852508,WESTRING_UNITORDERNOTARG_COUPLEINSTANT2\nOrderCodeDecouple=1,ordercodenotarg,852509,WESTRING_UNITORDERNOTARG_DECOUPLE\nOrderCodeAutoDispelOn=0,ordercodenotarg,852133,WESTRING_UNITORDERNOTARG_AUTODISPELON\nOrderCodeAutoDispelOff=0,ordercodenotarg,852134,WESTRING_UNITORDERNOTARG_AUTODISPELOFF\nOrderCodeFaerieFireOn=0,ordercodenotarg,852150,WESTRING_UNITORDERNOTARG_FAERIEFIREON\nOrderCodeFaerieFireOff=0,ordercodenotarg,852151,WESTRING_UNITORDERNOTARG_FAERIEFIREOFF\nOrderCodeRavenForm=0,ordercodenotarg,852155,WESTRING_UNITORDERNOTARG_RAVENFORM\nOrderCodeUnRavenForm=0,ordercodenotarg,852156,WESTRING_UNITORDERNOTARG_UNRAVENFORM\nOrderCodeRoar=0,ordercodenotarg,852164,WESTRING_UNITORDERNOTARG_ROAR\nOrderCodeBearForm=0,ordercodenotarg,852138,WESTRING_UNITORDERNOTARG_BEARFORM\nOrderCodeUnBearForm=0,ordercodenotarg,852139,WESTRING_UNITORDERNOTARG_UNBEARFORM\nOrderCodeTaunt=1,ordercodenotarg,852520,WESTRING_UNITORDERNOTARG_TAUNT\nOrderCodeManaFlareOn=1,ordercodenotarg,852512,WESTRING_UNITORDERNOTARG_MANAFLAREON\nOrderCodeManaFlareOff=1,ordercodenotarg,852513,WESTRING_UNITORDERNOTARG_MANAFLAREOFF\nOrderCodePhaseShift=1,ordercodenotarg,852514,WESTRING_UNITORDERNOTARG_PHASESHIFT\nOrderCodePhaseShiftOn=1,ordercodenotarg,852515,WESTRING_UNITORDERNOTARG_PHASESHIFTON\nOrderCodePhaseShiftOff=1,ordercodenotarg,852516,WESTRING_UNITORDERNOTARG_PHASESHIFTOFF\nOrderCodeVengeanceInstant=1,ordercodenotarg,852524,WESTRING_UNITORDERNOTARG_VENGEANCEINSTANT\nOrderCodeVengeanceOn=1,ordercodenotarg,852522,WESTRING_UNITORDERNOTARG_VENGEANCEON\nOrderCodeVengeanceOff=1,ordercodenotarg,852523,WESTRING_UNITORDERNOTARG_VENGEANCEOFF\nOrderCodeImmolation=0,ordercodenotarg,852177,WESTRING_UNITORDERNOTARG_IMMOLATION\nOrderCodeUnImmolation=0,ordercodenotarg,852178,WESTRING_UNITORDERNOTARG_UNIMMOLATION\nOrderCodeMetamorphosis=0,ordercodenotarg,852180,WESTRING_UNITORDERNOTARG_METAMORPHOSIS\nOrderCodeTranquility=0,ordercodenotarg,852184,WESTRING_UNITORDERNOTARG_TRANQUILITY\nOrderCodeSearingArrows=0,ordercodenotarg,852174,WESTRING_UNITORDERNOTARG_SEARINGARROWS\nOrderCodeUnSearingArrows=0,ordercodenotarg,852175,WESTRING_UNITORDERNOTARG_UNSEARINGARROWS\nOrderCodeScout=0,ordercodenotarg,852181,WESTRING_UNITORDERNOTARG_SCOUT\nOrderCodeStarfall2=0,ordercodenotarg,852183,WESTRING_UNITORDERNOTARG_STARFALL\nOrderCodeFanOfKnives=1,ordercodenotarg,852526,WESTRING_UNITORDERNOTARG_FANOFKNIVES\nOrderCodeSpiritOfVengeance=1,ordercodenotarg,852528,WESTRING_UNITORDERNOTARG_SPIRITOFVENGEANCE\n// Undead\nOrderCodeUndeadBuild=1,ordercodenotarg,851998,WESTRING_UNITORDERNOTARG_UNDEADBUILD\nOrderCodeRestorationOn=0,ordercodenotarg,852203,WESTRING_UNITORDERNOTARG_RESTOREON\nOrderCodeRestorationOff=0,ordercodenotarg,852204,WESTRING_UNITORDERNOTARG_RESTOREOFF\nOrderCodeCannibalize=0,ordercodenotarg,852188,WESTRING_UNITORDERNOTARG_CANNIBALIZE\nOrderCodeWebOn=0,ordercodenotarg,852212,WESTRING_UNITORDERNOTARG_WEBON\nOrderCodeWebOff=0,ordercodenotarg,852213,WESTRING_UNITORDERNOTARG_WEBOFF\nOrderCodeBurrow=1,ordercodenotarg,852533,WESTRING_UNITORDERNOTARG_BURROW\nOrderCodeUnBurrow=1,ordercodenotarg,852534,WESTRING_UNITORDERNOTARG_UNBURROW\nOrderCodeLoadCorpse=0,ordercodenotarg,852050,WESTRING_UNITORDERNOTARG_LOADCORPSE\nOrderCodeUnloadAllCorpses=0,ordercodenotarg,852054,WESTRING_UNITORDERNOTARG_UNLOADALLCORPSES\nOrderCodeStoneForm=0,ordercodenotarg,852206,WESTRING_UNITORDERNOTARG_STONEFORM\nOrderCodeUnStoneForm=0,ordercodenotarg,852207,WESTRING_UNITORDERNOTARG_UNSTONEFORM\nOrderCodeRaiseDeadInstant=1,ordercodenotarg,852200,WESTRING_UNITORDERNOTARG_RAISEDEAD\nOrderCodeRaiseDeadOn=0,ordercodenotarg,852198,WESTRING_UNITORDERNOTARG_RAISEDEADON\nOrderCodeRaiseDeadOff=0,ordercodenotarg,852199,WESTRING_UNITORDERNOTARG_RAISEDEADOFF\nOrderCodeCurseOn=0,ordercodenotarg,852191,WESTRING_UNITORDERNOTARG_CURSEON\nOrderCodeCurseOff=0,ordercodenotarg,852192,WESTRING_UNITORDERNOTARG_CURSEOFF\nOrderCodeFlamingAttackOn=1,ordercodenotarg,852540,WESTRING_UNITORDERNOTARG_FLAMINGATTACKON\nOrderCodeFlamingAttackOff=1,ordercodenotarg,852541,WESTRING_UNITORDERNOTARG_FLAMINGATTACKOFF\nOrderCodeSphinxForm=1,ordercodenotarg,852531,WESTRING_UNITORDERNOTARG_SPHINXFORM\nOrderCodeReplenishLife=1,ordercodenotarg,852545,WESTRING_UNITORDERNOTARG_REPLENISHLIFE\nOrderCodeReplenishLifeOn=1,ordercodenotarg,852546,WESTRING_UNITORDERNOTARG_REPLENISHLIFEON\nOrderCodeReplenishLifeOff=1,ordercodenotarg,852547,WESTRING_UNITORDERNOTARG_REPLENISHLIFEOFF\nOrderCodeReplenishMana=1,ordercodenotarg,852548,WESTRING_UNITORDERNOTARG_REPLENISHMANA\nOrderCodeReplenishManaOn=1,ordercodenotarg,852549,WESTRING_UNITORDERNOTARG_REPLENISHMANAON\nOrderCodeReplenishManaOff=1,ordercodenotarg,852550,WESTRING_UNITORDERNOTARG_REPLENISHMANAOFF\nOrderCodeCarrionScarabsInstant=1,ordercodenotarg,852554,\"不死族地穴领主 - 召唤腐尸甲虫\"\nOrderCodeCarrionScarabsOn=1,ordercodenotarg,852552,WESTRING_UNITORDERNOTARG_CARRIONSCARABSON\nOrderCodeCarrionScarabsOff=1,ordercodenotarg,852553,WESTRING_UNITORDERNOTARG_CARRIONSCARABSOFF\nOrderCodeCarrionScarabsInstant=1,ordercodenotarg,852554,WESTRING_UNITORDERNOTARG_CARRIONSCARABS\nOrderCodeLocustSwarm=1,ordercodenotarg,852556,WESTRING_UNITORDERNOTARG_LOCUSTSWARM\nOrderCodeAnimateDead=0,ordercodenotarg,852217,WESTRING_UNITORDERNOTARG_ANIMATEDEAD\nOrderCodeFrostArmorOn=0,ordercodenotarg,852458,WESTRING_UNITORDERNOTARG_FROSTARMORON\nOrderCodeFrostArmorOff=0,ordercodenotarg,852459,WESTRING_UNITORDERNOTARG_FROSTARMOROFF\n// Neutral\nOrderCodeNagaBuild=1,ordercodenotarg,852467,WESTRING_UNITORDERNOTARG_NAGABUILD\nOrderCodeSubmerge=1,ordercodenotarg,852604,娜迦 - 潜水\nOrderCodeUnSubmerge=1,ordercodenotarg,852605,娜迦 - 取消潜水\nOrderCodeParasiteOn=1,ordercodenotarg,852602,娜迦海妖 - 激活寄生虫\nOrderCodeParasiteOff=1,ordercodenotarg,852603,娜迦海妖 - 取消寄生虫\nOrderCodeCreepAnimateDead=0,ordercodenotarg,852246,WESTRING_UNITORDERNOTARG_CREEPANIMATEDEAD\nOrderCodeCreepHealOn=0,ordercodenotarg,852249,WESTRING_UNITORDERNOTARG_CREEPHEALON\nOrderCodeCreepHealOff=0,ordercodenotarg,852250,WESTRING_UNITORDERNOTARG_CREEPHEALOFF\nOrderCodeRevenge=0,ordercodenotarg,852241,WESTRING_UNITORDERNOTARG_REVENGE\nOrderCodeCreepThunderClap=0,ordercodenotarg,852253,WESTRING_UNITORDERNOTARG_CREEPTHUNDERCLAP\nOrderCodeWateryMinion=1,ordercodenotarg,852598,WESTRING_UNITORDERNOTARG_WATERYMINION\nOrderCodeSelfDestructOn=1,ordercodenotarg,852041,WESTRING_UNITORDERNOTARG_SELFDESTRUCTON\nOrderCodeSelfDestructOff=1,ordercodenotarg,852042,WESTRING_UNITORDERNOTARG_SELFDESTRUCTOFF\nOrderCodeSummonGrizzly=1,ordercodenotarg,852594,WESTRING_UNITORDERNOTARG_SUMMONGRIZZLY\nOrderCodeSummonQuillbeast=1,ordercodenotarg,852595,WESTRING_UNITORDERNOTARG_SUMMONQUILLBEAST\nOrderCodeSummonWarEagle=1,ordercodenotarg,852596,WESTRING_UNITORDERNOTARG_SUMMONWAREAGLE\nOrderCodeBlackArrowOn=1,ordercodenotarg,852578,WESTRING_UNITORDERNOTARG_BLACKARROWON\nOrderCodeBlackArrowOff=1,ordercodenotarg,852579,WESTRING_UNITORDERNOTARG_BLACKARROWOFF\nOrderCodeColdArrowOn=1,ordercodenotarg,852244,WESTRING_UNITORDERNOTARG_COLDARROWON\nOrderCodeColdArrowOff=1,ordercodenotarg,852245,WESTRING_UNITORDERNOTARG_COLDARROWOFF\nOrderCodeManaShieldOn=1,ordercodenotarg,852589,WESTRING_UNITORDERNOTARG_MANASHIELDON\nOrderCodeManaShieldOff=1,ordercodenotarg,852590,WESTRING_UNITORDERNOTARG_MANASHIELDOFF\nOrderCodeElementalFury=1,ordercodenotarg,852586,WESTRING_UNITORDERNOTARG_ELEMENTALFURY\nOrderCodeHowlOfTerror=1,ordercodenotarg,852588,WESTRING_UNITORDERNOTARG_HOWLOFTERROR\nOrderCodePoisonArrows=0,ordercodenotarg,852255,WESTRING_UNITORDERNOTARG_POISONARROWON\nOrderCodeUnPoisonArrows=0,ordercodenotarg,852256,WESTRING_UNITORDERNOTARG_POISONARROWOFF\nOrderCodeChemicalRage=1,ordercodenotarg,852663,WESTRING_UNITORDERNOTARG_CHEMICALRAGE\nOrderCodeRoboGoblin=1,ordercodenotarg,852656,WESTRING_UNITORDERNOTARG_ROBOGOBLIN\nOrderCodeUnRoboGoblin=1,ordercodenotarg,852657,WESTRING_UNITORDERNOTARG_UNROBOGOBLIN\nOrderCodeLavaMonster=1,ordercodenotarg,852667,WESTRING_UNITORDERNOTARG_LAVAMONSTER\nOrderCodeIncinerateArrowOn=1,ordercodenotarg,852671,WESTRING_UNITORDERNOTARG_INCINERATEARROWON\nOrderCodeIncinerateArrowOff=1,ordercodenotarg,852672,WESTRING_UNITORDERNOTARG_INCINERATEARROWOFF\n// Special\nOrderCodeChannel=1,ordercodenotarg,852600,WESTRING_UNITORDERNOTARG_CHANNEL\nOrderCodeMedivhRavenForm=0,ordercodenotarg,852155,WESTRING_UNITORDERNOTARG_MEDIVHRAVENFORM\nOrderCodeMedivhUnRavenForm=0,ordercodenotarg,852156,WESTRING_UNITORDERNOTARG_MEDIVHUNRAVENFORM\nOrderCodeRexxarBattleRoar=1,ordercodenotarg,852599,WESTRING_UNITORDERNOTARG_REXXARBATTLEROAR\nOrderCodeColdArrows=0,ordercodenotarg,852244,WESTRING_UNITORDERNOTARG_COLDARROWS\nOrderCodeUnColdArrows=0,ordercodenotarg,852245,WESTRING_UNITORDERNOTARG_UNCOLDARROWS\nOrderCodeDustOfAppearance=1,ordercodenotarg,852621,物品技能 - 月亮石\nOrderCodeDustOfAppearance=1,ordercodenotarg,852625,物品技能 - 显影之尘\n\n// Order\nOrderCode_Smart=0,ordercode,851971,右键点击\nOrderCode_Stop=0,ordercode,851972,停止\nOrderCode_Attack=0,ordercode,851983,攻击\nOrderCode_Hold=0,ordercode,851993,保持原位\nOrderCode_Move=0,ordercode,851986,移动/跟随\nOrderCode_Stun=0,ordercode,851973,昏迷\nOrderCode_Cancel=0,ordercode,851976,取消\nOrderCode_SkillPage=0,ordercode,852000,技能菜单\n\n// Hero Skills\n// Human Archmage\nHeroSkillBlizzard=0,heroskillcode,'AHbz',WESTRING_HEROSKILL_BLIZZARD\nHeroSkillWaterElemental=0,heroskillcode,'AHwe',WESTRING_HEROSKILL_WATERELEMENTAL\nHeroSkillBrillianceAura=0,heroskillcode,'AHab',WESTRING_HEROSKILL_BRILLIANCEAURA\nHeroSkillMassTeleport=0,heroskillcode,'AHmt',WESTRING_HEROSKILL_MASSTELEPORT\n// Human Blood Mage\nHeroSkillFlameStrike=1,heroskillcode,'AHfs',WESTRING_HEROSKILL_FLAMESTRIKE\nHeroSkillBanish=1,heroskillcode,'AHbn',WESTRING_HEROSKILL_BANISH\nHeroSkillSiphonMana=1,heroskillcode,'AHdr',WESTRING_HEROSKILL_SIPHONMANA\nHeroSkillPhoenix=1,heroskillcode,'AHpx',WESTRING_HEROSKILL_PHOENIX\n// Human Mountain King\nHeroSkillStormBolt=0,heroskillcode,'AHtb',WESTRING_HEROSKILL_STORMBOLT\nHeroSkillThunderClap=0,heroskillcode,'AHtc',WESTRING_HEROSKILL_THUNDERCLAP\nHeroSkillBash=0,heroskillcode,'AHbh',WESTRING_HEROSKILL_BASH\nHeroSkillAvatar=0,heroskillcode,'AHav',WESTRING_HEROSKILL_AVATAR\n// Human Paladin\nHeroSkillDivineShield=0,heroskillcode,'AHds',WESTRING_HEROSKILL_DIVINESHIELD\nHeroSkillHolyBolt=0,heroskillcode,'AHhb',WESTRING_HEROSKILL_HOLYBOLT\nHeroSkillDevotionAura=0,heroskillcode,'AHad',WESTRING_HEROSKILL_DEVOTIONAURA\nHeroSkillResurrection=0,heroskillcode,'AHre',WESTRING_HEROSKILL_RESURRECTION\n// Orc Blademaster\nHeroSkillWindWalk=0,heroskillcode,'AOwk',WESTRING_HEROSKILL_WINDWALK\nHeroSkillMirrorImage=0,heroskillcode,'AOmi',WESTRING_HEROSKILL_MIRRORIMAGE\nHeroSkillCriticalStrike=0,heroskillcode,'AOcr',WESTRING_HEROSKILL_CRITICALSTRIKE\nHeroSkillWhirlwind=0,heroskillcode,'AOww',WESTRING_HEROSKILL_WHIRLWIND\n// Orc Far Seer\nHeroSkillChainLightning=0,heroskillcode,'AOcl',WESTRING_HEROSKILL_CHAINLIGHTNING\nHeroSkillFarSight=0,heroskillcode,'AOfs',WESTRING_HEROSKILL_FARSIGHT\nHeroSkillSpiritWolf=0,heroskillcode,'AOsf',WESTRING_HEROSKILL_SPIRITWOLF\nHeroSkillEarthquake=0,heroskillcode,'AOeq',WESTRING_HEROSKILL_EARTHQUAKE\n// Orc Shadow Hunter\nHeroSkillHealingWave=1,heroskillcode,'AOhw',WESTRING_HEROSKILL_HEALINGWAVE\nHeroSkillHex=1,heroskillcode,'AOhx',WESTRING_HEROSKILL_HEX\nHeroSkillSerpentWard=1,heroskillcode,'AOsw',WESTRING_HEROSKILL_SERPENTWARD\nHeroSkillVoodoo=1,heroskillcode,'AOvd',WESTRING_HEROSKILL_VOODOO\n// Orc Tauren Chieftain\nHeroSkillShockwave=0,heroskillcode,'AOsh',WESTRING_HEROSKILL_SHOCKWAVE\nHeroSkillWarStomp=0,heroskillcode,'AOws',WESTRING_HEROSKILL_WARSTOMP\nHeroSkillEnduranceAura=0,heroskillcode,'AOae',WESTRING_HEROSKILL_ENDURANCEAURA\nHeroSkillReincarnation=0,heroskillcode,'AOre',WESTRING_HEROSKILL_REINCARNATION\n// Undead Crypt Lord\nHeroSkillImpale=1,heroskillcode,'AUim',WESTRING_HEROSKILL_IMPALE\nHeroSkillThornyShield=1,heroskillcode,'AUts',WESTRING_HEROSKILL_THORNYSHIELD\nHeroSkillCarrionScarabs=1,heroskillcode,'AUcb',WESTRING_HEROSKILL_CARRIONSCARABS\nHeroSkillLocustSwarm=1,heroskillcode,'AUls',WESTRING_HEROSKILL_LOCUSTSWARM\n// Undead Death Knight\nHeroSkillDeathCoil=0,heroskillcode,'AUdc',WESTRING_HEROSKILL_DEATHCOIL\nHeroSkillDeathPact=0,heroskillcode,'AUdp',WESTRING_HEROSKILL_DEATHPACT\nHeroSkillUnholyAura=0,heroskillcode,'AUau',WESTRING_HEROSKILL_UNHOLYAURA\nHeroSkillAnimateDead=0,heroskillcode,'AUan',WESTRING_HEROSKILL_ANIMATEDEAD\n// Undead Dread Lord\nHeroSkillCarrionSwarm=0,heroskillcode,'AUcs',WESTRING_HEROSKILL_CARRIONSWARM\nHeroSkillSleep=0,heroskillcode,'AUsl',WESTRING_HEROSKILL_SLEEP\nHeroSkillVampiricAura=0,heroskillcode,'AUav',WESTRING_HEROSKILL_VAMPIRICAURA\nHeroSkillDarkSummoning=0,heroskillcode,'AUin',WESTRING_HEROSKILL_DARKSUMMONING\n// Undead Lich\nHeroSkillFrostNova=0,heroskillcode,'AUfn',WESTRING_HEROSKILL_FROSTNOVA\nHeroSkillFrostArmor=0,heroskillcode,'AUfa',WESTRING_HEROSKILL_FROSTARMOR\nHeroSkillDarkRitual=0,heroskillcode,'AUdr',WESTRING_HEROSKILL_DARKRITUAL\nHeroSkillDeathAndDecay=0,heroskillcode,'AUdd',WESTRING_HEROSKILL_DEATHANDDECAY\n// Night Elf Demon Hunter\nHeroSkillManaBurn=0,heroskillcode,'AEmb',WESTRING_HEROSKILL_MANABURN\nHeroSkillImmolation=0,heroskillcode,'AEim',WESTRING_HEROSKILL_IMMOLATION\nHeroSkillEvasion=0,heroskillcode,'AEev',WESTRING_HEROSKILL_EVASION\nHeroSkillMetamorphosis=0,heroskillcode,'AEme',WESTRING_HEROSKILL_METAMORPHOSIS\n// Night Elf Keeper of the Grove\nHeroSkillEntanglingRoots=0,heroskillcode,'AEer',WESTRING_HEROSKILL_ENTANGLINGROOTS\nHeroSkillForceOfNature=0,heroskillcode,'AEfn',WESTRING_HEROSKILL_FORCEOFNATURE\nHeroSkillThornsAura=0,heroskillcode,'AEah',WESTRING_HEROSKILL_THORNSAURA\nHeroSkillTranquility=0,heroskillcode,'AEtq',WESTRING_HEROSKILL_TRANQUILITY\n// Night Elf Priestess of the Moon\nHeroSkillScout=0,heroskillcode,'AEst',WESTRING_HEROSKILL_SCOUT\nHeroSkillSearingArrows=0,heroskillcode,'AHfa',WESTRING_HEROSKILL_SEARINGARROWS\nHeroSkillTrueshotAura=0,heroskillcode,'AEar',WESTRING_HEROSKILL_TRUESHOTAURA\nHeroSkillStarfall=0,heroskillcode,'AEsf',WESTRING_HEROSKILL_STARFALL\n// Night Elf Warden\nHeroSkillFanOfKnives=1,heroskillcode,'AEfk',WESTRING_HEROSKILL_FANOFKNIVES\nHeroSkillBlink=1,heroskillcode,'AEbl',WESTRING_HEROSKILL_BLINK\nHeroSkillShadowTouch=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_SHADOWTOUCH\nHeroSkillSpiritOfVengeance=1,heroskillcode,'AEsv',WESTRING_HEROSKILL_SPIRITOFVENGEANCE\n// Neutral Beast Master\nHeroSkillGrizzly=1,heroskillcode,'ANsg',WESTRING_HEROSKILL_GRIZZLY\nHeroSkillQuillbeast=1,heroskillcode,'ANsq',WESTRING_HEROSKILL_QUILLBEAST\nHeroSkillWarEagle=1,heroskillcode,'ANsw',WESTRING_HEROSKILL_WAREAGLE\nHeroSkillStampede=1,heroskillcode,'ANst',WESTRING_HEROSKILL_STAMPEDE\n// Neutral Dark Ranger\nHeroSkillSilence=1,heroskillcode,'ANsi',WESTRING_HEROSKILL_SILENCE\nHeroSkillBlackArrow=1,heroskillcode,'ANba',WESTRING_HEROSKILL_BLACKARROW\nHeroSkillLifeDrain=1,heroskillcode,'ANdr',WESTRING_HEROSKILL_LIFEDRAIN\nHeroSkillCharm=1,heroskillcode,'ANch',WESTRING_HEROSKILL_CHARM\n// Neutral Naga Sea Witch\nHeroSkillForkedLightning=1,heroskillcode,'ANfl',WESTRING_HEROSKILL_FORKEDLIGHTNING\nHeroSkillColdArrow=1,heroskillcode,'ANfa',WESTRING_HEROSKILL_COLDARROW\nHeroSkillManaShield=1,heroskillcode,'ANms',WESTRING_HEROSKILL_MANASHIELD\nHeroSkillTornado=1,heroskillcode,'ANto',WESTRING_HEROSKILL_TORNADO\n// Neutral Pandaren Brewmaster\nHeroSkillBreathOfFire=1,heroskillcode,'ANbf',WESTRING_HEROSKILL_BREATHOFFIRE\nHeroSkillStrongDrink=1,heroskillcode,'ANdh',WESTRING_HEROSKILL_STRONGDRINK\nHeroSkillDrunkenBrawler=1,heroskillcode,'ANdb',WESTRING_HEROSKILL_DRUNKENBRAWLER\nHeroSkillElementalFury=1,heroskillcode,'ANef',WESTRING_HEROSKILL_ELEMENTALFURY\n// Neutral Pit Lord\nHeroSkillRainOfFire=1,heroskillcode,'ANrf',WESTRING_HEROSKILL_RAINOFFIRE\nHeroSkillHowlOfTerror=1,heroskillcode,'ANht',WESTRING_HEROSKILL_HOWLOFTERROR\nHeroSkillCleavingAttack=1,heroskillcode,'ANca',WESTRING_HEROSKILL_CLEAVINGATTACK\nHeroSkillDoom=1,heroskillcode,'ANdo',WESTRING_HEROSKILL_DOOM\n// Neutral Alchemist\nHeroSkillAcidBomb=1,heroskillcode,'ANab',WESTRING_HEROSKILL_ACIDBOMB\nHeroSkillChemicalRage=1,heroskillcode,'ANcr',WESTRING_HEROSKILL_CHEMICALRAGE\nHeroSkillHealingSpray=1,heroskillcode,'ANhs',WESTRING_HEROSKILL_HEALINGSPRAY\nHeroSkillTransmute=1,heroskillcode,'ANtm',WESTRING_HEROSKILL_TRANSMUTE\n// Neutral Tinker\nHeroSkillEngineeringUpgrade=1,heroskillcode,'ANeg',WESTRING_HEROSKILL_ENGINEERINGUPGRADE\nHeroSkillClusterRockets=1,heroskillcode,'ANcs',WESTRING_HEROSKILL_CLUSTERROCKETS\nHeroSkillSummonFactory=1,heroskillcode,'ANsy',WESTRING_HEROSKILL_SUMMONFACTORY\nHeroSkillRoboGoblin=1,heroskillcode,'ANrg',WESTRING_HEROSKILL_ROBOGOBLIN\n// Neutral Fire Lord\nHeroSkillIncinerate=1,heroskillcode,'ANic',WESTRING_HEROSKILL_INCINERATE\nHeroSkillIncinerateArrow=1,heroskillcode,'ANia',WESTRING_HEROSKILL_INCINERATEARROW\nHeroSkillSoulBurn=1,heroskillcode,'ANso',WESTRING_HEROSKILL_SOULBURN\nHeroSkillLavaMonster=1,heroskillcode,'ANlm',WESTRING_HEROSKILL_LAVAMONSTER\nHeroSkillVolcano=1,heroskillcode,'ANvc',WESTRING_HEROSKILL_VOLCANO\n// Special Akama\nHeroSkillChainLightning2=1,heroskillcode,'AOcl',WESTRING_HEROSKILL_AKAMA_CHAINLIGHTNING\nHeroSkillSpiritBeast=1,heroskillcode,'ACs7',WESTRING_HEROSKILL_AKAMA_FERALSPIRIT\nHeroSkillShadowTouch2=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_AKAMA_SHADOWTOUCH\nHeroSkillReincarnation2=1,heroskillcode,'ANr2',WESTRING_HEROSKILL_AKAMA_REINCARNATION\n// Special Archimonde\nHeroSkillDarkPortal=0,heroskillcode,'ANdp',WESTRING_HEROSKILL_DARKPORTAL\nHeroSkillRainOfChaos=0,heroskillcode,'ANrc',WESTRING_HEROSKILL_RAINOFCHAOS\nHeroSkillArchiBash=0,heroskillcode,'AHah',WESTRING_HEROSKILL_ARCHIBASH\nHeroSkillFingerOfDeath=0,heroskillcode,'ANfd',WESTRING_HEROSKILL_FINGEROFDEATH\n// Special Balnazar\nHeroSkillBalnaSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_BALNA_SLEEP\nHeroSkillBalnaVampiricAura=1,heroskillcode,'AUav',WESTRING_HEROSKILL_BALNA_VAMPIRICAURA\nHeroSkillBalnaRainOfChaos=1,heroskillcode,'ANr3',WESTRING_HEROSKILL_BALNA_RAINOFCHAOS\nHeroSkillBalnaFingerOfPain=1,heroskillcode,'ACf3',WESTRING_HEROSKILL_BALNA_FINGEROFPAIN\nHeroSkillBalnaEarthquake=1,heroskillcode,'AOeq',WESTRING_HEROSKILL_BALNA_EARTHQUAKE\n// Special Chen\nHeroSkillChenBreathOfFire=1,heroskillcode,'ANcf',WESTRING_HEROSKILL_CHEN_BREATHOFFIRE\nHeroSkillChenStrongDrink=1,heroskillcode,'Acdh',WESTRING_HEROSKILL_CHEN_STRONGDRINK\nHeroSkillChenDrunkenBrawler=1,heroskillcode,'Acdb',WESTRING_HEROSKILL_CHEN_DRUNKENBRAWLER\nHeroSkillChenElementalFury=1,heroskillcode,'Acef',WESTRING_HEROSKILL_CHEN_ELEMENTALFURY\nHeroSkillChenAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_CHEN_ATTRIBUTEBONUS\n// Special Detheroc\nHeroSkillDetheSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_DETHE_SLEEP\nHeroSkillDetheShadowTouch=1,heroskillcode,'AEsh',WESTRING_HEROSKILL_DETHE_SHADOWTOUCH\nHeroSkillDetheCarrionSwarm=1,heroskillcode,'AUcs',WESTRING_HEROSKILL_DETHE_CARRIONSWARM\nHeroSkillDetheDeathAndDecay=1,heroskillcode,'AUdd',WESTRING_HEROSKILL_DETHE_DEATHANDDECAY\n// Special Garithos\nHeroSkillGaritShockwave=1,heroskillcode,'ANsh',WESTRING_HEROSKILL_GARIT_SHOCKWAVE\nHeroSkillGaritHolyLight=1,heroskillcode,'AHhb',WESTRING_HEROSKILL_GARIT_HOLYLIGHT\nHeroSkillGaritDevotionAura=1,heroskillcode,'AHad',WESTRING_HEROSKILL_GARIT_DEVOTIONAURA\nHeroSkillGaritAvatar=1,heroskillcode,'ANav',WESTRING_HEROSKILL_GARIT_AVATAR\n// Special Illidan\nHeroSkillIllimorphosis=0,heroskillcode,'AEIl',WESTRING_HEROSKILL_ILLIMORPHOSIS\nHeroSkillEvilIllimorphosis=0,heroskillcode,'AEvi',WESTRING_HEROSKILL_EVILILLIMORPHOSIS\n// Special Malganis\nHeroSkillMalganisSleep=0,heroskillcode,'ANdc',WESTRING_HEROSKILL_DARKCONVERSION\nHeroSkillSoulPreservation=0,heroskillcode,'ANsl',WESTRING_HEROSKILL_SOULPRESERVATION\n// Special Manaroth\nHeroSkillManarothReincarnation=0,heroskillcode,'ANrn',WESTRING_HEROSKILL_MANAROTHREINCARNATION\n// Special Rexxar\nHeroSkillRexxarGrizzly=1,heroskillcode,'Arsg',WESTRING_HEROSKILL_REXXAR_GRIZZLY\nHeroSkillRexxarQuillbeast=1,heroskillcode,'Arsq',WESTRING_HEROSKILL_REXXAR_QUILLBEAST\nHeroSkillRexxarStormBolt=1,heroskillcode,'ANsb',WESTRING_HEROSKILL_REXXAR_STORMBOLT\nHeroSkillRexxarStampede=1,heroskillcode,'Arsp',WESTRING_HEROSKILL_REXXAR_STAMPEDE\nHeroSkillRexxarAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_REXXAR_ATTRIBUTEBONUS\n// Special Rokhan\nHeroSkillRokhanHealingWave=1,heroskillcode,'ANhw',WESTRING_HEROSKILL_ROKHAN_HEALINGWAVE\nHeroSkillRokhanHex=1,heroskillcode,'ANhx',WESTRING_HEROSKILL_ROKHAN_HEX\nHeroSkillRokhanSerpentWard=1,heroskillcode,'Arsw',WESTRING_HEROSKILL_ROKHAN_SERPENTWARD\nHeroSkillRokhanVoodooSpirits=1,heroskillcode,'AOls',WESTRING_HEROSKILL_ROKHAN_VOODOOSPIRITS\nHeroSkillRokhanAttributeBonus=1,heroskillcode,'Aamk',WESTRING_HEROSKILL_ROKHAN_ATTRIBUTEBONUS\n// Special Sylvanas Windrunner\nHeroSkillColdArrows=0,heroskillcode,'AHca',WESTRING_HEROSKILL_COLDARROWS\n// Special Tichondrius\nHeroSkillTichondriusInferno=0,heroskillcode,'SNin',WESTRING_HEROSKILL_TICHONDRIUSINFERNO\n// Special Varimathras\nHeroSkillVarimSleep=1,heroskillcode,'AUsl',WESTRING_HEROSKILL_VARIM_SLEEP\nHeroSkillVarimVampiricAura=1,heroskillcode,'AUav',WESTRING_HEROSKILL_VARIM_VAMPIRICAURA\nHeroSkillVarimRainOfFire=1,heroskillcode,'ANrf',WESTRING_HEROSKILL_VARIM_RAINOFFIRE\nHeroSkillVarimDoom=1,heroskillcode,'ANdo',WESTRING_HEROSKILL_VARIM_DOOM\n// Special Warlock\nHeroSkillInfernal=0,heroskillcode,'ANin',WESTRING_HEROSKILL_INFERNAL\n// Special Miscellaneous\nHeroSkillMalganisSleepFast=0,heroskillcode,'SNdc',WESTRING_HEROSKILL_DARKCONVERSIONFAST\nHeroSkillDarkSummoningOld=0,heroskillcode,'AUds',WESTRING_HEROSKILL_DARKSUMMONINGOLD\n\n// Weather Effects\nWeatherAshenvaleHeavyRain=0,weathereffectcode,'RAhr',WESTRING_WEATHER_ASHENVALEHEAVYRAIN\nWeatherAshenvaleLightRain=0,weathereffectcode,'RAlr',WESTRING_WEATHER_ASHENVALELIGHTRAIN\nWeatherDalaranShield=0,weathereffectcode,'MEds',WESTRING_WEATHER_DALARANSHIELD\nWeatherDungeonHeavyBlueFog=0,weathereffectcode,'FDbh',WESTRING_WEATHER_DUNGEONHEAVYBLUEFOG\nWeatherDungeonLightBlueFog=0,weathereffectcode,'FDbl',WESTRING_WEATHER_DUNGEONBLUEFOG\nWeatherDungeonHeavyGreenFog=0,weathereffectcode,'FDgh',WESTRING_WEATHER_DUNGEONHEAVYGREENFOG\nWeatherDungeonLightGreenFog=0,weathereffectcode,'FDgl',WESTRING_WEATHER_DUNGEONGREENFOG\nWeatherDungeonHeavyRedFog=0,weathereffectcode,'FDrh',WESTRING_WEATHER_DUNGEONHEAVYREDFOG\nWeatherDungeonLightRedFog=0,weathereffectcode,'FDrl',WESTRING_WEATHER_DUNGEONREDFOG\nWeatherDungeonHeavyWhiteFog=0,weathereffectcode,'FDwh',WESTRING_WEATHER_DUNGEONHEAVYWHITEFOG\nWeatherDungeonLightWhiteFog=0,weathereffectcode,'FDwl',WESTRING_WEATHER_DUNGEONWHITEFOG\nWeatherLordaeronHeavyRain=0,weathereffectcode,'RLhr',WESTRING_WEATHER_LORDAERONHEAVYRAIN\nWeatherLordaeronLightRain=0,weathereffectcode,'RLlr',WESTRING_WEATHER_LORDAERONLIGHTRAIN\nWeatherNorthrendBlizzard=0,weathereffectcode,'SNbs',WESTRING_WEATHER_NORTHRENDBLIZZARD\nWeatherNorthrendHeavySnow=0,weathereffectcode,'SNhs',WESTRING_WEATHER_NORTHRENDHEAVYSNOW\nWeatherNorthrendLightSnow=0,weathereffectcode,'SNls',WESTRING_WEATHER_NORTHRENDLIGHTSNOW\nWeatherOutlandWind=1,weathereffectcode,'WOcw',WESTRING_WEATHER_OUTLANDWIND\nWeatherOutlandWindLight=1,weathereffectcode,'WOlw',WESTRING_WEATHER_OUTLANDWINDLIGHT\nWeatherRaysOfLight=0,weathereffectcode,'LRaa',WESTRING_WEATHER_RAYSOFLIGHT\nWeatherRaysOfMoonlight=0,weathereffectcode,'LRma',WESTRING_WEATHER_RAYSOFMOONLIGHT\nWeatherHeavyWind=0,weathereffectcode,'WNcw',WESTRING_WEATHER_WIND\n\n// Tile IDs\nTerrainTypeLdrt=1,terraintype,'Ldrt',WESTRING_TERRAINTYPE_Ldrt\nTerrainTypeLdro=1,terraintype,'Ldro',WESTRING_TERRAINTYPE_Ldro\nTerrainTypeLdrg=1,terraintype,'Ldrg',WESTRING_TERRAINTYPE_Ldrg\nTerrainTypeLrok=1,terraintype,'Lrok',WESTRING_TERRAINTYPE_Lrok\nTerrainTypeLgrs=1,terraintype,'Lgrs',WESTRING_TERRAINTYPE_Lgrs\nTerrainTypeLgrd=1,terraintype,'Lgrd',WESTRING_TERRAINTYPE_Lgrd\nTerrainTypeFdrt=1,terraintype,'Fdrt',WESTRING_TERRAINTYPE_Fdrt\nTerrainTypeFdro=1,terraintype,'Fdro',WESTRING_TERRAINTYPE_Fdro\nTerrainTypeFdrg=1,terraintype,'Fdrg',WESTRING_TERRAINTYPE_Fdrg\nTerrainTypeFrok=1,terraintype,'Frok',WESTRING_TERRAINTYPE_Frok\nTerrainTypeFgrs=1,terraintype,'Fgrs',WESTRING_TERRAINTYPE_Fgrs\nTerrainTypeFgrd=1,terraintype,'Fgrd',WESTRING_TERRAINTYPE_Fgrd\nTerrainTypeWdrt=1,terraintype,'Wdrt',WESTRING_TERRAINTYPE_Wdrt\nTerrainTypeWdro=1,terraintype,'Wdro',WESTRING_TERRAINTYPE_Wdro\nTerrainTypeWsng=1,terraintype,'Wsng',WESTRING_TERRAINTYPE_Wsng\nTerrainTypeWrok=1,terraintype,'Wrok',WESTRING_TERRAINTYPE_Wrok\nTerrainTypeWgrs=1,terraintype,'Wgrs',WESTRING_TERRAINTYPE_Wgrs\nTerrainTypeWsnw=1,terraintype,'Wsnw',WESTRING_TERRAINTYPE_Wsnw\nTerrainTypeBdrt=1,terraintype,'Bdrt',WESTRING_TERRAINTYPE_Bdrt\nTerrainTypeBdrh=1,terraintype,'Bdrh',WESTRING_TERRAINTYPE_Bdrh\nTerrainTypeBdrr=1,terraintype,'Bdrr',WESTRING_TERRAINTYPE_Bdrr\nTerrainTypeBdrg=1,terraintype,'Bdrg',WESTRING_TERRAINTYPE_Bdrg\nTerrainTypeBdsr=1,terraintype,'Bdsr',WESTRING_TERRAINTYPE_Bdsr\nTerrainTypeBdsd=1,terraintype,'Bdsd',WESTRING_TERRAINTYPE_Bdsd\nTerrainTypeBflr=1,terraintype,'Bflr',WESTRING_TERRAINTYPE_Bflr\nTerrainTypeBgrr=1,terraintype,'Bgrr',WESTRING_TERRAINTYPE_Bgrr\nTerrainTypeAdrt=1,terraintype,'Adrt',WESTRING_TERRAINTYPE_Adrt\nTerrainTypeAdrd=1,terraintype,'Adrd',WESTRING_TERRAINTYPE_Adrd\nTerrainTypeAgrs=1,terraintype,'Agrs',WESTRING_TERRAINTYPE_Agrs\nTerrainTypeArck=1,terraintype,'Arck',WESTRING_TERRAINTYPE_Arck\nTerrainTypeAgrd=1,terraintype,'Agrd',WESTRING_TERRAINTYPE_Agrd\nTerrainTypeAvin=1,terraintype,'Avin',WESTRING_TERRAINTYPE_Avin\nTerrainTypeAdrg=1,terraintype,'Adrg',WESTRING_TERRAINTYPE_Adrg\nTerrainTypeAlvd=1,terraintype,'Alvd',WESTRING_TERRAINTYPE_Alvd\nTerrainTypeCdrt=1,terraintype,'Cdrt',WESTRING_TERRAINTYPE_Cdrt\nTerrainTypeCdrd=1,terraintype,'Cdrd',WESTRING_TERRAINTYPE_Cdrd\nTerrainTypeCpos=1,terraintype,'Cpos',WESTRING_TERRAINTYPE_Cpos\nTerrainTypeCrck=1,terraintype,'Crck',WESTRING_TERRAINTYPE_Crck\nTerrainTypeCvin=1,terraintype,'Cvin',WESTRING_TERRAINTYPE_Cvin\nTerrainTypeCgrs=1,terraintype,'Cgrs',WESTRING_TERRAINTYPE_Cgrs\nTerrainTypeClvg=1,terraintype,'Clvg',WESTRING_TERRAINTYPE_Clvg\nTerrainTypeNdrt=1,terraintype,'Ndrt',WESTRING_TERRAINTYPE_Ndrt\nTerrainTypeNdrd=1,terraintype,'Ndrd',WESTRING_TERRAINTYPE_Ndrd\nTerrainTypeNrck=1,terraintype,'Nrck',WESTRING_TERRAINTYPE_Nrck\nTerrainTypeNgrs=1,terraintype,'Ngrs',WESTRING_TERRAINTYPE_Ngrs\nTerrainTypeNice=1,terraintype,'Nice',WESTRING_TERRAINTYPE_Nice\nTerrainTypeNsnw=1,terraintype,'Nsnw',WESTRING_TERRAINTYPE_Nsnw\nTerrainTypeNsnr=1,terraintype,'Nsnr',WESTRING_TERRAINTYPE_Nsnr\nTerrainTypeYdrt=1,terraintype,'Ydrt',WESTRING_TERRAINTYPE_Ydrt\nTerrainTypeYdtr=1,terraintype,'Ydtr',WESTRING_TERRAINTYPE_Ydtr\nTerrainTypeYblm=1,terraintype,'Yblm',WESTRING_TERRAINTYPE_Yblm\nTerrainTypeYbtl=1,terraintype,'Ybtl',WESTRING_TERRAINTYPE_Ybtl\nTerrainTypeYsqd=1,terraintype,'Ysqd',WESTRING_TERRAINTYPE_Ysqd\nTerrainTypeYrtl=1,terraintype,'Yrtl',WESTRING_TERRAINTYPE_Yrtl\nTerrainTypeYgsb=1,terraintype,'Ygsb',WESTRING_TERRAINTYPE_Ygsb\nTerrainTypeYhdg=1,terraintype,'Yhdg',WESTRING_TERRAINTYPE_Yhdg\nTerrainTypeYwmb=1,terraintype,'Ywmb',WESTRING_TERRAINTYPE_Ywmb\nTerrainTypeVdrt=1,terraintype,'Vdrt',WESTRING_TERRAINTYPE_Vdrt\nTerrainTypeVdrr=1,terraintype,'Vdrr',WESTRING_TERRAINTYPE_Vdrr\nTerrainTypeVcrp=1,terraintype,'Vcrp',WESTRING_TERRAINTYPE_Vcrp\nTerrainTypeVcbp=1,terraintype,'Vcbp',WESTRING_TERRAINTYPE_Vcbp\nTerrainTypeVstp=1,terraintype,'Vstp',WESTRING_TERRAINTYPE_Vstp\nTerrainTypeVgrs=1,terraintype,'Vgrs',WESTRING_TERRAINTYPE_Vgrs\nTerrainTypeVrck=1,terraintype,'Vrck',WESTRING_TERRAINTYPE_Vrck\nTerrainTypeVgrt=1,terraintype,'Vgrt',WESTRING_TERRAINTYPE_Vgrt\nTerrainTypeQdrt=1,terraintype,'Qdrt',WESTRING_TERRAINTYPE_Qdrt\nTerrainTypeQdrr=1,terraintype,'Qdrr',WESTRING_TERRAINTYPE_Qdrr\nTerrainTypeQcrp=1,terraintype,'Qcrp',WESTRING_TERRAINTYPE_Qcrp\nTerrainTypeQcbp=1,terraintype,'Qcbp',WESTRING_TERRAINTYPE_Qcbp\nTerrainTypeQstp=1,terraintype,'Qstp',WESTRING_TERRAINTYPE_Qstp\nTerrainTypeQgrs=1,terraintype,'Qgrs',WESTRING_TERRAINTYPE_Qgrs\nTerrainTypeQrck=1,terraintype,'Qrck',WESTRING_TERRAINTYPE_Qrck\nTerrainTypeQgrt=1,terraintype,'Qgrt',WESTRING_TERRAINTYPE_Qgrt\nTerrainTypeXdrt=1,terraintype,'Xdrt',WESTRING_TERRAINTYPE_Xdrt\nTerrainTypeXdtr=1,terraintype,'Xdtr',WESTRING_TERRAINTYPE_Xdtr\nTerrainTypeXblm=1,terraintype,'Xblm',WESTRING_TERRAINTYPE_Xblm\nTerrainTypeXbtl=1,terraintype,'Xbtl',WESTRING_TERRAINTYPE_Xbtl\nTerrainTypeXsqd=1,terraintype,'Xsqd',WESTRING_TERRAINTYPE_Xsqd\nTerrainTypeXrtl=1,terraintype,'Xrtl',WESTRING_TERRAINTYPE_Xrtl\nTerrainTypeXgsb=1,terraintype,'Xgsb',WESTRING_TERRAINTYPE_Xgsb\nTerrainTypeXhdg=1,terraintype,'Xhdg',WESTRING_TERRAINTYPE_Xhdg\nTerrainTypeXwmb=1,terraintype,'Xwmb',WESTRING_TERRAINTYPE_Xwmb\nTerrainTypeDdrt=1,terraintype,'Ddrt',WESTRING_TERRAINTYPE_Ddrt\nTerrainTypeDbrk=1,terraintype,'Dbrk',WESTRING_TERRAINTYPE_Dbrk\nTerrainTypeDrds=1,terraintype,'Drds',WESTRING_TERRAINTYPE_Drds\nTerrainTypeDlvc=1,terraintype,'Dlvc',WESTRING_TERRAINTYPE_Dlvc\nTerrainTypeDlav=1,terraintype,'Dlav',WESTRING_TERRAINTYPE_Dlav\nTerrainTypeDdkr=1,terraintype,'Ddkr',WESTRING_TERRAINTYPE_Ddkr\nTerrainTypeDgrs=1,terraintype,'Dgrs',WESTRING_TERRAINTYPE_Dgrs\nTerrainTypeDsqd=1,terraintype,'Dsqd',WESTRING_TERRAINTYPE_Dsqd\nTerrainTypeGdrt=1,terraintype,'Gdrt',WESTRING_TERRAINTYPE_Gdrt\nTerrainTypeGbrk=1,terraintype,'Gbrk',WESTRING_TERRAINTYPE_Gbrk\nTerrainTypeGrds=1,terraintype,'Grds',WESTRING_TERRAINTYPE_Grds\nTerrainTypeGlvc=1,terraintype,'Glvc',WESTRING_TERRAINTYPE_Glvc\nTerrainTypeGlav=1,terraintype,'Glav',WESTRING_TERRAINTYPE_Glav\nTerrainTypeGdkr=1,terraintype,'Gdkr',WESTRING_TERRAINTYPE_Gdkr\nTerrainTypeGgrs=1,terraintype,'Ggrs',WESTRING_TERRAINTYPE_Ggrs\nTerrainTypeGsqd=1,terraintype,'Gsqd',WESTRING_TERRAINTYPE_Gsqd\nTerrainTypeZdrt=1,terraintype,'Zdrt',WESTRING_TERRAINTYPE_Zdrt\nTerrainTypeZdtr=1,terraintype,'Zdtr',WESTRING_TERRAINTYPE_Zdtr\nTerrainTypeZdrg=1,terraintype,'Zdrg',WESTRING_TERRAINTYPE_Zdrg\nTerrainTypeZbks=1,terraintype,'Zbks',WESTRING_TERRAINTYPE_Zbks\nTerrainTypeZsan=1,terraintype,'Zsan',WESTRING_TERRAINTYPE_Zsan\nTerrainTypeZbkl=1,terraintype,'Zbkl',WESTRING_TERRAINTYPE_Zbkl\nTerrainTypeZtil=1,terraintype,'Ztil',WESTRING_TERRAINTYPE_Ztil\nTerrainTypeZgrs=1,terraintype,'Zgrs',WESTRING_TERRAINTYPE_Zgrs\nTerrainTypeZvin=1,terraintype,'Zvin',WESTRING_TERRAINTYPE_Zvin\nTerrainTypeIdrt=1,terraintype,'Idrt',WESTRING_TERRAINTYPE_Idrt\nTerrainTypeIdtr=1,terraintype,'Idtr',WESTRING_TERRAINTYPE_Idtr\nTerrainTypeIdki=1,terraintype,'Idki',WESTRING_TERRAINTYPE_Idki\nTerrainTypeIbkb=1,terraintype,'Ibkb',WESTRING_TERRAINTYPE_Ibkb\nTerrainTypeIrbk=1,terraintype,'Irbk',WESTRING_TERRAINTYPE_Irbk\nTerrainTypeItbk=1,terraintype,'Itbk',WESTRING_TERRAINTYPE_Itbk\nTerrainTypeIice=1,terraintype,'Iice',WESTRING_TERRAINTYPE_Iice\nTerrainTypeIbsq=1,terraintype,'Ibsq',WESTRING_TERRAINTYPE_Ibsq\nTerrainTypeIsnw=1,terraintype,'Isnw',WESTRING_TERRAINTYPE_Isnw\nTerrainTypeOdrt=1,terraintype,'Odrt',WESTRING_TERRAINTYPE_Odrt\nTerrainTypeOdtr=1,terraintype,'Odtr',WESTRING_TERRAINTYPE_Odtr\nTerrainTypeOsmb=1,terraintype,'Osmb',WESTRING_TERRAINTYPE_Osmb\nTerrainTypeOfst=1,terraintype,'Ofst',WESTRING_TERRAINTYPE_Ofst\nTerrainTypeOlgb=1,terraintype,'Olgb',WESTRING_TERRAINTYPE_Olgb\nTerrainTypeOrok=1,terraintype,'Orok',WESTRING_TERRAINTYPE_Orok\nTerrainTypeOfsl=1,terraintype,'Ofsl',WESTRING_TERRAINTYPE_Ofsl\nTerrainTypeOaby=1,terraintype,'Oaby',WESTRING_TERRAINTYPE_Oaby\nTerrainTypeKdrt=1,terraintype,'Kdrt',WESTRING_TERRAINTYPE_Kdrt\nTerrainTypeKfsl=1,terraintype,'Kfsl',WESTRING_TERRAINTYPE_Kfsl\nTerrainTypeKdtr=1,terraintype,'Kdtr',WESTRING_TERRAINTYPE_Kdtr\nTerrainTypeKfst=1,terraintype,'Kfst',WESTRING_TERRAINTYPE_Kfst\nTerrainTypeKsmb=1,terraintype,'Ksmb',WESTRING_TERRAINTYPE_Ksmb\nTerrainTypeKlgb=1,terraintype,'Klgb',WESTRING_TERRAINTYPE_Klgb\nTerrainTypeKsqt=1,terraintype,'Ksqt',WESTRING_TERRAINTYPE_Ksqt\nTerrainTypeKdkt=1,terraintype,'Kdkt',WESTRING_TERRAINTYPE_Kdkt\nTerrainTypeJdrt=1,terraintype,'Jdrt',WESTRING_TERRAINTYPE_Jdrt\nTerrainTypeJdtr=1,terraintype,'Jdtr',WESTRING_TERRAINTYPE_Jdtr\nTerrainTypeJblm=1,terraintype,'Jblm',WESTRING_TERRAINTYPE_Jblm\nTerrainTypeJbtl=1,terraintype,'Jbtl',WESTRING_TERRAINTYPE_Jbtl\nTerrainTypeJsqd=1,terraintype,'Jsqd',WESTRING_TERRAINTYPE_Jsqd\nTerrainTypeJrtl=1,terraintype,'Jrtl',WESTRING_TERRAINTYPE_Jrtl\nTerrainTypeJgsb=1,terraintype,'Jgsb',WESTRING_TERRAINTYPE_Jgsb\nTerrainTypeJhdg=1,terraintype,'Jhdg',WESTRING_TERRAINTYPE_Jhdg\nTerrainTypeJwmb=1,terraintype,'Jwmb',WESTRING_TERRAINTYPE_Jwmb\nTerrainTypecAc2=1,terraintype,'cAc2',WESTRING_TERRAINTYPE_cAc2\nTerrainTypecAc1=1,terraintype,'cAc1',WESTRING_TERRAINTYPE_cAc1\nTerrainTypecBc2=1,terraintype,'cBc2',WESTRING_TERRAINTYPE_cBc2\nTerrainTypecBc1=1,terraintype,'cBc1',WESTRING_TERRAINTYPE_cBc1\nTerrainTypecKc1=1,terraintype,'cKc1',WESTRING_TERRAINTYPE_cKc1\nTerrainTypecKc2=1,terraintype,'cKc2',WESTRING_TERRAINTYPE_cKc2\nTerrainTypecYc2=1,terraintype,'cYc2',WESTRING_TERRAINTYPE_cYc2\nTerrainTypecYc1=1,terraintype,'cYc1',WESTRING_TERRAINTYPE_cYc1\nTerrainTypecXc2=1,terraintype,'cXc2',WESTRING_TERRAINTYPE_cXc2\nTerrainTypecXc1=1,terraintype,'cXc1',WESTRING_TERRAINTYPE_cXc1\nTerrainTypecJc2=1,terraintype,'cJc2',WESTRING_TERRAINTYPE_cJc2\nTerrainTypecJc1=1,terraintype,'cJc1',WESTRING_TERRAINTYPE_cJc1\nTerrainTypecDc2=1,terraintype,'cDc2',WESTRING_TERRAINTYPE_cDc2\nTerrainTypecDc1=1,terraintype,'cDc1',WESTRING_TERRAINTYPE_cDc1\nTerrainTypecCc2=1,terraintype,'cCc2',WESTRING_TERRAINTYPE_cCc2\nTerrainTypecCc1=1,terraintype,'cCc1',WESTRING_TERRAINTYPE_cCc1\nTerrainTypecIc2=1,terraintype,'cIc2',WESTRING_TERRAINTYPE_cIc2\nTerrainTypecIc1=1,terraintype,'cIc1',WESTRING_TERRAINTYPE_cIc1\nTerrainTypecFc2=1,terraintype,'cFc2',WESTRING_TERRAINTYPE_cFc2\nTerrainTypecFc1=1,terraintype,'cFc1',WESTRING_TERRAINTYPE_cFc1\nTerrainTypecLc2=1,terraintype,'cLc2',WESTRING_TERRAINTYPE_cLc2\nTerrainTypecLc1=1,terraintype,'cLc1',WESTRING_TERRAINTYPE_cLc1\nTerrainTypecWc2=1,terraintype,'cWc2',WESTRING_TERRAINTYPE_cWc2\nTerrainTypecWc1=1,terraintype,'cWc1',WESTRING_TERRAINTYPE_cWc1\nTerrainTypecNc2=1,terraintype,'cNc2',WESTRING_TERRAINTYPE_cNc2\nTerrainTypecNc1=1,terraintype,'cNc1',WESTRING_TERRAINTYPE_cNc1\nTerrainTypecOc1=1,terraintype,'cOc1',WESTRING_TERRAINTYPE_cOc1\nTerrainTypecOc2=1,terraintype,'cOc2',WESTRING_TERRAINTYPE_cOc2\nTerrainTypecZc2=1,terraintype,'cZc2',WESTRING_TERRAINTYPE_cZc2\nTerrainTypecZc1=1,terraintype,'cZc1',WESTRING_TERRAINTYPE_cZc1\nTerrainTypecGc2=1,terraintype,'cGc2',WESTRING_TERRAINTYPE_cGc2\nTerrainTypecGc1=1,terraintype,'cGc1',WESTRING_TERRAINTYPE_cGc1\nTerrainTypecVc2=1,terraintype,'cVc2',WESTRING_TERRAINTYPE_cVc2\nTerrainTypecVc1=1,terraintype,'cVc1',WESTRING_TERRAINTYPE_cVc1\nTerrainTypecQc2=1,terraintype,'cQc2',WESTRING_TERRAINTYPE_cQc2\nTerrainTypecQc1=1,terraintype,'cQc1',WESTRING_TERRAINTYPE_cQc1\n\n//  Terrain Shapes\nTerrainShapeCircle=1,terrainshape,0,WESTRING_TERRAINSHAPE_CIRCLE\nTerrainShapeSquare=1,terrainshape,1,WESTRING_TERRAINSHAPE_SQUARE\n\n//  Lightning Types\nLightningTypeCLPB=1,lightningtype,`CLPB`,WESTRING_LIGHTNINGTYPE_CLPB\nLightningTypeCLSB=1,lightningtype,`CLSB`,WESTRING_LIGHTNINGTYPE_CLSB\nLightningTypeDRAB=1,lightningtype,`DRAB`,WESTRING_LIGHTNINGTYPE_DRAB\nLightningTypeDRAL=1,lightningtype,`DRAL`,WESTRING_LIGHTNINGTYPE_DRAL\nLightningTypeDRAM=1,lightningtype,`DRAM`,WESTRING_LIGHTNINGTYPE_DRAM\nLightningTypeAFOD=1,lightningtype,`AFOD`,WESTRING_LIGHTNINGTYPE_AFOD\nLightningTypeFORK=1,lightningtype,`FORK`,WESTRING_LIGHTNINGTYPE_FORK\nLightningTypeHWPB=1,lightningtype,`HWPB`,WESTRING_LIGHTNINGTYPE_HWPB\nLightningTypeHWSB=1,lightningtype,`HWSB`,WESTRING_LIGHTNINGTYPE_HWSB\nLightningTypeCHIM=1,lightningtype,`CHIM`,WESTRING_LIGHTNINGTYPE_CHIM\nLightningTypeLEAS=1,lightningtype,`LEAS`,WESTRING_LIGHTNINGTYPE_LEAS\nLightningTypeMBUR=1,lightningtype,`MBUR`,WESTRING_LIGHTNINGTYPE_MBUR\nLightningTypeMFPB=1,lightningtype,`MFPB`,WESTRING_LIGHTNINGTYPE_MFPB\nLightningTypeSPLK=1,lightningtype,`SPLK`,WESTRING_LIGHTNINGTYPE_SPLK\n\n//  Image types\nImageTypeShadow=1,imagetype,0,WESTRING_IMAGETYPE_SHADOW\nImageTypeSelection=1,imagetype,1,WESTRING_IMAGETYPE_SELECTION\nImageTypeIndicator=1,imagetype,2,WESTRING_IMAGETYPE_INDICATOR\nImageTypeOcclusionMark=1,imagetype,3,WESTRING_IMAGETYPE_OCCLUSIONMARK\nImageTypeUbersplat=1,imagetype,4,WESTRING_IMAGETYPE_UBERSPLAT\nImageTypeLast=1,imagetype,5,WESTRING_IMAGETYPE_LAST\n\n//  Ubersplat codes\nUbersplatTypeTEST=1,ubersplattype,`TEST`,WESTRING_UBERSPLAT_TEST\nUbersplatTypeLSDS=1,ubersplattype,`LSDS`,WESTRING_UBERSPLAT_LSDS\nUbersplatTypeLSDM=1,ubersplattype,`LSDM`,WESTRING_UBERSPLAT_LSDM\nUbersplatTypeLSDL=1,ubersplattype,`LSDL`,WESTRING_UBERSPLAT_LSDL\nUbersplatTypeHCRT=1,ubersplattype,`HCRT`,WESTRING_UBERSPLAT_HCRT\nUbersplatTypeUDSU=1,ubersplattype,`UDSU`,WESTRING_UBERSPLAT_UDSU\nUbersplatTypeDNCS=1,ubersplattype,`DNCS`,WESTRING_UBERSPLAT_DNCS\nUbersplatTypeHMTP=1,ubersplattype,`HMTP`,WESTRING_UBERSPLAT_HMTP\nUbersplatTypeSCTP=1,ubersplattype,`SCTP`,WESTRING_UBERSPLAT_SCTP\nUbersplatTypeAMRC=1,ubersplattype,`AMRC`,WESTRING_UBERSPLAT_AMRC\nUbersplatTypeDRKC=1,ubersplattype,`DRKC`,WESTRING_UBERSPLAT_DRKC\nUbersplatTypeDOSB=1,ubersplattype,`DOSB`,WESTRING_UBERSPLAT_DOSB\nUbersplatTypeDOMB=1,ubersplattype,`DOMB`,WESTRING_UBERSPLAT_DOMB\nUbersplatTypeDOLB=1,ubersplattype,`DOLB`,WESTRING_UBERSPLAT_DOLB\nUbersplatTypeDHSB=1,ubersplattype,`DHSB`,WESTRING_UBERSPLAT_DHSB\nUbersplatTypeDHMB=1,ubersplattype,`DHMB`,WESTRING_UBERSPLAT_DHMB\nUbersplatTypeDHLB=1,ubersplattype,`DHLB`,WESTRING_UBERSPLAT_DHLB\nUbersplatTypeDUSB=1,ubersplattype,`DUSB`,WESTRING_UBERSPLAT_DUSB\nUbersplatTypeDUMB=1,ubersplattype,`DUMB`,WESTRING_UBERSPLAT_DUMB\nUbersplatTypeDULB=1,ubersplattype,`DULB`,WESTRING_UBERSPLAT_DULB\nUbersplatTypeDNSB=1,ubersplattype,`DNSB`,WESTRING_UBERSPLAT_DNSB\nUbersplatTypeDNMB=1,ubersplattype,`DNMB`,WESTRING_UBERSPLAT_DNMB\nUbersplatTypeDNSA=1,ubersplattype,`DNSA`,WESTRING_UBERSPLAT_DNSA\nUbersplatTypeDNMA=1,ubersplattype,`DNMA`,WESTRING_UBERSPLAT_DNMA\nUbersplatTypeHSMA=1,ubersplattype,`HSMA`,WESTRING_UBERSPLAT_HSMA\nUbersplatTypeHMED=1,ubersplattype,`HMED`,WESTRING_UBERSPLAT_HMED\nUbersplatTypeHLAR=1,ubersplattype,`HLAR`,WESTRING_UBERSPLAT_HLAR\nUbersplatTypeOSMA=1,ubersplattype,`OSMA`,WESTRING_UBERSPLAT_OSMA\nUbersplatTypeOMED=1,ubersplattype,`OMED`,WESTRING_UBERSPLAT_OMED\nUbersplatTypeOLAR=1,ubersplattype,`OLAR`,WESTRING_UBERSPLAT_OLAR\nUbersplatTypeUSMA=1,ubersplattype,`USMA`,WESTRING_UBERSPLAT_USMA\nUbersplatTypeUMED=1,ubersplattype,`UMED`,WESTRING_UBERSPLAT_UMED\nUbersplatTypeULAR=1,ubersplattype,`ULAR`,WESTRING_UBERSPLAT_ULAR\nUbersplatTypeESMA=1,ubersplattype,`ESMA`,WESTRING_UBERSPLAT_ESMA\nUbersplatTypeEMDA=1,ubersplattype,`EMDA`,WESTRING_UBERSPLAT_EMDA\nUbersplatTypeESMB=1,ubersplattype,`ESMB`,WESTRING_UBERSPLAT_ESMB\nUbersplatTypeEMDB=1,ubersplattype,`EMDB`,WESTRING_UBERSPLAT_EMDB\nUbersplatTypeHTOW=1,ubersplattype,`HTOW`,WESTRING_UBERSPLAT_HTOW\nUbersplatTypeHCAS=1,ubersplattype,`HCAS`,WESTRING_UBERSPLAT_HCAS\nUbersplatTypeNGOL=1,ubersplattype,`NGOL`,WESTRING_UBERSPLAT_NGOL\nUbersplatTypeTHND=1,ubersplattype,`THND`,WESTRING_UBERSPLAT_THND\nUbersplatTypeNDGS=1,ubersplattype,`NDGS`,WESTRING_UBERSPLAT_NDGS\nUbersplatTypeCLTS=1,ubersplattype,`CLTS`,WESTRING_UBERSPLAT_CLTS\nUbersplatTypeHFS1=1,ubersplattype,`HFS1`,WESTRING_UBERSPLAT_HFS1\nUbersplatTypeHFS2=1,ubersplattype,`HFS2`,WESTRING_UBERSPLAT_HFS2\nUbersplatTypeUSBR=1,ubersplattype,`USBR`,WESTRING_UBERSPLAT_USBR\nUbersplatTypeNLAR=1,ubersplattype,`NLAR`,WESTRING_UBERSPLAT_NLAR\nUbersplatTypeNMED=1,ubersplattype,`NMED`,WESTRING_UBERSPLAT_NMED\nUbersplatTypeDPSW=1,ubersplattype,`DPSW`,WESTRING_UBERSPLAT_DPSW\nUbersplatTypeDPSE=1,ubersplattype,`DPSE`,WESTRING_UBERSPLAT_DPSE\nUbersplatTypeNVOL=1,ubersplattype,`NVOL`,WESTRING_UBERSPLAT_NVOL\nUbersplatTypeNVCR=1,ubersplattype,`NVCR`,WESTRING_UBERSPLAT_NVCR\n\nRacePrefHuman=0,racepreference,RACE_PREF_HUMAN,WESTRING_RACE_HUMAN\nRacePrefOrc=0,racepreference,RACE_PREF_ORC,WESTRING_RACE_ORC\nRacePrefNightElf=0,racepreference,RACE_PREF_NIGHTELF,WESTRING_RACE_NIGHTELF\nRacePrefUndead=0,racepreference,RACE_PREF_UNDEAD,WESTRING_RACE_UNDEAD\nRacePrefRandom=0,racepreference,RACE_PREF_RANDOM,随机\n\n\n\n//===================================================\n// For use with TriggerRegisterGameEvent\n//===================================================\nID_EVENT_GAME_VICTORY=0,eventid,EVENT_GAME_VICTORY,\"(000)游戏事件 - 游戏胜利\"\nID_EVENT_GAME_END_LEVEL=0,eventid,EVENT_GAME_END_LEVEL,\"(001)游戏事件 - 游戏结束\"\nID_EVENT_GAME_VARIABLE_LIMIT=0,eventid,EVENT_GAME_VARIABLE_LIMIT,\"(002)游戏事件 - 变量改变\"\nID_EVENT_GAME_STATE_LIMIT=0,eventid,EVENT_GAME_STATE_LIMIT,\"(003)游戏事件 - 状态改变\"\nID_EVENT_GAME_TIMER_EXPIRED=0,eventid,EVENT_GAME_TIMER_EXPIRED,\"(004)游戏事件 - 计时器到期\"\nID_EVENT_GAME_ENTER_REGION=0,eventid,EVENT_GAME_ENTER_REGION,\"(005)游戏事件 - 进入区域\"\nID_EVENT_GAME_LEAVE_REGION=0,eventid,EVENT_GAME_LEAVE_REGION,\"(006)游戏事件 - 离开区域\"\nID_EVENT_GAME_TRACKABLE_HIT=0,eventid,EVENT_GAME_TRACKABLE_HIT,\"(007)游戏事件 - 鼠标点击可追踪物\"\nID_EVENT_GAME_TRACKABLE_TRACK=0,eventid,EVENT_GAME_TRACKABLE_TRACK,\"(008)游戏事件 - 鼠标移动到可追踪物\"\nID_EVENT_GAME_SHOW_SKILL=0,eventid,EVENT_GAME_SHOW_SKILL,\"(009)游戏事件 - 英雄技能按钮被点击\"\nID_EVENT_GAME_SHOW_SKILL=0,eventid,EVENT_GAME_SHOW_SKILL,\"(010)游戏事件 - 建造建筑按钮被点击\"\n\n//===================================================\n// For use with TriggerRegisterPlayerEvent\n//===================================================\nID_EVENT_PLAYER_STATE_LIMIT=0,eventid,EVENT_PLAYER_STATE_LIMIT,\"(011)玩家事件 - 属性变化\"\nID_EVENT_PLAYER_ALLIANCE_CHANGED=0,eventid,EVENT_PLAYER_ALLIANCE_CHANGED,\"(012)玩家事件 - 联盟状态变化\"\nID_EVENT_PLAYER_DEFEAT=0,eventid,EVENT_PLAYER_DEFEAT,\"(013)玩家事件 - 游戏失败\"\nID_EVENT_PLAYER_VICTORY=0,eventid,EVENT_PLAYER_VICTORY,\"(014)玩家事件 - 游戏胜利\"\nID_EVENT_PLAYER_LEAVE=0,eventid,EVENT_PLAYER_LEAVE,\"(015)玩家事件 - 离开游戏\"\nID_EVENT_PLAYER_CHAT=0,eventid,EVENT_PLAYER_CHAT,\"(016)玩家事件 - (废弃的事件)\"\nID_EVENT_PLAYER_END_CINEMATIC=0,eventid,EVENT_PLAYER_END_CINEMATIC,\"(017)玩家事件 - 按下Esc键\"\n\n//===================================================\n// For use with TriggerRegisterPlayerUnitEvent\n//===================================================\nID_EVENT_PLAYER_UNIT_ATTACKED=0,eventid,EVENT_PLAYER_UNIT_ATTACKED,\"(018)玩家单位事件 - 被攻击\"\nID_EVENT_PLAYER_UNIT_RESCUED=0,eventid,EVENT_PLAYER_UNIT_RESCUED,\"(019)玩家单位事件 - 被营救\"\nID_EVENT_PLAYER_UNIT_DEATH=0,eventid,EVENT_PLAYER_UNIT_DEATH,\"(020)玩家单位事件 - 死亡\"\nID_EVENT_PLAYER_UNIT_DECAY=0,eventid,EVENT_PLAYER_UNIT_DECAY,\"(021)玩家单位事件 - 开始腐化\"\nID_EVENT_PLAYER_UNIT_DETECTED=0,eventid,EVENT_PLAYER_UNIT_DETECTED,\"(022)玩家单位事件 - 被侦测到\"\nID_EVENT_PLAYER_UNIT_HIDDEN=0,eventid,EVENT_PLAYER_UNIT_HIDDEN,\"(023)玩家单位事件 - 被隐藏\"\nID_EVENT_PLAYER_UNIT_SELECTED=0,eventid,EVENT_PLAYER_UNIT_SELECTED,\"(024)玩家单位事件 - 被选择\"\nID_EVENT_PLAYER_UNIT_DESELECTED=0,eventid,EVENT_PLAYER_UNIT_DESELECTED,\"(025)玩家单位事件 - 被取消选择\"\nID_EVENT_PLAYER_UNIT_CONSTRUCT_START=0,eventid,EVENT_PLAYER_UNIT_CONSTRUCT_START,\"(026)玩家单位事件 - 开始被建造\"\nID_EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL=0,eventid,EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL,\"(027)玩家单位事件 - 被取消建造\"\nID_EVENT_PLAYER_UNIT_CONSTRUCT_FINISH=0,eventid,EVENT_PLAYER_UNIT_CONSTRUCT_FINISH,\"(028)玩家单位事件 - 完成建造\"\nID_EVENT_PLAYER_UNIT_UPGRADE_START=0,eventid,EVENT_PLAYER_UNIT_UPGRADE_START,\"(029)玩家单位事件 - 开始建筑升级\"\nID_EVENT_PLAYER_UNIT_UPGRADE_CANCEL=0,eventid,EVENT_PLAYER_UNIT_UPGRADE_CANCEL,\"(030)玩家单位事件 - 取消建筑升级\"\nID_EVENT_PLAYER_UNIT_UPGRADE_FINISH=0,eventid,EVENT_PLAYER_UNIT_UPGRADE_FINISH,\"(031)玩家单位事件 - 完成建筑升级\"\nID_EVENT_PLAYER_UNIT_TRAIN_START=0,eventid,EVENT_PLAYER_UNIT_TRAIN_START,\"(032)玩家单位事件 - 开始训练单位\"\nID_EVENT_PLAYER_UNIT_TRAIN_CANCEL=0,eventid,EVENT_PLAYER_UNIT_TRAIN_CANCEL,\"(033)玩家单位事件 - 取消训练单位\"\nID_EVENT_PLAYER_UNIT_TRAIN_FINISH=0,eventid,EVENT_PLAYER_UNIT_TRAIN_FINISH,\"(034)玩家单位事件 - 完成训练单位\"\nID_EVENT_PLAYER_UNIT_RESEARCH_START=0,eventid,EVENT_PLAYER_UNIT_RESEARCH_START,\"(035)玩家单位事件 - 开始研究科技\"\nID_EVENT_PLAYER_UNIT_RESEARCH_CANCEL=0,eventid,EVENT_PLAYER_UNIT_RESEARCH_CANCEL,\"(036)玩家单位事件 - 取消研究科技\"\nID_EVENT_PLAYER_UNIT_RESEARCH_FINISH=0,eventid,EVENT_PLAYER_UNIT_RESEARCH_FINISH,\"(037)玩家单位事件 - 完成研究科技\"\nID_EVENT_PLAYER_UNIT_ISSUED_ORDER=0,eventid,EVENT_PLAYER_UNIT_ISSUED_ORDER,\"(038)玩家单位事件 - 发布无目标指令\"\nID_EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER=0,eventid,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,\"(039)玩家单位事件 - 发布指定点目标指令\"\nID_EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER=0,eventid,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER,\"(040)玩家单位事件 - 发布指定物体目标指令\"\nID_EVENT_PLAYER_HERO_LEVEL=0,eventid,EVENT_PLAYER_HERO_LEVEL,\"(041)玩家单位事件 - 提升等级\"\nID_EVENT_PLAYER_HERO_SKILL=0,eventid,EVENT_PLAYER_HERO_SKILL,\"(042)玩家单位事件 - 学习技能\"\nID_EVENT_PLAYER_HERO_REVIVABLE=0,eventid,EVENT_PLAYER_HERO_REVIVABLE,\"(043)玩家单位事件 - 变得可重生\"\nID_EVENT_PLAYER_HERO_REVIVE_START=0,eventid,EVENT_PLAYER_HERO_REVIVE_START,\"(044)玩家单位事件 - 开始复活英雄\"\nID_EVENT_PLAYER_HERO_REVIVE_CANCEL=0,eventid,EVENT_PLAYER_HERO_REVIVE_CANCEL,\"(045)玩家单位事件 - 取消复活英雄\"\nID_EVENT_PLAYER_HERO_REVIVE_FINISH=0,eventid,EVENT_PLAYER_HERO_REVIVE_FINISH,\"(046)玩家单位事件 - 完成复活英雄\"\nID_EVENT_PLAYER_UNIT_SUMMON=0,eventid,EVENT_PLAYER_UNIT_SUMMON,\"(047)玩家单位事件 - 被召唤\"\nID_EVENT_PLAYER_UNIT_DROP_ITEM=0,eventid,EVENT_PLAYER_UNIT_DROP_ITEM,\"(048)玩家单位事件 - 丢弃物品\"\nID_EVENT_PLAYER_UNIT_PICKUP_ITEM=0,eventid,EVENT_PLAYER_UNIT_PICKUP_ITEM,\"(049)玩家单位事件 - 获得物品\"\nID_EVENT_PLAYER_UNIT_USE_ITEM=0,eventid,EVENT_PLAYER_UNIT_USE_ITEM,\"(050)玩家单位事件 - 使用物品\"\nID_EVENT_PLAYER_UNIT_LOADED=0,eventid,EVENT_PLAYER_UNIT_LOADED,\"(051)玩家单位事件 - 被运输机装载\"\n\n//===================================================\n// For use with TriggerRegisterUnitEvent\n//===================================================\nID_EVENT_UNIT_DAMAGED=0,eventid,EVENT_UNIT_DAMAGED,\"(052)单位事件 - 接受伤害\"\nID_EVENT_UNIT_DEATH=0,eventid,EVENT_UNIT_DEATH,\"(053)单位事件 - 死亡\"\nID_EVENT_UNIT_DECAY=0,eventid,EVENT_UNIT_DECAY,\"(054)单位事件 - 开始腐化\"\nID_EVENT_UNIT_DETECTED=0,eventid,EVENT_UNIT_DETECTED,\"(055)单位事件 - 被侦测到\"\nID_EVENT_UNIT_HIDDEN=0,eventid,EVENT_UNIT_HIDDEN,\"(056)单位事件 - 被隐藏\"\nID_EVENT_UNIT_SELECTED=0,eventid,EVENT_UNIT_SELECTED,\"(057)单位事件 - 被选择\"\nID_EVENT_UNIT_DESELECTED=0,eventid,EVENT_UNIT_DESELECTED,\"(058)单位事件 - 被取消选择\"\nID_EVENT_UNIT_STATE_LIMIT=0,eventid,EVENT_UNIT_STATE_LIMIT,\"(059)单位事件 - 生命值/魔法值发生变化\"\nID_EVENT_UNIT_ACQUIRED_TARGET=0,eventid,EVENT_UNIT_ACQUIRED_TARGET,\"(060)单位事件 - 注意到攻击目标\"\nID_EVENT_UNIT_TARGET_IN_RANGE=0,eventid,EVENT_UNIT_TARGET_IN_RANGE,\"(061)单位事件 - 获取攻击目标\"\nID_EVENT_UNIT_ATTACKED=0,eventid,EVENT_UNIT_ATTACKED,\"(062)单位事件 - 被攻击\"\nID_EVENT_UNIT_RESCUED=0,eventid,EVENT_UNIT_RESCUED,\"(063)单位事件 - 被营救\"\nID_EVENT_UNIT_CONSTRUCT_CANCEL=0,eventid,EVENT_UNIT_CONSTRUCT_CANCEL,\"(064)单位事件 - 被取消建造\"\nID_EVENT_UNIT_CONSTRUCT_FINISH=0,eventid,EVENT_UNIT_CONSTRUCT_FINISH,\"(065)单位事件 - 完成建造\"\nID_EVENT_UNIT_UPGRADE_START=0,eventid,EVENT_UNIT_UPGRADE_START,\"(066)单位事件 - 开始建筑升级\"\nID_EVENT_UNIT_UPGRADE_CANCEL=0,eventid,EVENT_UNIT_UPGRADE_CANCEL,\"(067)单位事件 - 取消建筑升级\"\nID_EVENT_UNIT_UPGRADE_FINISH=0,eventid,EVENT_UNIT_UPGRADE_FINISH,\"(068)单位事件 - 完成建筑升级\"\nID_EVENT_UNIT_TRAIN_START=0,eventid,EVENT_UNIT_TRAIN_START,\"(069)单位事件 - 开始训练单位\"\nID_EVENT_UNIT_TRAIN_CANCEL=0,eventid,EVENT_UNIT_TRAIN_CANCEL,\"(070)单位事件 - 取消训练单位\"\nID_EVENT_UNIT_TRAIN_FINISH=0,eventid,EVENT_UNIT_TRAIN_FINISH,\"(071)单位事件 - 完成训练单位\"\nID_EVENT_UNIT_RESEARCH_START=0,eventid,EVENT_UNIT_RESEARCH_START,\"(072)单位事件 - 开始研究科技\"\nID_EVENT_UNIT_RESEARCH_CANCEL=0,eventid,EVENT_UNIT_RESEARCH_CANCEL,\"(073)单位事件 - 取消研究科技\"\nID_EVENT_UNIT_RESEARCH_FINISH=0,eventid,EVENT_UNIT_RESEARCH_FINISH,\"(074)单位事件 - 完成研究科技\"\nID_EVENT_UNIT_ISSUED_ORDER=0,eventid,EVENT_UNIT_ISSUED_ORDER,\"(075)单位事件 - 发布无目标指令\"\nID_EVENT_UNIT_ISSUED_POINT_ORDER=0,eventid,EVENT_UNIT_ISSUED_POINT_ORDER,\"(076)单位事件 - 发布指定点目标指令\"\nID_EVENT_UNIT_ISSUED_TARGET_ORDER=0,eventid,EVENT_UNIT_ISSUED_TARGET_ORDER,\"(077)单位事件 - 发布指定物体目标指令\"\nID_EVENT_UNIT_HERO_LEVEL=0,eventid,EVENT_UNIT_HERO_LEVEL,\"(078)单位事件 - 提升等级\"\nID_EVENT_UNIT_HERO_SKILL=0,eventid,EVENT_UNIT_HERO_SKILL,\"(079)单位事件 - 学习技能\"\nID_EVENT_UNIT_HERO_REVIVABLE=0,eventid,EVENT_UNIT_HERO_REVIVABLE,\"(080)单位事件 - 变得可重生\"\nID_EVENT_UNIT_HERO_REVIVE_START=0,eventid,EVENT_UNIT_HERO_REVIVE_START,\"(081)单位事件 - 开始复活英雄\"\nID_EVENT_UNIT_HERO_REVIVE_CANCEL=0,eventid,EVENT_UNIT_HERO_REVIVE_CANCEL,\"(082)单位事件 - 取消复活英雄\"\nID_EVENT_UNIT_HERO_REVIVE_FINISH=0,eventid,EVENT_UNIT_HERO_REVIVE_FINISH,\"(083)单位事件 - 完成复活英雄\"\nID_EVENT_UNIT_SUMMON=0,eventid,EVENT_UNIT_SUMMON,\"(084)单位事件 - 召唤一个单位\"\nID_EVENT_UNIT_DROP_ITEM=0,eventid,EVENT_UNIT_DROP_ITEM,\"(085)单位事件 - 丢弃物品\"\nID_EVENT_UNIT_PICKUP_ITEM=0,eventid,EVENT_UNIT_PICKUP_ITEM,\"(086)单位事件 - 获得物品\"\nID_EVENT_UNIT_USE_ITEM=0,eventid,EVENT_UNIT_USE_ITEM,\"(087)单位事件 - 使用物品\"\nID_EVENT_UNIT_LOADED=0,eventid,EVENT_UNIT_LOADED,\"(088)单位事件 - 被运输机装载\"\n\n//===================================================\n// Other\n//===================================================\nID_EVENT_WIDGET_DEATH=0,eventid,EVENT_WIDGET_DEATH,\"(089)widget事件 - 死亡\"\nID_EVENT_DIALOG_BUTTON_CLICK=0,eventid,EVENT_DIALOG_BUTTON_CLICK,\"(090)对话框事件 - 对话框按钮被点击\"\nID_EVENT_DIALOG_CLICK=0,eventid,EVENT_DIALOG_CLICK,\"(091)对话框事件 - 对话框被点击\"\nID_EVENT_PLAYER_CHAT2=0,eventid,ConvertPlayerEvent(96),\"(096)玩家事件 - 输入聊天消息\"\n\n//===================================================\n// Frozen Throne Expansion Events\n//===================================================\n\n//===================================================\n// For use with TriggerRegisterGameEvent\n//===================================================\nID_EVENT_GAME_LOADED=0,eventid,EVENT_GAME_LOADED,\"(256)游戏事件 - 游戏读档\"\nID_EVENT_GAME_TOURNAMENT_FINISH_SOON=0,eventid,EVENT_GAME_TOURNAMENT_FINISH_SOON,\"(257)游戏事件 - 游戏将在现在结束\"\nID_EVENT_GAME_TOURNAMENT_FINISH_NOW=0,eventid,EVENT_GAME_TOURNAMENT_FINISH_NOW,\"(258)游戏事件 - 游戏将在不久结束\"\nID_EVENT_GAME_SAVE=0,eventid,EVENT_GAME_SAVE,\"(259)游戏事件 - 游戏存档\"\n\n//===================================================\n// For use with TriggerRegisterPlayerEvent\n//===================================================\nID_EVENT_PLAYER_ARROW_LEFT_DOWN=0,eventid,EVENT_PLAYER_ARROW_LEFT_DOWN,\"(261)玩家键盘事件 - 按下Left键\"\nID_EVENT_PLAYER_ARROW_LEFT_UP=0,eventid,EVENT_PLAYER_ARROW_LEFT_UP,\"(262)玩家键盘事件 - 按上Left键\"\nID_EVENT_PLAYER_ARROW_RIGHT_DOWN=0,eventid,EVENT_PLAYER_ARROW_RIGHT_DOWN,\"(263)玩家键盘事件 - 按下Right键\"\nID_EVENT_PLAYER_ARROW_RIGHT_UP=0,eventid,EVENT_PLAYER_ARROW_RIGHT_UP,\"(264)玩家键盘事件 - 按上Right键\"\nID_EVENT_PLAYER_ARROW_DOWN_DOWN=0,eventid,EVENT_PLAYER_ARROW_DOWN_DOWN,\"(265)玩家键盘事件 - 按下Down键\"\nID_EVENT_PLAYER_ARROW_DOWN_UP=0,eventid,EVENT_PLAYER_ARROW_DOWN_UP,\"(266)玩家键盘事件 - 按上Down键\"\nID_EVENT_PLAYER_ARROW_UP_DOWN=0,eventid,EVENT_PLAYER_ARROW_UP_DOWN,\"(267)玩家键盘事件 - 按下Up键\"\nID_EVENT_PLAYER_ARROW_UP_UP=0,eventid,EVENT_PLAYER_ARROW_UP_UP,\"(268)玩家键盘事件 - 按上Up键\"\n\n//===================================================\n// For use with TriggerRegisterPlayerUnitEvent\n//===================================================\nID_EVENT_PLAYER_UNIT_SELL=0,eventid,EVENT_PLAYER_UNIT_SELL,\"(269)玩家单位事件 - 出售单位\"\nID_EVENT_PLAYER_UNIT_CHANGE_OWNER=0,eventid,EVENT_PLAYER_UNIT_CHANGE_OWNER,\"(270)玩家单位事件 - 改变所有者\"\nID_EVENT_PLAYER_UNIT_SELL_ITEM=0,eventid,EVENT_PLAYER_UNIT_SELL_ITEM,\"(271)玩家单位事件 - 出售物品\"\nID_EVENT_PLAYER_UNIT_SPELL_CHANNEL=0,eventid,EVENT_PLAYER_UNIT_SPELL_CHANNEL,\"(272)玩家单位事件 - 准备施放技能\"\nID_EVENT_PLAYER_UNIT_SPELL_CAST=0,eventid,EVENT_PLAYER_UNIT_SPELL_CAST,\"(273)玩家单位事件 - 开始施放技能\"\nID_EVENT_PLAYER_UNIT_SPELL_EFFECT=0,eventid,EVENT_PLAYER_UNIT_SPELL_EFFECT,\"(273)玩家单位事件 - 发动技能效果\"\nID_EVENT_PLAYER_UNIT_SPELL_FINISH=0,eventid,EVENT_PLAYER_UNIT_SPELL_FINISH,\"(275)玩家单位事件 - 施放技能结束\"\nID_EVENT_PLAYER_UNIT_SPELL_ENDCAST=0,eventid,EVENT_PLAYER_UNIT_SPELL_ENDCAST,\"(276)玩家单位事件 - 停止施放技能\"\nID_EVENT_PLAYER_UNIT_PAWN_ITEM=0,eventid,EVENT_PLAYER_UNIT_PAWN_ITEM,\"(277)玩家单位事件 - 抵押物品\"\n\n//===================================================\n// For use with TriggerRegisterUnitEvent\n//===================================================\nID_EVENT_UNIT_SELL=0,eventid,EVENT_UNIT_SELL,\"(286)单位事件 - 出售单位\"\nID_EVENT_UNIT_CHANGE_OWNER=0,eventid,EVENT_UNIT_CHANGE_OWNER,\"(287)单位事件 - 改变所有者\"\nID_EVENT_UNIT_SELL_ITEM=0,eventid,EVENT_PLAYER_SELL_ITEM,\"(288)单位事件 - 出售物品\"\nID_EVENT_UNIT_SPELL_CHANNEL=0,eventid,EVENT_UNIT_SPELL_CHANNEL,\"(289)单位事件 - 准备施放技能\"\nID_EVENT_UNIT_SPELL_CAST=0,eventid,EVENT_UNIT_SPELL_CAST,\"(290)单位事件 - 开始施放技能\"\nID_EVENT_UNIT_SPELL_EFFECT=0,eventid,EVENT_UNIT_SPELL_EFFECT,\"(291)单位事件 - 发动技能效果\"\nID_EVENT_UNIT_SPELL_FINISH=0,eventid,EVENT_UNIT_SPELL_FINISH,\"(292)单位事件 - 施放技能结束\"\nID_EVENT_UNIT_SPELL_ENDCAST=0,eventid,EVENT_UNIT_SPELL_ENDCAST,\"(293)单位事件 - 停止施放技能\"\nID_EVENT_UNIT_PAWN_ITEM=0,eventid,EVENT_UNIT_PAWN_ITEM,\"(294)单位事件 - 抵押物品\"\n\n\nABILITY_STATE_COOLDOWN=0,AbilityState,1,冷却时间\n\n//ABILITY_DATA_TARGS=0,AbilityDataInteger,100,目标允许\nABILITY_DATA_COST=0,AbilityDataInteger,104,魔法消耗\nABILITY_DATA_UNITID=0,AbilityDataInteger,117,单位类型\nABILITY_DATA_HOTKET=0,AbilityDataInteger,200,热键\nABILITY_DATA_UNHOTKET=0,AbilityDataInteger,201,关闭热键\nABILITY_DATA_RESEARCH_HOTKEY=0,AbilityDataInteger,202,学习热键\n\nABILITY_DATA_CAST=0,AbilityDataReal,101,施放时间\nABILITY_DATA_DUR=0,AbilityDataReal,102,持续时间(普通)\nABILITY_DATA_HERODUR=0,AbilityDataReal,103,持续时间(英雄)\nABILITY_DATA_COOL=0,AbilityDataReal,105,施放间隔\nABILITY_DATA_AREA=0,AbilityDataReal,106,影响区域\nABILITY_DATA_RNG=0,AbilityDataReal,107,施法距离\nABILITY_DATA_DATA_A=0,AbilityDataReal,108,数据A\nABILITY_DATA_DATA_B=0,AbilityDataReal,109,数据B\nABILITY_DATA_DATA_C=0,AbilityDataReal,110,数据C\nABILITY_DATA_DATA_D=0,AbilityDataReal,111,数据D\nABILITY_DATA_DATA_E=0,AbilityDataReal,112,数据E\nABILITY_DATA_DATA_F=0,AbilityDataReal,113,数据F\nABILITY_DATA_DATA_G=0,AbilityDataReal,114,数据G\nABILITY_DATA_DATA_H=0,AbilityDataReal,115,数据H\nABILITY_DATA_DATA_I=0,AbilityDataReal,116,数据I\n\nABILITY_DATA_NAME=0,AbilityDataString,203,名字\nABILITY_DATA_ART=0,AbilityDataString,204,图标\nABILITY_DATA_TARGET_ART=0,AbilityDataString,205,目标效果\nABILITY_DATA_CASTER_ART=0,AbilityDataString,206,施法者效果\nABILITY_DATA_EFFECT_ART=0,AbilityDataString,207,目标点效果\nABILITY_DATA_AREAEFFECT_ART=0,AbilityDataString,208,区域效果\nABILITY_DATA_MISSILE_ART=0,AbilityDataString,209,投射物\nABILITY_DATA_SPECIAL_ART=0,AbilityDataString,210,特殊效果\nABILITY_DATA_LIGHTNING_EFFECT=0,AbilityDataString,211,闪电效果\nABILITY_DATA_BUFF_TIP=0,AbilityDataString,212,buff提示\nABILITY_DATA_BUFF_UBERTIP=0,AbilityDataString,213,buff提示(扩展)\nABILITY_DATA_RESEARCH_TIP=0,AbilityDataString,214,学习提示\nABILITY_DATA_TIP=0,AbilityDataString,215,提示\nABILITY_DATA_UNTIP=0,AbilityDataString,216,关闭提示\nABILITY_DATA_RESEARCH_UBERTIP=0,AbilityDataString,217,学习提示(扩展)\nABILITY_DATA_UBERTIP=0,AbilityDataString,218,提示(扩展)\nABILITY_DATA_UNUBERTIP=0,AbilityDataString,219,关闭提示(扩展)\n\nCHAT_RECIPIENT_ALL=0,ChatRecipient,0,所有人频道\nCHAT_RECIPIENT_ALLIES=0,ChatRecipient,1,盟友频道\nCHAT_RECIPIENT_OBSERVERS=0,ChatRecipient,2,观看者/裁判频道\nCHAT_RECIPIENT_PRIVATE=0,ChatRecipient,3,私人频道\n\n\n\n\n//***************************************************************************\n[TriggerEvents]\n// Defines events available in the editor\n// Key: script event function\n// Value 0: first game version in which this function is valid\n// Value 1+: argument types\n// Note that the first argument is always a `trigger`, and is excluded here\n\n// Special events not defined in scripts, handled internally by the editor\nMapInitializationEvent=0,nothing\n_MapInitializationEvent_Defaults=\n_MapInitializationEvent_Category=TC_NOTHING\n\n\n//最萌小汐\nEvent.AnyUnitSkill=0,skillType,abilcode\n_Event.AnyUnitSkill_Defaults=skillTypeC,_\n_Event.AnyUnitSkill_Category=TC_MU_EVENT\n\nEvent.AnyUnitDamage=0,damageTypeA,damageTypeB\n_Event.AnyUnitDamage_Defaults=damageTypeA1,damageTypeB1\n_Event.AnyUnitDamage_Category=TC_MU_EVENT\n\nEvent.AnyUnitHeal=0,damageTypeA,healType\n_Event.AnyUnitHeal_Defaults=damageTypeA1,healType1\n_Event.AnyUnitHeal_Category=TC_MU_EVENT\n\nEvent.UserEventInit=0,scriptcode\n_Event.UserEventInit_Category=TC_MU_EVENT\n\nEvent.SkillCoolReset=0,abilcode\n_Event.SkillCoolReset_Defaults=GetSpellAbilityId\n_Event.SkillCoolReset_Category=TC_MU_EVENT\n\nEvent.ItemPick=0,itemcode\n_Event.ItemPick_Category=TC_MU_EVENT\n\nEvent.ItemDrop=0,itemcode\n_Event.ItemDrop_Category=TC_MU_EVENT\n\nEvent.ItemPickDrop=0,itemPickDrop,itemcode\n_Event.ItemPickDrop_Defaults=itemPickDrop1,_\n_Event.ItemPickDrop_Category=TC_MU_EVENT\n\nEvent.HeroRevive=0,abilcode\n_Event.HeroRevive_Defaults=GetSpellAbilityId\n_Event.HeroRevive_Category=TC_MU_EVENT\n\nEvent.ProcessCovered=0,integer\n_Event.ProcessCovered_Category=TC_MU_EVENT\n\nEvent.SkillBarEnd=0,unit,SkillBarEndReason\n_Event.SkillBarEnd_Defaults=Unit.lastSkillBar,SkillBarEndReasonA\n_Event.SkillBarEnd_Category=TC_MU_EVENT\n\nEvent.HeroInit=0,unitcode\n_Event.HeroInit_Category=TC_MU_EVENT\n\nEvent.Crit=0\n_Event.Crit_Category=TC_MU_EVENT\n\n//\nYDWEDisableRegister=0,nothing\n_YDWEDisableRegister_Defaults=\n_YDWEDisableRegister_Category=TC_NOTHING\n\n\n//YD Event Trigger\nYDWESyStemAnyUnitDamagedRegistTrigger=1\n_YDWESyStemAnyUnitDamagedRegistTrigger_Defaults=\n_YDWESyStemAnyUnitDamagedRegistTrigger_Category=TC_YDET\n\nYDWESyStemItemUnmovableRegistTrigger=1\n_YDWESyStemItemUnmovableRegistTrigger_Defaults=\n_YDWESyStemItemUnmovableRegistTrigger_Category=TC_YDET\n\nYDWESyStemItemCombineRegistTrigger=1\n_YDWESyStemItemCombineRegistTrigger_Defaults=\n_YDWESyStemItemCombineRegistTrigger_Category=TC_YDET\n\nYDWESyStemAbilityCastingOverRegistTrigger=0,abilevent\n_YDWESyStemAbilityCastingOverRegistTrigger_Defaults=abileventA\n_YDWESyStemAbilityCastingOverRegistTrigger_Category=TC_YDET\n\n// Unit events\nTriggerRegisterUnitEvent=0,unit,unitevent\n_TriggerRegisterUnitEvent_Defaults=_,UnitEventDeath\n_TriggerRegisterUnitEvent_Category=TC_UNIT\n\nTriggerRegisterPlayerUnitEventSimple=0,player,playerunitevent\n_TriggerRegisterPlayerUnitEventSimple_Defaults=Player00,PlayerUnitEventDeath\n_TriggerRegisterPlayerUnitEventSimple_Category=TC_UNIT\n\nTriggerRegisterAnyUnitEventBJ=1,playerunitevent\n_TriggerRegisterAnyUnitEventBJ_Defaults=PlayerUnitEventDeath\n_TriggerRegisterAnyUnitEventBJ_Category=TC_UNIT\n\nTriggerRegisterEnterRectSimple=0,rect\n_TriggerRegisterEnterRectSimple_Defaults=_\n_TriggerRegisterEnterRectSimple_Category=TC_UNIT\n\nTriggerRegisterLeaveRectSimple=0,rect\n_TriggerRegisterLeaveRectSimple_Defaults=_\n_TriggerRegisterLeaveRectSimple_Category=TC_UNIT\n\nTriggerRegisterEnterRegionSimple=0,region\n_TriggerRegisterEnterRegionSimple_Defaults=_\n_TriggerRegisterEnterRegionSimple_Category=TC_UNIT\n\nTriggerRegisterLeaveRegionSimple=0,region\n_TriggerRegisterLeaveRegionSimple_Defaults=_\n_TriggerRegisterLeaveRegionSimple_Category=TC_UNIT\n\nTriggerRegisterEnterRegion=0,region,boolexpr\n_TriggerRegisterEnterRegion_Defaults=_,BoolExprNull\n_TriggerRegisterEnterRegion_Category=TC_UNIT\n\nTriggerRegisterLeaveRegion=0,region,boolexpr\n_TriggerRegisterLeaveRegion_Defaults=_,BoolExprNull\n_TriggerRegisterLeaveRegion_Category=TC_UNIT\n\nTriggerRegisterUnitInRangeSimple=0,real,unit\n_TriggerRegisterUnitInRangeSimple_Defaults=256,_\n_TriggerRegisterUnitInRangeSimple_Defaults=0,_,_,_\n_TriggerRegisterUnitInRangeSimple_Category=TC_UNIT\n\nTriggerRegisterUnitLifeEvent=0,unit,limitop,real\n_TriggerRegisterUnitLifeEvent_Defaults=_,LimitOpLessThan,50\n_TriggerRegisterUnitLifeEvent_Category=TC_UNIT\n\nTriggerRegisterUnitManaEvent=0,unit,limitop,real\n_TriggerRegisterUnitManaEvent_Defaults=_,LimitOpLessThan,50\n_TriggerRegisterUnitManaEvent_Category=TC_UNIT\n\n\n// Dialog events\nTriggerRegisterDialogEventBJ=0,dialog\n_TriggerRegisterDialogEventBJ_Defaults=_\n_TriggerRegisterDialogEventBJ_Category=TC_DIALOG\n_TriggerRegisterDialogEventBJ_ScriptName=TriggerRegisterDialogEvent\n\nTriggerRegisterDialogButtonEvent=0,button\n_TriggerRegisterDialogButtonEvent_Defaults=_\n_TriggerRegisterDialogButtonEvent_Category=TC_DIALOG\n\n\n// Destructible events\nTriggerRegisterDeathEvent=0,destructable\n_TriggerRegisterDeathEvent_Defaults=_\n_TriggerRegisterDeathEvent_Category=TC_DESTRUCT\n\nTriggerRegisterDestDeathInRegionEvent=1,rect\n_TriggerRegisterDestDeathInRegionEvent_Defaults=_\n_TriggerRegisterDestDeathInRegionEvent_Category=TC_DESTRUCT\n\n\n// Trackable events\nTriggerRegisterTrackableHitEvent=0,trackable\n_TriggerRegisterTrackableHitEvent_Defaults=_\n_TriggerRegisterTrackableHitEvent_Category=TC_TRACKABLE\n\nTriggerRegisterTrackableTrackEvent=0,trackable\n_TriggerRegisterTrackableTrackEvent_Defaults=_\n_TriggerRegisterTrackableTrackEvent_Category=TC_TRACKABLE\n\n\n// Timer events\nTriggerRegisterTimerEventSingle=0,real\n_TriggerRegisterTimerEventSingle_Defaults=5\n_TriggerRegisterTimerEventSingle_Limits=0,_\n_TriggerRegisterTimerEventSingle_Category=TC_TIME\n\nTriggerRegisterTimerEventPeriodic=0,real\n_TriggerRegisterTimerEventPeriodic_Defaults=2\n_TriggerRegisterTimerEventPeriodic_Limits=0,_\n_TriggerRegisterTimerEventPeriodic_Category=TC_TIME\n\nTriggerRegisterTimerExpireEventBJ=0,timer\n_TriggerRegisterTimerExpireEventBJ_Defaults=_\n_TriggerRegisterTimerExpireEventBJ_Category=TC_TIME\n_TriggerRegisterTimerExpireEventBJ_ScriptName=TriggerRegisterTimerExpireEvent\n\n\n// Player events\nTriggerRegisterPlayerChatEvent=0,player,string,chatmatchtype\n_TriggerRegisterPlayerChatEvent_Defaults=Player00,_,ChatMatchTypeExact\n_TriggerRegisterPlayerChatEvent_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventEndCinematic=0,player\n_TriggerRegisterPlayerEventEndCinematic_Defaults=Player00\n_TriggerRegisterPlayerEventEndCinematic_Category=TC_PLAYER\n\nTriggerRegisterPlayerSelectionEventBJ=0,player,seldeseloption\n_TriggerRegisterPlayerSelectionEventBJ_Defaults=Player00,SelDeselOptionSel\n_TriggerRegisterPlayerSelectionEventBJ_Category=TC_PLAYER\n\nTriggerRegisterPlayerKeyEventBJ=1,player,keyeventtype,keyeventkey\n_TriggerRegisterPlayerKeyEventBJ_Defaults=Player00,KeyEventTypeDepress,KeyEventKeyLeft\n_TriggerRegisterPlayerKeyEventBJ_Category=TC_PLAYER\n\nTriggerRegisterPlayerStateEvent=0,player,playerstate,limitop,real\n_TriggerRegisterPlayerStateEvent_Defaults=Player00,PlayerStateGold,LimitOpGreaterThanOrEqual,1000\n_TriggerRegisterPlayerStateEvent_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventAllianceChanged=0,player\n_TriggerRegisterPlayerEventAllianceChanged_Defaults=Player00\n_TriggerRegisterPlayerEventAllianceChanged_Category=TC_PLAYER\n\nTriggerRegisterPlayerAllianceChange=0,player,alliancetype\n_TriggerRegisterPlayerAllianceChange_Defaults=Player00,AllianceTypePassive\n_TriggerRegisterPlayerAllianceChange_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventVictory=0,player\n_TriggerRegisterPlayerEventVictory_Defaults=Player00\n_TriggerRegisterPlayerEventVictory_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventDefeat=0,player\n_TriggerRegisterPlayerEventDefeat_Defaults=Player00\n_TriggerRegisterPlayerEventDefeat_Category=TC_PLAYER\n\nTriggerRegisterPlayerEventLeave=1,player\n_TriggerRegisterPlayerEventLeave_Defaults=Player00\n_TriggerRegisterPlayerEventLeave_Category=TC_PLAYER\n\n\n// Item events\nTriggerRegisterItemDeathEvent=0,item\n_TriggerRegisterItemDeathEvent_Defaults=_\n_TriggerRegisterItemDeathEvent_Category=TC_ITEM\n_TriggerRegisterItemDeathEvent_ScriptName=TriggerRegisterDeathEvent\n\n\n// Game events\nTriggerRegisterGameStateEventTimeOfDay=0,limitop,real\n_TriggerRegisterGameStateEventTimeOfDay_Defaults=LimitOpEqual,12\n_TriggerRegisterGameStateEventTimeOfDay_Limits=_,_,0,24\n_TriggerRegisterGameStateEventTimeOfDay_Category=TC_GAME\n\nTriggerRegisterVariableEvent=0,VarAsString_Real,limitop,real\n_TriggerRegisterVariableEvent_Defaults=_,LimitOpEqual,0\n_TriggerRegisterVariableEvent_Category=TC_GAME\n\nTriggerRegisterGameLoadedEventBJ=1,nothing\n_TriggerRegisterGameLoadedEventBJ_Defaults=\n_TriggerRegisterGameLoadedEventBJ_Category=TC_GAME\n\nTriggerRegisterGameSavedEventBJ=1,nothing\n_TriggerRegisterGameSavedEventBJ_Defaults=\n_TriggerRegisterGameSavedEventBJ_Category=TC_GAME\n\nTriggerRegisterShowSkillEventBJ=0,nothing\n_TriggerRegisterShowSkillEventBJ_Defaults=\n_TriggerRegisterShowSkillEventBJ_Category=TC_GAME\n\nTriggerRegisterBuildSubmenuEventBJ=0,nothing\n_TriggerRegisterBuildSubmenuEventBJ_Defaults=\n_TriggerRegisterBuildSubmenuEventBJ_Category=TC_GAME\n\nTriggerRegisterGameEvent=1,gameevent\n_TriggerRegisterGameEvent_Defaults=GameEventTourneyNow\n_TriggerRegisterGameEvent_Category=TC_GAME\n\n\n\n//***************************************************************************\n[TriggerConditions]\n// Defines boolean condition functions\n// Key: condition function name\n// Value 0: first game version in which this function is valid\n// Value 1+: argument types\n\nOperatorCompareBoolean=0,boolean,EqualNotEqualOperator,boolean\n_OperatorCompareBoolean_Defaults=IsUnitType,OperatorEqualENE,true\n_OperatorCompareBoolean_Category=TC_CONDITION\n_OperatorCompareBoolean_UseWithAI=1\n_OperatorCompareBoolean_AIDefaults=true,OperatorEqualENE,true\n\n             =0,scriptcode\n_             _Defaults=_\n_             _Category=TC_CONDITION\n\nOperatorCompareTrigger=0,trigger,EqualNotEqualOperator,trigger\n_OperatorCompareTrigger_Defaults=_,OperatorEqualENE,_\n_OperatorCompareTrigger_Category=TC_CONDITION\n\nOperatorCompareUnit=0,unit,EqualNotEqualOperator,unit\n_OperatorCompareUnit_Defaults=GetTriggerUnit,OperatorEqualENE,_\n_OperatorCompareUnit_Category=TC_CONDITION\n\nOperatorCompareUnitCode=0,unitcode,EqualNotEqualOperator,unitcode\n_OperatorCompareUnitCode_Defaults=GetUnitTypeId,OperatorEqualENE,hfoo\n_OperatorCompareUnitCode_Category=TC_CONDITION\n\nOperatorCompareTerrainType=1,terraintype,EqualNotEqualOperator,terraintype\n_OperatorCompareTerrainType_Defaults=GetTerrainTypeBJ,OperatorEqualENE,TerrainTypeLdrt\n_OperatorCompareTerrainType_Category=TC_CONDITION\n\nOperatorComparePoint=0,location,EqualNotEqualOperator,location\n_OperatorComparePoint_Defaults=_,OperatorEqualENE,_\n_OperatorComparePoint_Category=TC_CONDITION\n\nOperatorCompareDialog=0,dialog,EqualNotEqualOperator,dialog\n_OperatorCompareDialog_Defaults=GetClickedDialogBJ,OperatorEqualENE,_\n_OperatorCompareDialog_Category=TC_CONDITION\n\nOperatorCompareButton=0,button,EqualNotEqualOperator,button\n_OperatorCompareButton_Defaults=_,OperatorEqualENE,_\n_OperatorCompareButton_Category=TC_CONDITION\n\nOperatorCompareMeleeDifficulty=1,aidifficulty,EqualNotEqualOperator,aidifficulty\n_OperatorCompareMeleeDifficulty_Defaults=GetAIDifficulty,OperatorEqualENE,AIDifficultyNormal\n_OperatorCompareMeleeDifficulty_Category=TC_CONDITION\n\nOperatorCompareAbilityId=1,abilcode,EqualNotEqualOperator,abilcode\n_OperatorCompareAbilityId_Defaults=GetSpellAbilityId,OperatorEqualENE,AUan\n_OperatorCompareAbilityId_Category=TC_CONDITION\n\nOperatorCompareTimer=1,timer,EqualNotEqualOperator,timer\n_OperatorCompareTimer_Defaults=GetExpiredTimer,OperatorEqualENE,_\n_OperatorCompareTimer_Category=TC_CONDITION\n\nOperatorCompareTechCode=0,techcode,EqualNotEqualOperator,techcode\n_OperatorCompareTechCode_Defaults=GetResearched,OperatorEqualENE,_\n_OperatorCompareTechCode_Category=TC_CONDITION\n\nOperatorCompareDestructible=0,destructable,EqualNotEqualOperator,destructable\n_OperatorCompareDestructible_Defaults=_,OperatorEqualENE,_\n_OperatorCompareDestructible_Category=TC_CONDITION\n\nOperatorCompareDestructableCode=0,destructablecode,EqualNotEqualOperator,destructablecode\n_OperatorCompareDestructableCode_Defaults=GetDestructableTypeId,OperatorEqualENE,LTlt\n_OperatorCompareDestructableCode_Category=TC_CONDITION\n\nOperatorCompareTrackable=1,trackable,EqualNotEqualOperator,trackable\n_OperatorCompareTrackable_Defaults=GetTriggeringTrackable,OperatorEqualENE,GetTriggeringTrackable\n_OperatorCompareTrackable_Category=TC_CONDITION\n\nOperatorCompareOrderCode=0,ordercode,EqualNotEqualOperator,ordercode\n_OperatorCompareOrderCode_Defaults=GetIssuedOrderIdBJ,OperatorEqualENE,String2OrderIdBJ\n_OperatorCompareOrderCode_Category=TC_CONDITION\n\nOperatorCompareBuffId=1,buffcode,EqualNotEqualOperator,buffcode\n_OperatorCompareBuffId_Defaults=_,OperatorEqualENE,_\n_OperatorCompareBuffId_Category=TC_CONDITION\n\nOperatorCompareRegion=0,rect,EqualNotEqualOperator,rect\n_OperatorCompareRegion_Defaults=_,OperatorEqualENE,_\n_OperatorCompareRegion_Category=TC_CONDITION\n\nOperatorCompareRegionR=0,region,EqualNotEqualOperator,region\n_OperatorCompareRegionR_Defaults=_,OperatorEqualENE,_\n_OperatorCompareRegionR_Category=TC_CONDITION\n\nOperatorCompareReal=0,real,ComparisonOperator,real\n_OperatorCompareReal_Defaults=10,OperatorGreaterEq,10\n_OperatorCompareReal_Category=TC_CONDITION\n\nOperatorCompareDegree=0,real,ComparisonOperator,real\n_OperatorCompareDegree_Defaults=10,OperatorGreaterEq,10\n_OperatorCompareDegree_Category=TC_CONDITION\n\nOperatorCompareRadian=0,real,ComparisonOperator,real\n_OperatorCompareRadian_Defaults=10,OperatorGreaterEq,10\n_OperatorCompareRadian_Category=TC_CONDITION\n\nOperatorComparePlayer=0,player,EqualNotEqualOperator,player\n_OperatorComparePlayer_Defaults=GetOwningPlayer,OperatorEqualENE,Player00\n_OperatorComparePlayer_Category=TC_CONDITION\n\nOperatorComparePlayerColor=0,playercolor,EqualNotEqualOperator,playercolor\n_OperatorComparePlayerColor_Defaults=GetPlayerColor,OperatorEqualENE,Color00\n_OperatorComparePlayerColor_Category=TC_CONDITION\n\nOperatorComparePlayerControl=0,mapcontrol,EqualNotEqualOperator,mapcontrol\n_OperatorComparePlayerControl_Defaults=GetPlayerController,OperatorEqualENE,MapControlUser\n_OperatorComparePlayerControl_Category=TC_CONDITION\n\nOperatorComparePlayerSlotStatus=0,playerslotstate,EqualNotEqualOperator,playerslotstate\n_OperatorComparePlayerSlotStatus_Defaults=GetPlayerSlotState,OperatorEqualENE,PlayerSlotStatePlaying\n_OperatorComparePlayerSlotStatus_Category=TC_CONDITION\n\nOperatorCompareItem=0,item,EqualNotEqualOperator,item\n_OperatorCompareItem_Defaults=_,OperatorEqualENE,_\n_OperatorCompareItem_Category=TC_CONDITION\n\nOperatorCompareItemType=1,itemtype,EqualNotEqualOperator,itemtype\n_OperatorCompareItemType_Defaults=GetItemType,OperatorEqualENE,ItemTypePowerup\n_OperatorCompareItemType_Category=TC_CONDITION\n\nOperatorCompareItemCode=0,itemcode,EqualNotEqualOperator,itemcode\n_OperatorCompareItemCode_Defaults=GetItemTypeId,OperatorEqualENE,texp\n_OperatorCompareItemCode_Category=TC_CONDITION\n\nOperatorCompareHeroSkill=0,heroskillcode,EqualNotEqualOperator,heroskillcode\n_OperatorCompareHeroSkill_Defaults=GetLearnedSkillBJ,OperatorEqualENE,HeroSkillBlizzard\n_OperatorCompareHeroSkill_Category=TC_CONDITION\n\nOperatorCompareGameDifficulty=0,gamedifficulty,EqualNotEqualOperator,gamedifficulty\n_OperatorCompareGameDifficulty_Defaults=GetGameDifficulty,OperatorEqualENE,GameDifficultyNormal\n_OperatorCompareGameDifficulty_Category=TC_CONDITION\n\nOperatorCompareGameSpeed=0,gamespeed,EqualNotEqualOperator,gamespeed\n_OperatorCompareGameSpeed_Defaults=GetGameSpeed,OperatorEqualENE,GameSpeedNormal\n_OperatorCompareGameSpeed_Category=TC_CONDITION\n\nOperatorCompareInteger=0,integer,ComparisonOperator,integer\n_OperatorCompareInteger_Defaults=0,OperatorEqual,0\n_OperatorCompareInteger_Category=TC_CONDITION\n_OperatorCompareInteger_UseWithAI=1\n_OperatorCompareInteger_AIDefaults=0,OperatorEqual,0\n\nOperatorCompareRace=0,race,EqualNotEqualOperator,race\n_OperatorCompareRace_Defaults=GetPlayerRace,OperatorEqualENE,RaceHuman\n_OperatorCompareRace_Category=TC_CONDITION\n\nOperatorCompareString=0,string,EqualNotEqualOperator,string\n_OperatorCompareString_Defaults=GetEventPlayerChatString,OperatorEqualENE,_\n_OperatorCompareString_Category=TC_CONDITION\n\n//OperatorComparePoint=0,location,EqualNotEqualOperator,location\n//_OperatorComparePoint_Defaults=_,OperatorEqualENE,_\n//_OperatorComparePoint_Category=TC_CONDITION\n\nGetBooleanAnd=0,boolcall,boolcall\n_GetBooleanAnd_Defaults=_,_\n_GetBooleanAnd_Category=TC_CONDITION\n_GetBooleanAnd_UseWithAI=1\n\nGetBooleanOr=0,boolcall,boolcall\n_GetBooleanOr_Defaults=_,_\n_GetBooleanOr_Category=TC_CONDITION\n_GetBooleanOr_UseWithAI=1\n\n// Specially handled by the editor\nAndMultiple=1,nothing\n_AndMultiple_Category=TC_CONDITION\n\n// Specially handled by the editor\nOrMultiple=1,nothing\n_OrMultiple_Category=TC_CONDITION\n\n\n\n\n//***************************************************************************\n[TriggerActions]\n\n// Defines action functions\n// Key: action function name\n// Value 0: first game version in which this function is valid\n// Value 1+: argument types\n\nDoNothing=0,nothing\n_DoNothing_Defaults=\n_DoNothing_Category=TC_NOTHING\n\nCommentString=0,scriptcode\n_CommentString_Defaults=_\n_CommentString_Category=TC_COMMENT\n\nCustomScriptCode=1,scriptcode\n_CustomScriptCode_Defaults=_\n_CustomScriptCode_Category=TC_CUSTOM\n\nExecuteFunc=0,string\n_ExecuteFunc_Defaults=_\n_ExecuteFunc_Category=TC_NOTHING\n\nTriggerSleepAction=0,real\n_TriggerSleepAction_Defaults=2\n_TriggerSleepAction_Limits=0,_\n_TriggerSleepAction_Category=TC_WAIT\n\nPolledWait=1,real\n_PolledWait_Defaults=2\n_PolledWait_Limits=0,_\n_PolledWait_Category=TC_WAIT\n\n\n\n\n\n\n\n\nWaitForCondition=1,boolexpr,real\n_WaitForCondition_Defaults=_,1\n_WaitForCondition_Limits=_,_,0.1,_\n_WaitForCondition_Category=TC_WAIT\n\nWaitForSoundBJ=0,sound,real\n_WaitForSoundBJ_Defaults=_,0\n_WaitForSoundBJ_Category=TC_WAIT\n_WaitForSoundBJ_ScriptName=TriggerWaitForSound\n\n// Specially handled by the editor\nSetVariable=0,AnyGlobal,Null\n_SetVariable_Defaults=_,_\n_SetVariable_Category=TC_SETVARIABLE\n\n// Specially handled by the editor\nReturnAction=0,nothing\n_ReturnAction_Defaults=\n_ReturnAction_Category=TC_SKIPACTIONS\n\nYDWEExitLoop=0,nothing\n_YDWEExitLoop_Defaults=\n_YDWEExitLoop_Category=TC_SKIPACTIONS\n_YDWEExitLoop_ScriptName=DoNothing() YDNL exitwhen true//\n\n// Specially handled by the editor\nIfThenElseMultiple=1,nothing\n_IfThenElseMultiple_Category=TC_LOGIC\n\n//YDWEIfThenElseMultiple=1,nothing\n//_IfThenElseMultiple_Category=TC_YDST\n\n// Specially handled by the editor\nIfThenElse=0,boolexpr,code,code\n_IfThenElse_Defaults=_,DoNothing,DoNothing\n_IfThenElse_Category=TC_LOGIC\n\n//YDWEIfThenElse=0,boolexpr,code,code\n//_YDWEIfThenElse_Defaults=_,DoNothing,DoNothing\n//_YDWEIfThenElse_Category=TC_YDST\n\n// Specially handled by the editor\nForLoopAMultiple=1,integer,integer\n_ForLoopAMultiple_Defaults=1,10\n_ForLoopAMultiple_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopBMultiple=1,integer,integer\n_ForLoopBMultiple_Defaults=1,10\n_ForLoopBMultiple_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopVarMultiple=1,integervar,integer,integer\n_ForLoopVarMultiple_Defaults=_,1,10\n_ForLoopVarMultiple_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopA=0,integer,integer,code\n_ForLoopA_Defaults=1,10,DoNothing\n_ForLoopA_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopB=0,integer,integer,code\n_ForLoopB_Defaults=1,10,DoNothing\n_ForLoopB_Category=TC_FORLOOP\n\n// Specially handled by the editor\nForLoopVar=1,integervar,integer,integer,code\n_ForLoopVar_Defaults=_,1,10,DoNothing\n_ForLoopVar_Category=TC_FORLOOP\n\nSetForLoopIndexA=1,integer\n_SetForLoopIndexA_Defaults=10\n_SetForLoopIndexA_Category=TC_FORLOOP\n\nSetForLoopIndexB=1,integer\n_SetForLoopIndexB_Defaults=10\n_SetForLoopIndexB_Category=TC_FORLOOP\n\n// AI actions\nStartMeleeAI=0,player,aiscript\n_StartMeleeAI_Defaults=Player00,\"map.ai\"\n_StartMeleeAI_Category=TC_AI\n\nStartCampaignAI=0,player,aiscript\n_StartCampaignAI_Defaults=Player00,\"map.ai\"\n_StartCampaignAI_Category=TC_AI\n\nCommandAI=0,player,integer,integer\n_CommandAI_Defaults=Player00,_,_\n_CommandAI_Category=TC_AI\n\nPauseCompAI=0,player,pauseresumeoption\n_PauseCompAI_Defaults=Player00,PauseResumePause\n_PauseCompAI_Category=TC_AI\n\nRemoveGuardPosition=0,unit\n_RemoveGuardPosition_Defaults=_\n_RemoveGuardPosition_Category=TC_AI\n\nRemoveAllGuardPositions=0,player\n_RemoveAllGuardPositions_Defaults=Player00\n_RemoveAllGuardPositions_Category=TC_AI\n\nRecycleGuardPosition=0,unit\n_RecycleGuardPosition_Defaults=_\n_RecycleGuardPosition_Category=TC_AI\n\nSetUnitCreepGuard=1,unit,lockunlockoption\n_SetUnitCreepGuard_Defaults=GetTriggerUnit,LockUnLockLock\n_SetUnitCreepGuard_Category=TC_AI\n\nLockGuardPosition=1,unit\n_LockGuardPosition_Defaults=_\n_LockGuardPosition_Category=TC_AI\n\n\n//最萌小汐\n//专用库\nbaka.lucky=0,unit,real,isLuck\n_baka.lucky_Defaults=GetTriggerUnit,75,isLuckA\n_baka.lucky_Limits=_,_,0,100,_,_\n_baka.lucky_Category=TC_MU_BAKA\n\nbaka.Sp=0\n_baka.Sp_Category=TC_MU_BAKA\n\nbaka.hookImage=0\n_baka.hookImage_Category=TC_MU_BAKA\n\nFlushUnit_Add=0,unit\n_FlushUnit_Add_Defaults=GetTriggerUnit\n_FlushUnit_Add_Category=TC_MU_BAKA\n\nmaphack.InitHero=0,unit\n_maphack.InitHero_Defaults=GetTriggerUnit\n_maphack.InitHero_Category=TC_MU_BAKA\n\nLua_hook=0,player,string\n_Lua_hook_Defaults=GetOwningPlayer,\"函数名 参数\"\n_Lua_hook_Category=TC_MU_BAKA\n\n//数学库\nmath.MoveLocationAngle=0,location,real,real,boolean\n_math.MoveLocationAngle_Defaults=_,0,100,true\n_math.MoveLocationAngle_Category=TC_MU_MATH\n\nmath.SetPolygonLocation=0,integer,real,real\n_math.SetPolygonLocation_Defaults=1,0,0\n_math.SetPolygonLocation_Limits=0,8191,_,_,_,_\n_math.SetPolygonLocation_Category=TC_MU_MATH\n\n//单位库\nUnit.ExchangeItem=0,unit,itemcode,itemcode,boolean,boolean\n_Unit.ExchangeItem_Defaults=GetTriggerUnit,ches,ches,true,true\n_Unit.ExchangeItem_Category=TC_MU_UNIT\n\nUnit.Move=0,unit,real,real\n_Unit.Move_Defaults=GetTriggerUnit,0,50\n_Unit.Move_Category=TC_MU_UNIT\n\nUnit.Move2=0,unit,real,real,pathingtype\n_Unit.Move2_Defaults=GetTriggerUnit,0,50,PathingTypeWalkability\n_Unit.Move2_Category=TC_MU_UNIT\n\nUnit.SetUnitXY=0,unit,real,real\n_Unit.SetUnitXY_Defaults=GetTriggerUnit,GetUnitX,GetUnitY\n_Unit.SetUnitXY_Category=TC_MU_UNIT\n\nUnit.SetUnitXYOffset=0,unit,real,real,real,real\n_Unit.SetUnitXYOffset_Defaults=GetTriggerUnit,GetUnitX,GetUnitY,GetUnitFacing,50\n_Unit.SetUnitXYOffset_Category=TC_MU_UNIT\n\nUnit.DummyAttack=0,unit,unitcode,unit,integer,boolean,boolean,boolean,boolean\n_Unit.DummyAttack_Defaults=GetTriggerUnit,_,GetTriggerUnit,1,true,true,true,true\n_Unit.DummyAttack_Category=TC_MU_UNIT\n\nUnit.WantDestroyGroup=0\n_Unit.WantDestroyGroup_Category=TC_MU_UNIT\n\nUnit.DummySkill=0,player,unit,integer,abilcode\n_Unit.DummySkill_Defaults=GetOwningPlayer,GetTriggerUnit,1,Aloc\n_Unit.DummySkill_Category=TC_MU_UNIT\n\nUnit.DummySkillLoc=0,player,location,boolean,integer,abilcode\n_Unit.DummySkillLoc_Defaults=GetOwningPlayer,GetUnitLoc,true,1,Aloc\n_Unit.DummySkillLoc_Category=TC_MU_UNIT\n\nUnit.SetHard=0,unit,real\n_Unit.SetHard_Defaults=GetTriggerUnit,1\n_Unit.SetHard_Category=TC_MU_UNIT\n\nUnit.SkillBar=0,unit,real,playercolor,boolean,boolean,boolean,boolean\n_Unit.SkillBar_Defaults=GetTriggerUnit,1,Color00,true,true,true,true\n_Unit.SkillBar_Category=TC_MU_UNIT\n\nUnit.SaveSlkData=0,unitcode,scriptcode\n_Unit.SaveSlkData_Defaults=hfoo,_\n_Unit.SaveSlkData_Category=TC_MU_UNIT\n\nUnit.Crit=0,unit,add_remove,real,real,string,crit_crited\n_Unit.Crit_Defaults=GetTriggerUnit,add_remove_add,15,1.5,\"无\",crit_crited_crit\n_Unit.Crit_Category=TC_MU_UNIT\n\nUnit.HitDodg=0,unit,add_remove,real,string,hit_dodg\n_Unit.HitDodg_Defaults=GetTriggerUnit,add_remove_add,15,\"无\",hit_dodg_dodg\n_Unit.HitDodg_Category=TC_MU_UNIT\n\nUnit.PrintHitDodgCrit=0,unit,hit_dodg_crit,player\n_Unit.PrintHitDodgCrit_Defaults=GetTriggerUnit,hit_dodg_crit_hit,GetTriggerPlayer\n_Unit.PrintHitDodgCrit_Category=TC_MU_UNIT\n\nUnit.ExtraMoveSpeed=0,unit,real\n_Unit.ExtraMoveSpeed_Defaults=GetTriggerUnit,500\n_Unit.ExtraMoveSpeed_Category=TC_MU_UNIT\n\n//物品库\nItem.Formula=0,itemcode,itemcode,itemcode,itemcode,itemcode,itemcode,itemcode,itemcode,integer\n_Item.Formula_Defaults=_,_,_,_,ches,ches,ches,ches,0\n_Item.Formula_Category=TC_MU_ITEM\n\n//音效库\nSound.InitUnitResponses=0,unitcode,unit_response_type,StringExt\n_Sound.InitUnitResponses_Defaults=_,unit_response_type1,_\n_Sound.InitUnitResponses_Category=TC_MU_SOUND\n\n//过程库\nprocess.Create2=0,unit,string,integer,boolean\n_process.Create2_Defaults=GetTriggerUnit,\"移动\",100,true\n_process.Create2_Category=TC_MU_PROCESS\n\nprocess.Remove=0,integer\n_process.Remove_Defaults=_\n_process.Remove_Category=TC_MU_PROCESS\n\nprocess.Cover=0,unit,integer,string\n_process.Cover_Defaults=GetTriggerUnit,100,\"移动\"\n_process.Cover_Category=TC_MU_PROCESS\n\nprocess.SetUper=0,integer,integer\n_process.SetUper_Defaults=_,100\n_process.SetUper_Category=TC_MU_PROCESS\n\n//事件库\nEvent.ReduceDamage=0,real\n_Event.ReduceDamage_Defaults=100\n_Event.ReduceDamage_Category=TC_MU_EVENT\n\nEvent.AddHeal=0,real\n_Event.AddHeal_Defaults=100\n_Event.AddHeal_Category=TC_MU_EVENT\n\nEvent.UserEventStart=0,scriptcode\n_Event.UserEventStart_Category=TC_MU_EVENT\n\nEvent.SkipTriggers=0\n_Event.SkipTriggers_Category=TC_MU_EVENT\n\nEvent.BlockCurrentModule=0\n_Event.BlockCurrentModule_Category=TC_MU_EVENT\n\n//弹幕库\nMover.SetMover=0,unit\n_Mover.SetMover_Defaults=bj_lastCreatedUnit\n_Mover.SetMover_Category=TC_MU_MOVER\n\nMover.SetStateReal=0,unit,mover_state_real,real\n_Mover.SetStateReal_Defaults=bj_lastCreatedUnit,mover_state_real1,0\n_Mover.SetStateReal_Category=TC_MU_MOVER\n\n//YD Ability\nYDWEJumpTimer=0,unit,real,real,real,real,real\n_YDWEJumpTimer_Defaults=GetTriggerUnit,0,800,2,0.01,300\n_YDWEJumpTimer_Limits=_,_,0,360,0,_,0,_,0.03,_,0,_\n_YDWEJumpTimer_Category=TC_YDAB\n\n//function YDWEMeatHook takes unit lTl,location lng,integer uid1,integer uid2,real distance,real dis,real damage,real timeout returns nothing\nYDWEMeatHook=0,unit,location,unitcode,unitcode,real,real,real,real\n_YDWEMeatHook_Defaults=GetTriggerUnit,GetSpellTargetLoc,_,_,2000,35,100,0.03\n_YDWEMeatHook_Limits=_,_,_,_,_,_,_,_,0,_,0,_,0,_,0.01,_\n_YDWEMeatHook_Category=TC_YDAB\n\nYDWETimerPatternJumpAttack=0,unit,real,real,real,real,real,real,string,modelfile\n_YDWETimerPatternJumpAttack_Defaults=GetTriggerUnit,0,800,1,0.03,100,0,\"chest\",_\n_YDWETimerPatternJumpAttack_Limits=_,_,0,360,0,_,0.01,_,0.01,_,0,_,0,_,_,_,_,_\n_YDWETimerPatternJumpAttack_Category=TC_YDAB\n\nYDWETimerPatternMoonPriestessArrow=0,unit,real,real,real,real,integer,abilcode,unitcode,unitorderutarg,string,modelfile\n_YDWETimerPatternMoonPriestessArrow_Defaults=GetTriggerUnit,0,800,1,0.03,1,_,_,UnitOrderAttackUnit,\"overhead\",_\n_YDWETimerPatternMoonPriestessArrow_Limits=_,_,0,360,0,_,0.01,_,0.01,_,1,_,_,_,_,_,_,_,_,_,_,_\n_YDWETimerPatternMoonPriestessArrow_Category=TC_YDAB\n\nYDWETimerPatternRushSlide=0,unit,real,real,real,real,real,boolean,boolean,boolean,string,modelfile,modelfile\n_YDWETimerPatternRushSlide_Defaults=GetTriggerUnit,0,800,1,0.03,0,false,false,false,\"origin\",_,_\n_YDWETimerPatternRushSlide_Limits=_,_,0,360,0,_,0.01,_,0.01,_,0,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_\n_YDWETimerPatternRushSlide_Category=TC_YDAB\n\nYDWEAroundSystem=0,unit,unit,real,real,real,real,real\n_YDWEAroundSystem_Defaults=GetLastCreatedUnit,GetTriggerUnit,8,3,0,5,0.03\n_YDWEAroundSystem_Limits=_,_,_,_,_,_,_,_,_,_,0,_,0.01,_\n_YDWEAroundSystem_Category=TC_YDAB\n\n//YD System\n\nYDWENewItemsFormula=0,itemcode,integer,itemcode,integer,itemcode,integer,itemcode,integer,itemcode,integer,itemcode,integer,itemcode\n_YDWENewItemsFormula_Defaults=ches,0,ches,0,ches,0,ches,0,ches,0,ches,0,bzbe\n_YDWENewItemsFormula_Limits=_,_,0,_,_,_,0,_,_,_,0,_,_,_,0,_,_,_,0,_,_,_,0,_,_,_\n_YDWENewItemsFormula_Category=TC_YDST\n\nYDWE_TP_PauseTimerPeriodic=0,integer\n_YDWE_TP_PauseTimerPeriodic_Defaults=_\n_YDWE_TP_PauseTimerPeriodic_Category=TC_YDST\n\nYDWE_TP_SetTimeInterval=0,integer,real\n_YDWE_TP_SetTimeInterval_Defaults=_,0.03\n_YDWE_TP_SetTimeInterval_Limits=_,_,0.01,_\n_YDWE_TP_SetTimeInterval_Category=TC_YDST\n\nYDWEAttackWaveTimer=0,player,integer,unitcode,location,real,location,real\n_YDWEAttackWaveTimer_Defaults=Player00,1,hfoo,_,RealUnitFacing,_,2\n_YDWEAttackWaveTimer_Limits=_,_,1,_,0,_,0,_,0,360,_,_,0.01,_\n_YDWEAttackWaveTimer_Category=TC_YDST\n\nYDWERemoveAttackWaveByUnitID=0,unitcode,location,real\n_YDWERemoveAttackWaveByUnitID_Defaults=hfoo,_,2\n_YDWERemoveAttackWaveByUnitID_Limits=_,_,_,_,0.01,_\n_YDWERemoveAttackWaveByUnitID_Category=TC_YDST\n\nYDWERemoveAttackWaveByTimer=0,timer\n_YDWERemoveAttackWaveByTimer_Defaults=YDWERemoveAttackWaveReturnTimer\n_YDWERemoveAttackWaveByTimer_Category=TC_YDST\n\n//MulItemSlot\nYDWEDoubleItemSlotByAbility=0,unit,abilcode,unitcode,integer\n_YDWEDoubleItemSlotByAbility_Defaults=GetTriggerUnit,_,_,3\n_YDWEDoubleItemSlotByAbility_Limits=_,_,_,_,_,_,1,10\n_YDWEDoubleItemSlotByAbility_Category=TC_YDST\n\nYDWEDoubleItemSlotByItem=0,unit,itemcode,unitcode,integer\n_YDWEDoubleItemSlotByItem_Defaults=GetTriggerUnit,_,_,3\n_YDWEDoubleItemSlotByItem_Limits=_,_,_,_,_,_,1,10\n_YDWEDoubleItemSlotByItem_Category=TC_YDST\n\nYDWEGeneralBounsSystemUnitSetBonus=0,unit,bonusType,unitstatechangetype,integer\n_YDWEGeneralBounsSystemUnitSetBonus_Defaults=GetTriggerUnit,bonusTypeA,unitstatechangetypeA,300\n_YDWEGeneralBounsSystemUnitSetBonus_Category=TC_YDST\n\n//YD AI\nYDWESetGuard=0,unit,unit,real,real,real,real,integer\n_YDWESetGuard_Defaults=_,_,2,800,1200,1500,75\n_YDWESetGuard_Limits=_,_,_,_,0.01,_,0,_,0,_,0,_,0,100\n_YDWESetGuard_Category=TC_YDAI\n\nYDWERemoveGuard=0,unit\n_YDWERemoveGuard_Defaults=_\n_YDWERemoveGuard_Limits=_,_\n_YDWERemoveGuard_Category=TC_YDAI\n\nYDWEAIRecordAbility=0,unitcode,abilcode,abilcode,abilcode,abilcode,abilcode\n_YDWEAIRecordAbility_Defaults=Hamg,_,_,_,_,_\n_YDWEAIRecordAbility_Limits=_,_,_,_,_,_,_,_,_,_,_,_\n_YDWEAIRecordAbility_Category=TC_YDAI\n\nYDWEAIRecordLearn_sequence=0,unitcode,string,string,string,string,string\n_YDWEAIRecordLearn_sequence_Defaults=Hamg,^1^3^5^,^2^4^7^,^8^9^10^,^6^,null\n_YDWEAIRecordLearn_sequence_Limits=_,_,_,_,_,_,_,_,_,_,_,_\n_YDWEAIRecordLearn_sequence_Category=TC_YDAI\n\nYDWEHeroLearnSkillAI=0,unit,integer\n_YDWEHeroLearnSkillAI_Defaults=GetTriggerUnit,1\n_YDWEHeroLearnSkillAI_Limits=_,_,1,_\n_YDWEHeroLearnSkillAI_Category=TC_YDAI\n\nYDWEHeroMaxSkillAI=0,unit\n_YDWEHeroMaxSkillAI_Defaults=GetTriggerUnit\n_YDWEHeroMaxSkillAI_Limits=_,_\n_YDWEHeroMaxSkillAI_Category=TC_YDAI\n\nYDWEAddAIOrder=0,unit,attackorattackedevent,targettype,unitorderutarg,unitorderptarg,unitordernotarg,integer\n_YDWEAddAIOrder_Defaults=GetTriggerUnit,attackorattackedeventB,targettypeA,UnitOrderAttackUnitnull,UnitOrderAttacknull,UnitOrderStopnull,20\n_YDWEAddAIOrder_Limits=_,_,_,_,_,_,_,_,_,_,_,_,1,100\n_YDWEAddAIOrder_Category=TC_YDAI\n\n//YD Aganist Fate\nYDWEEnumUnitsInRangeMultiple=0,real,real,real\n_YDWEEnumUnitsInRangeMultiple_Defaults=0,0,512\n_YDWEEnumUnitsInRangeMultiple_Limits=_,_,_,_,_,_,0,_,_,_\n_YDWEEnumUnitsInRangeMultiple_Category=TC_YDBF\n\nYDWESetAnyTypeLocalVariable=0,typename,scriptcode,Null\n_YDWESetAnyTypeLocalVariable_Defaults=_,_,_\n_YDWESetAnyTypeLocalVariable_Category=TC_YDBF\n\nYDWEForLoopLocVarMultiple=1,scriptcode,integer,integer\n_YDWEForLoopLocVarMultiple_Defaults=_,1,10\n_YDWEForLoopLocVarMultiple_Category=TC_YDBF\n\nYDWETimerStartMultiple=0,timer,real,periodicoption\n_YDWETimerStartMultiple_Defaults=CreateTimer,0.03,PeriodicOptionOneTime\n_YDWETimerStartMultiple_Limits=_,_,0,_,_,_\n_YDWETimerStartMultiple_Category=TC_YDBF\n\nYDWETimerStartFlush=0,nothing\n_YDWETimerStartFlush_Category=TC_YDBF\n\nYDWERegisterTriggerMultiple=0,trigger\n_YDWERegisterTriggerMultiple_Defaults=CreateTrigger\n_YDWERegisterTriggerMultiple_Category=TC_YDBF\n\nYDWERegisterTriggerFlush=0,nothing\n_YDWERegisterTriggerFlush_Category=TC_YDBF\n\nYDWESaveAnyTypeDataByUserData=0,typename,Null,scriptcode,typename,Null\n_YDWESaveAnyTypeDataByUserData_Defaults=_,_,_,_,_\n_YDWESaveAnyTypeDataByUserData_Category=TC_YDBF\n\nYDWEFlushAllByUserData=0,typename,Null\n_YDWEFlushAllByUserData_Defaults=_,_\n_YDWEFlushAllByUserData_Category=TC_YDBF\n\nYDWEFlushAnyTypeDataByUserData=0,typename,Null,typename,scriptcode\n_YDWEFlushAnyTypeDataByUserData_Defaults=_,_,_,_\n_YDWEFlushAnyTypeDataByUserData_Category=TC_YDBF\n\n\n//YD Save Load\nYDWE_PreloadSL_SetFile=0,player,string,string,integer\n_YDWE_PreloadSL_SetFile_Defaults=Player00,_,_,_\n_YDWE_PreloadSL_SetFile_Limits=_,_,_,_,_,_,1,16\n_YDWE_PreloadSL_SetFile_Category=TC_YDSL\n\nYDWE_PreloadSL_Save=0,player,string,string,integer\n_YDWE_PreloadSL_Save_Defaults=Player00,_,_,_\n_YDWE_PreloadSL_Save_Limits=_,_,_,_,_,_,1,500\n_YDWE_PreloadSL_Save_Category=TC_YDSL\n\nYDWE_PreloadSL_Load=0,player,string,string,integer\n_YDWE_PreloadSL_Load_Defaults=Player00,_,_,_\n_YDWE_PreloadSL_Load_Limits=_,_,_,_,_,_,1,500\n_YDWE_PreloadSL_Load_Category=TC_YDSL\n\nYDWE_PreloadSL_Set=0,player,string,integer,integer\n_YDWE_PreloadSL_Set_Defaults=Player00,_,_,_\n_YDWE_PreloadSL_Set_Limits=_,_,_,_,1,500,_,_\n_YDWE_PreloadSL_Set_Category=TC_YDSL\n\n//YD LocalVariable\nYDWELocalVariableInitiliation=0,nothing\n_YDWELocalVariableInitiliation_Category=TC_YDLC\n\nYDWELocalVariableEnd=0,nothing\n_YDWELocalVariableEnd_Category=TC_YDLC\n\nYDWESetLocalVariableInteger=0,string,integer\n_YDWESetLocalVariableInteger_Defaults=_,0\n_YDWESetLocalVariableInteger_Category=TC_YDLC\n\nYDWESetLocalVariableIntegerArray=0,string,integer,integer\n_YDWESetLocalVariableIntegerArray_Defaults=_,1,0\n_YDWESetLocalVariableIntegerArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableIntegerArray_Category=TC_YDLC\n\nYDWESetLocalVariableReal=0,string,real\n_YDWESetLocalVariableReal_Defaults=_,0\n_YDWESetLocalVariableReal_Category=TC_YDLC\n\nYDWESetLocalVariableRealArray=0,string,integer,real\n_YDWESetLocalVariableRealArray_Defaults=_,1,0\n_YDWESetLocalVariableRealArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableRealArray_Category=TC_YDLC\n\nYDWESetLocalVariableString=0,string,string\n_YDWESetLocalVariableString_Defaults=_,null\n_YDWESetLocalVariableString_Category=TC_YDLC\n\nYDWESetLocalVariableStringArray=0,string,integer,string\n_YDWESetLocalVariableStringArray_Defaults=_,1,null\n_YDWESetLocalVariableStringArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableStringArray_Category=TC_YDLC\n\nYDWESetLocalVariableBoolean=0,string,boolean\n_YDWESetLocalVariableBoolean_Defaults=_,false\n_YDWESetLocalVariableBoolean_Category=TC_YDLC\n\nYDWESetLocalVariableBooleanArray=0,string,integer,boolean\n_YDWESetLocalVariableBooleanArray_Defaults=_,1,false\n_YDWESetLocalVariableBooleanArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableBooleanArray_Category=TC_YDLC\n\nYDWESetLocalVariableUnit=0,string,unit\n_YDWESetLocalVariableUnit_Defaults=_,GetTriggerUnit\n_YDWESetLocalVariableUnit_Category=TC_YDLC\n\nYDWESetLocalVariableUnitArray=0,string,integer,unit\n_YDWESetLocalVariableUnitArray_Defaults=_,1,GetTriggerUnit\n_YDWESetLocalVariableUnitArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableUnitArray_Category=TC_YDLC\n\nYDWESetLocalVariableUnitID=0,string,unitcode\n_YDWESetLocalVariableUnitID_Defaults=_,hfoo\n_YDWESetLocalVariableUnitID_Category=TC_YDLC\n\nYDWESetLocalVariableUnitIDArray=0,string,integer,unitcode\n_YDWESetLocalVariableUnitIDArray_Defaults=_,1,hfoo\n_YDWESetLocalVariableUnitIDArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableUnitIDArray_Category=TC_YDLC\n\nYDWESetLocalVariableAbilityID=0,string,abilcode\n_YDWESetLocalVariableAbilityID_Defaults=_,Aloc\n_YDWESetLocalVariableAbilityID_Category=TC_YDLC\n\nYDWESetLocalVariableAbilityIDArray=0,string,integer,abilcode\n_YDWESetLocalVariableAbilityIDArray_Defaults=_,1,Aloc\n_YDWESetLocalVariableAbilityIDArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableAbilityIDArray_Category=TC_YDLC\n\nYDWESetLocalVariableItem=0,string,item\n_YDWESetLocalVariableItem_Defaults=_,GetManipulatedItem\n_YDWESetLocalVariableItem_Category=TC_YDLC\n\nYDWESetLocalVariableItemArray=0,string,integer,item\n_YDWESetLocalVariableItemArray_Defaults=_,1,GetManipulatedItem\n_YDWESetLocalVariableItemArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableItemArray_Category=TC_YDLC\n\nYDWESetLocalVariableItemID=0,string,itemcode\n_YDWESetLocalVariableItemID_Defaults=_,spsh\n_YDWESetLocalVariableItemID_Category=TC_YDLC\n\nYDWESetLocalVariableItemIDArray=0,string,integer,itemcode\n_YDWESetLocalVariableItemIDArray_Defaults=_,1,spsh\n_YDWESetLocalVariableItemIDArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableItemIDArray_Category=TC_YDLC\n\nYDWESetLocalVariableLocation=0,string,location\n_YDWESetLocalVariableLocation_Defaults=_,GetSpellTargetLoc\n_YDWESetLocalVariableLocation_Category=TC_YDLC\n\nYDWESetLocalVariableLocationArray=0,string,integer,location\n_YDWESetLocalVariableLocationArray_Defaults=_,1,GetSpellTargetLoc\n_YDWESetLocalVariableLocationArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableLocationArray_Category=TC_YDLC\n\nYDWESetLocalVariableGroup=0,string,group\n_YDWESetLocalVariableGroup_Defaults=_,bj_lastCreatedGroup\n_YDWESetLocalVariableGroup_Category=TC_YDLC\n\nYDWESetLocalVariableGroupArray=0,string,integer,group\n_YDWESetLocalVariableGroupArray_Defaults=_,1,bj_lastCreatedGroup\n_YDWESetLocalVariableGroupArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableGroupArray_Category=TC_YDLC\n\nYDWESetLocalVariableEffect=0,string,effect\n_YDWESetLocalVariableEffect_Defaults=_,GetLastCreatedEffectBJ\n_YDWESetLocalVariableEffect_Category=TC_YDLC\n\nYDWESetLocalVariableEffectArray=0,string,integer,effect\n_YDWESetLocalVariableEffectArray_Defaults=_,1,GetLastCreatedEffectBJ\n_YDWESetLocalVariableEffectArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableEffectArray_Category=TC_YDLC\n\nYDWESetLocalVariableRect=0,string,rect\n_YDWESetLocalVariableRect_Defaults=_,GetCurrentCameraBoundsMapRectBJ\n_YDWESetLocalVariableRect_Category=TC_YDLC\n\nYDWESetLocalVariableRectArray=0,string,integer,rect\n_YDWESetLocalVariableRectArray_Defaults=_,1,GetCurrentCameraBoundsMapRectBJ\n_YDWESetLocalVariableRectArray_Limits=_,_,0,_,_,_\n_YDWESetLocalVariableRectArray_Category=TC_YDLC\n\nSetRandomSeed=0,integer\n_SetRandomSeed_Defaults=_\n_SetRandomSeed_Limits=0,_\n_SetRandomSeed_Category=TC_MATH\n\n//YD Function\nYDWESetAttackDamageWeaponType=0,attacktype,damagetype,weapontype\n_YDWESetAttackDamageWeaponType_Defaults=AttackTypeNormal,DamageTypeNormal,WEAPON_TYPE_WHOKNOWS\n_YDWESetAttackDamageWeaponType_Category=TC_YDFC\n\nYDWESetEventDamage=0,real\n_YDWESetEventDamage_Defaults=0.\n_YDWESetEventDamage_Category=TC_YDFC\n\nYDWEFlyEnable=0,unit\n_YDWEFlyEnable_Defaults=GetTriggerUnit\n_YDWEFlyEnable_Category=TC_YDFC\n\nYDWESetMapLimitCoordinate=0,real,real,real,real\n_YDWESetMapLimitCoordinate_Defaults=GetCameraBoundMinX,GetCameraBoundMaxX,GetCameraBoundMinY,GetCameraBoundMaxY\n_YDWESetMapLimitCoordinate_Category=TC_YDFC\n\nYDWELifeChange=0,unit,unitstatechangetype,integer,abilcode\n_YDWELifeChange_Defaults=GetTriggerUnit,unitstatechangetypeA,300,_\n_YDWELifeChange_Limits=_,_,_,_,0,99999,_,_\n_YDWELifeChange_Category=TC_YDFC\n\nYDWEManaChange=0,unit,unitstatechangetype,integer,abilcode\n_YDWEManaChange_Defaults=GetTriggerUnit,unitstatechangetypeA,300,_\n_YDWEManaChange_Limits=_,_,_,_,0,99999,_,_\n_YDWEManaChange_Category=TC_YDFC\n\n// YDWEOpenObjectMerger=0,nothing\n// _YDWEOpenObjectMerger_Category=TC_YDFC\n\n//YD Game Data\nYDWERHSetGameWinner=0,integer\n_YDWERHSetGameWinner_Defaults=0\n_YDWERHSetGameWinner_Limits=0,15\n_YDWERHSetGameWinner_Category=TC_YDHIDE\n\nYDWERecordSetTitle=0,integer,string\n_YDWERecordSetTitle_Defaults=0,_,\n_YDWERecordSetTitle_Limits=0,7,_,_\n_YDWERecordSetTitle_Category=TC_YDSL\n\nYDWERecordSetI=0,player,string,integer\n_YDWERecordSetI_Defaults=Player00,_,5\n_YDWERecordSetI_Category=TC_YDSL\n\nYDWERecordSave=0,player\n_YDWERecordSave_Defaults=Player00\n_YDWERecordSave_Category=TC_YDSL\n\nYDWERecordClear=0,player\n_YDWERecordClear_Defaults=Player00\n_YDWERecordClear_Category=TC_YDSL\n\n//YD Load\n\nYDWEFlushMissionByInteger=0,integer\n_YDWEFlushMissionByInteger_Defaults=0\n_YDWEFlushMissionByInteger_Limits=0,_\n_YDWEFlushMissionByInteger_Category=TC_YDLD\n\nYDWEFlushMissionByString=0,string\n_YDWEFlushMissionByString_Defaults=null\n_YDWEFlushMissionByString_Category=TC_YDLD\n\nYDWESaveIntegerByInteger=0,integer,integer,integer\n_YDWESaveIntegerByInteger_Defaults=0,0,0\n_YDWESaveIntegerByInteger_Limits=0,_,0,_,_,_\n_YDWESaveIntegerByInteger_Category=TC_YDLD\n\nYDWESaveIntegerByString=0,string,string,integer\n_YDWESaveIntegerByString_Defaults=null,null,0\n_YDWESaveIntegerByString_Category=TC_YDLD\n\nYDWESaveRealByInteger=0,integer,integer,real\n_YDWESaveRealByInteger_Defaults=0,0,0\n_YDWESaveRealByInteger_Limits=0,_,0,_,_,_\n_YDWESaveRealByInteger_Category=TC_YDLD\n\nYDWESaveRealByString=0,string,string,real\n_YDWESaveRealByString_Defaults=null,null,0\n_YDWESaveRealByString_Category=TC_YDLD\n\nYDWESaveStringByInteger=0,integer,integer,string\n_YDWESaveStringByInteger_Defaults=0,0,null\n_YDWESaveStringByInteger_Limits=0,_,0,_,_,_\n_YDWESaveStringByInteger_Category=TC_YDLD\n\nYDWESaveStringByString=0,string,string,string\n_YDWESaveStringByString_Defaults=null,null,null\n_YDWESaveStringByString_Category=TC_YDLD\n\nYDWESaveBooleanByInteger=0,integer,integer,boolean\n_YDWESaveBooleanByInteger_Defaults=0,0,false\n_YDWESaveBooleanByInteger_Limits=0,_,0,_,_,_\n_YDWESaveBooleanByInteger_Category=TC_YDLD\n\nYDWESaveBooleanByString=0,string,string,boolean\n_YDWESaveBooleanByString_Defaults=null,null,false\n_YDWESaveBooleanByString_Category=TC_YDLD\n\nYDWESaveUnitByInteger=0,integer,integer,unit\n_YDWESaveUnitByInteger_Defaults=0,0,GetTriggerUnit\n_YDWESaveUnitByInteger_Limits=0,_,0,_,_,_\n_YDWESaveUnitByInteger_Category=TC_YDLD\n\nYDWESaveUnitByString=0,string,string,unit\n_YDWESaveUnitByString_Defaults=null,null,GetTriggerUnit\n_YDWESaveUnitByString_Category=TC_YDLD\n\nYDWESaveUnitIDByInteger=0,integer,integer,unitcode\n_YDWESaveUnitIDByInteger_Defaults=0,0,hfoo\n_YDWESaveUnitIDByInteger_Limits=0,_,0,_,_,_\n_YDWESaveUnitIDByInteger_Category=TC_YDLD\n\nYDWESaveUnitIDByString=0,string,string,unitcode\n_YDWESaveUnitIDByString_Defaults=null,null,hfoo\n_YDWESaveUnitIDByString_Category=TC_YDLD\n\nYDWESaveAbilityIDByInteger=0,integer,integer,abilcode\n_YDWESaveAbilityIDByInteger_Defaults=0,0,Aloc\n_YDWESaveAbilityIDByInteger_Limits=0,_,0,_,_,_\n_YDWESaveAbilityIDByInteger_Category=TC_YDLD\n\nYDWESaveAbilityIDByString=0,string,string,abilcode\n_YDWESaveAbilityIDByString_Defaults=null,null,Aloc\n_YDWESaveAbilityIDByString_Category=TC_YDLD\n\nYDWESaveItemByInteger=0,integer,integer,item\n_YDWESaveItemByInteger_Defaults=0,0,GetManipulatedItem\n_YDWESaveItemByInteger_Limits=0,_,0,_,_,_\n_YDWESaveItemByInteger_Category=TC_YDLD\n\nYDWESaveItemByString=0,string,string,item\n_YDWESaveItemByString_Defaults=null,null,GetManipulatedItem\n_YDWESaveItemByString_Category=TC_YDLD\n\nYDWESaveItemIDByInteger=0,integer,integer,itemcode\n_YDWESaveItemIDByInteger_Defaults=0,0,texp\n_YDWESaveItemIDByInteger_Limits=0,_,0,_,_,_\n_YDWESaveItemIDByInteger_Category=TC_YDLD\n\nYDWESaveItemIDByString=0,string,string,itemcode\n_YDWESaveItemIDByString_Defaults=null,null,texp\n_YDWESaveItemIDByString_Category=TC_YDLD\n\nYDWESavePlayerByInteger=0,integer,integer,player\n_YDWESavePlayerByInteger_Defaults=0,0,GetEnumPlayer\n_YDWESavePlayerByInteger_Limits=0,_,0,_,_,_\n_YDWESavePlayerByInteger_Category=TC_YDLD\n\nYDWESavePlayerByString=0,string,string,player\n_YDWESavePlayerByString_Defaults=null,null,GetEnumPlayer\n_YDWESavePlayerByString_Category=TC_YDLD\n\nYDWESaveTimerByInteger=0,integer,integer,timer\n_YDWESaveTimerByInteger_Defaults=0,0,GetExpiredTimer\n_YDWESaveTimerByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTimerByInteger_Category=TC_YDLD\n\nYDWESaveTimerByString=0,string,string,timer\n_YDWESaveTimerByString_Defaults=null,null,GetExpiredTimer\n_YDWESaveTimerByString_Category=TC_YDLD\n\nYDWESaveTriggerByInteger=0,integer,integer,trigger\n_YDWESaveTriggerByInteger_Defaults=0,0,GetTriggeringTrigger\n_YDWESaveTriggerByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTriggerByInteger_Category=TC_YDLD\n\nYDWESaveTriggerByString=0,string,string,trigger\n_YDWESaveTriggerByString_Defaults=null,null,GetTriggeringTrigger\n_YDWESaveTriggerByString_Category=TC_YDLD\n\nYDWESaveLocationByInteger=0,integer,integer,location\n_YDWESaveLocationByInteger_Defaults=0,0,GetSpellTargetLoc\n_YDWESaveLocationByInteger_Limits=0,_,0,_,_,_\n_YDWESaveLocationByInteger_Category=TC_YDLD\n\nYDWESaveLocationByString=0,string,string,location\n_YDWESaveLocationByString_Defaults=null,null,GetSpellTargetLoc\n_YDWESaveLocationByString_Category=TC_YDLD\n\nYDWESaveGroupByInteger=0,integer,integer,group\n_YDWESaveGroupByInteger_Defaults=0,0,GetLastCreatedGroup\n_YDWESaveGroupByInteger_Limits=0,_,0,_,_,_\n_YDWESaveGroupByInteger_Category=TC_YDLD\n\nYDWESaveGroupByString=0,string,string,group\n_YDWESaveGroupByString_Defaults=null,null,GetLastCreatedGroup\n_YDWESaveGroupByString_Category=TC_YDLD\n\nYDWESaveMultiboardByInteger=0,integer,integer,multiboard\n_YDWESaveMultiboardByInteger_Defaults=0,0,GetLastCreatedMultiboard\n_YDWESaveMultiboardByInteger_Limits=0,_,0,_,_,_\n_YDWESaveMultiboardByInteger_Category=TC_YDLD\n\nYDWESaveMultiboardByString=0,string,string,multiboard\n_YDWESaveMultiboardByString_Defaults=null,null,GetLastCreatedMultiboard\n_YDWESaveMultiboardByString_Category=TC_YDLD\n\nYDWESaveMultiboardItemByInteger=0,integer,integer,multiboarditem\n_YDWESaveMultiboardItemByInteger_Defaults=0,0,_\n_YDWESaveMultiboardItemByInteger_Limits=0,_,0,_,_,_\n_YDWESaveMultiboardItemByInteger_Category=TC_YDLD\n\nYDWESaveMultiboardItemByString=0,string,string,multiboarditem\n_YDWESaveMultiboardItemByString_Defaults=null,null,_\n_YDWESaveMultiboardItemByString_Category=TC_YDLD\n\nYDWESaveTextTagByInteger=0,integer,integer,texttag\n_YDWESaveTextTagByInteger_Defaults=0,0,GetLastCreatedTextTag\n_YDWESaveTextTagByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTextTagByInteger_Category=TC_YDLD\n\nYDWESaveTextTagByString=0,string,string,texttag\n_YDWESaveTextTagByString_Defaults=null,null,GetLastCreatedTextTag\n_YDWESaveTextTagByString_Category=TC_YDLD\n\nYDWESaveLightningByInteger=0,integer,integer,lightning\n_YDWESaveLightningByInteger_Defaults=0,0,GetLastCreatedLightningBJ\n_YDWESaveLightningByInteger_Limits=0,_,0,_,_,_\n_YDWESaveLightningByInteger_Category=TC_YDLD\n\nYDWESaveLightningByString=0,string,string,lightning\n_YDWESaveLightningByString_Defaults=null,null,GetLastCreatedLightningBJ\n_YDWESaveLightningByString_Category=TC_YDLD\n\nYDWESaveRegionByInteger=0,integer,integer,region\n_YDWESaveRegionByInteger_Defaults=0,0,GetTriggeringRegion\n_YDWESaveRegionByInteger_Limits=0,_,0,_,_,_\n_YDWESaveRegionByInteger_Category=TC_YDLD\n\nYDWESaveRegionByString=0,string,string,region\n_YDWESaveRegionByString_Defaults=null,null,GetTriggeringRegion\n_YDWESaveRegionByString_Category=TC_YDLD\n\nYDWESaveRectByInteger=0,integer,integer,rect\n_YDWESaveRectByInteger_Defaults=0,0,GetCurrentCameraBoundsMapRectBJ\n_YDWESaveRectByInteger_Limits=0,_,0,_,_,_\n_YDWESaveRectByInteger_Category=TC_YDLD\n\nYDWESaveRectByString=0,string,string,rect\n_YDWESaveRectByString_Defaults=null,null,GetCurrentCameraBoundsMapRectBJ\n_YDWESaveRectByString_Category=TC_YDLD\n\nYDWESaveLeaderboardByInteger=0,integer,integer,leaderboard\n_YDWESaveLeaderboardByInteger_Defaults=0,0,GetLastCreatedLeaderboard\n_YDWESaveLeaderboardByInteger_Limits=0,_,0,_,_,_\n_YDWESaveLeaderboardByInteger_Category=TC_YDLD\n\nYDWESaveLeaderboardByString=0,string,string,leaderboard\n_YDWESaveLeaderboardByString_Defaults=null,null,GetLastCreatedLeaderboard\n_YDWESaveLeaderboardByString_Category=TC_YDLD\n\nYDWESaveEffectByInteger=0,integer,integer,effect\n_YDWESaveEffectByInteger_Defaults=0,0,GetLastCreatedEffectBJ\n_YDWESaveEffectByInteger_Limits=0,_,0,_,_,_\n_YDWESaveEffectByInteger_Category=TC_YDLD\n\nYDWESaveEffectByString=0,string,string,effect\n_YDWESaveEffectByString_Defaults=null,null,GetLastCreatedEffectBJ\n_YDWESaveEffectByString_Category=TC_YDLD\n\nYDWESaveDestructableByInteger=0,integer,integer,destructable\n_YDWESaveDestructableByInteger_Defaults=0,0,GetLastCreatedDestructable\n_YDWESaveDestructableByInteger_Limits=0,_,0,_,_,_\n_YDWESaveDestructableByInteger_Category=TC_YDLD\n\nYDWESaveDestructableByString=0,string,string,destructable\n_YDWESaveDestructableByString_Defaults=null,null,GetLastCreatedDestructable\n_YDWESaveDestructableByString_Category=TC_YDLD\n\nYDWESaveTriggerConditionByInteger=0,integer,integer,triggercondition\n_YDWESaveTriggerConditionByInteger_Defaults=0,0,_\n_YDWESaveTriggerConditionByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTriggerConditionByInteger_Category=TC_YDLD\n\nYDWESaveTriggerConditionByString=0,string,string,triggercondition\n_YDWESaveTriggerConditionByString_Defaults=null,null,_\n_YDWESaveTriggerConditionByString_Category=TC_YDLD\n\nYDWESaveTriggerActionByInteger=0,integer,integer,triggeraction\n_YDWESaveTriggerActionByInteger_Defaults=0,0,_\n_YDWESaveTriggerActionByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTriggerActionByInteger_Category=TC_YDLD\n\nYDWESaveTriggerActionByString=0,string,string,triggeraction\n_YDWESaveTriggerActionByString_Defaults=null,null,_\n_YDWESaveTriggerActionByString_Category=TC_YDLD\n\nYDWESaveTriggerEventByInteger=0,integer,integer,event\n_YDWESaveTriggerEventByInteger_Defaults=0,0,_\n_YDWESaveTriggerEventByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTriggerEventByInteger_Category=TC_YDLD\n\nYDWESaveTriggerEventByString=0,string,string,event\n_YDWESaveTriggerEventByString_Defaults=null,null,_\n_YDWESaveTriggerEventByString_Category=TC_YDLD\n\nYDWESaveForceByInteger=0,integer,integer,force\n_YDWESaveForceByInteger_Defaults=0,0,_\n_YDWESaveForceByInteger_Limits=0,_,0,_,_,_\n_YDWESaveForceByInteger_Category=TC_YDLD\n\nYDWESaveForceByString=0,string,string,force\n_YDWESaveForceByString_Defaults=null,null,_\n_YDWESaveForceByString_Category=TC_YDLD\n\nYDWESaveBoolexprByInteger=0,integer,integer,boolexpr\n_YDWESaveBoolexprByInteger_Defaults=0,0,_\n_YDWESaveBoolexprByInteger_Limits=0,_,0,_,_,_\n_YDWESaveBoolexprByInteger_Category=TC_YDLD\n\nYDWESaveBoolexprByString=0,string,string,boolexpr\n_YDWESaveBoolexprByString_Defaults=null,null,_\n_YDWESaveBoolexprByString_Category=TC_YDLD\n\nYDWESaveSoundByInteger=0,integer,integer,sound\n_YDWESaveSoundByInteger_Defaults=0,0,_\n_YDWESaveSoundByInteger_Limits=0,_,0,_,_,_\n_YDWESaveSoundByInteger_Category=TC_YDLD\n\nYDWESaveSoundByString=0,string,string,sound\n_YDWESaveSoundByString_Defaults=null,null,_\n_YDWESaveSoundByString_Category=TC_YDLD\n\nYDWESaveTimerDialogByInteger=0,integer,integer,timerdialog\n_YDWESaveTimerDialogByInteger_Defaults=0,0,_\n_YDWESaveTimerDialogByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTimerDialogByInteger_Category=TC_YDLD\n\nYDWESaveTimerDialogByString=0,string,string,timerdialog\n_YDWESaveTimerDialogByString_Defaults=null,null,_\n_YDWESaveTimerDialogByString_Category=TC_YDLD\n\nYDWESaveTrackableByInteger=0,integer,integer,trackable\n_YDWESaveTrackableByInteger_Defaults=0,0,_\n_YDWESaveTrackableByInteger_Limits=0,_,0,_,_,_\n_YDWESaveTrackableByInteger_Category=TC_YDLD\n\nYDWESaveTrackableByString=0,string,string,trackable\n_YDWESaveTrackableByString_Defaults=null,null,_\n_YDWESaveTrackableByString_Category=TC_YDLD\n\nYDWESaveDialogByInteger=0,integer,integer,dialog\n_YDWESaveDialogByInteger_Defaults=0,0,_\n_YDWESaveDialogByInteger_Limits=0,_,0,_,_,_\n_YDWESaveDialogByInteger_Category=TC_YDLD\n\nYDWESaveDialogByString=0,string,string,dialog\n_YDWESaveDialogByString_Defaults=null,null,_\n_YDWESaveDialogByString_Category=TC_YDLD\n\nYDWESaveButtonByInteger=0,integer,integer,button\n_YDWESaveButtonByInteger_Defaults=0,0,_\n_YDWESaveButtonByInteger_Limits=0,_,0,_,_,_\n_YDWESaveButtonByInteger_Category=TC_YDLD\n\nYDWESaveButtonByString=0,string,string,button\n_YDWESaveButtonByString_Defaults=null,null,_\n_YDWESaveButtonByString_Category=TC_YDLD\n\nYDWESaveQuestByInteger=0,integer,integer,quest\n_YDWESaveQuestByInteger_Defaults=0,0,GetLastCreatedQuestBJ\n_YDWESaveQuestByInteger_Limits=0,_,0,_,_,_\n_YDWESaveQuestByInteger_Category=TC_YDLD\n\nYDWESaveQuestByString=0,string,string,quest\n_YDWESaveQuestByString_Defaults=null,null,GetLastCreatedQuestBJ\n_YDWESaveQuestByString_Category=TC_YDLD\n\nYDWESaveQuestItemByString=0,string,string,questitem\n_YDWESaveQuestItemByString_Defaults=null,null,GetLastCreatedQuestItemBJ\n_YDWESaveQuestItemByString_Category=TC_YDLD\n\nYDWESaveQuestItemByInteger=0,integer,integer,questitem\n_YDWESaveQuestItemByInteger_Defaults=0,0,GetLastCreatedQuestItemBJ\n_YDWESaveQuestItemByInteger_Limits=0,_,0,_,_,_\n_YDWESaveQuestItemByInteger_Category=TC_YDLD\n\n//YD Special Effect\n//YDWEMusicFountain=0,location,real,real,real,real,real,lightningtype\n//_YDWEMusicFountain_Defaults=_,1,1.01,1000,0.98,0,LightningTypeCLPB\n//_YDWEMusicFountain_Limits=_,_,0,_,0,_,0,_,0,_,0,_,_,_\n//_YDWEMusicFountain_Category=TC_YDSE\nYDWECreateEwsp=0,unit,unitcode,integer,real,real,real,real\n_YDWECreateEwsp_Defaults=GetTriggerUnit,hfoo,1,300,20,0.01,1\n_YDWECreateEwsp_Limits=_,_,_,_,1,_,0,_,0,_,0.01,_,_,_\n_YDWECreateEwsp_Category=TC_YDSE\n\nYDWECreateLine=0,unit,unitcode,integer,real,real,real,real,real,real,real,real\n_YDWECreateLine_Defaults=GetTriggerUnit,ewsp,12,50,60,30,0.03,0,10,100,30\n_YDWECreateLine_Limits=_,_,_,_,0,_,-360,360,0,_,0,_,0.01,_,0,_,0,_,1.0,1000.0,_,_\n_YDWECreateLine_Category=TC_YDSE\n\n//Script System actions\nYDWEInitCinematicSystem=0,nothing\n_YDWEInitCinematicSystem_Defaults=\n_YDWEInitCinematicSystem_Category=TC_SCRIPTSET\n\nYDWECinematicCameraDisable=0,nothing\n_YDWECinematicCameraDisable_Defaults=\n_YDWECinematicCameraDisable_Category=TC_SCRIPTSET\n\nYDWECinSInitTempPoint=0,location\n_YDWECinSInitTempPoint_Defaults=Location\n_YDWECinSInitTempPoint_Category=TC_SCRIPTSET\n\nYDWEScriptSystemPeriod=0,real\n_YDWEScriptSystemPeriod_Defaults=0.02\n_YDWEScriptSystemPeriod_Category=TC_SCRIPTSET\n\nYDWEParticlePeriod=0,real\n_YDWEParticlePeriod_Defaults=0.02\n_YDWEParticlePeriod_Category=TC_SCRIPTSET\n\nYDWECameraPeriod=0,real\n_YDWECameraPeriod_Defaults=0.02\n_YDWECameraPeriod_Category=TC_SCRIPTSET\n\nYDWEFadeFilterUnit=0,unitcode\n_YDWEFadeFilterUnit_Defaults=_\n_YDWEFadeFilterUnit_Category=TC_SCRIPTSET\n\nYDWEWriteToScene=0,integer\n_YDWEWriteToScene_Defaults=1\n_YDWEWriteToScene_Limits=1,_\n_YDWEWriteToScene_Category=TC_SCRIPTSET\n\nYDWEPlayScene=0,integer\n_YDWEPlayScene_Defaults=1\n_YDWEPlayScene_Limits=1,_\n_YDWEPlayScene_Category=TC_SCRIPTSET\n\nYDWEScriptNextScene=0,real\n_YDWEScriptNextScene_Defaults=2\n_YDWEScriptNextScene_Limits=0,_\n_YDWEScriptNextScene_Category=TC_SCRIPTSET\n\nYDWEScriptExternalFunc=0,real,string\n_YDWEScriptExternalFunc_Defaults=2,EverguoIsHandsome\n_YDWEScriptExternalFunc_Limits=0,_,_,_\n_YDWEScriptExternalFunc_Category=TC_SCRIPTSET\n\nYDWEScriptSubtitleLine=0,real,string\n_YDWEScriptSubtitleLine_Defaults=2,EverguoIsHandsome\n_YDWEScriptSubtitleLine_Limits=0,_,_,_\n_YDWEScriptSubtitleLine_Category=TC_SCRIPTSET\n\nYDWEScriptSubtitleClear=0,real\n_YDWEScriptSubtitleClear_Defaults=2\n_YDWEScriptSubtitleClear_Limits=0,_\n_YDWEScriptSubtitleClear_Category=TC_SCRIPTSET\n\nYDWEActorCreate=0,player,integer,unitcode\n_YDWEActorCreate_Defaults=Player00,1,Edem\n_YDWEActorCreate_Limits=_,_,1,_,_,_\n_YDWEActorCreate_Category=TC_SCRIPTSET\n\nYDWEScriptActAbilityLvl=0,real,integer,abilcode,integer\n_YDWEScriptActAbilityLvl_Defaults=2,1,Aloc,1\n_YDWEScriptActAbilityLvl_Limits=0,_,1,_,_,_,0,_\n_YDWEScriptActAbilityLvl_Category=TC_SCRIPTSET\n\nYDWEScriptActAnimPlay=0,real,integer,integer,real\n_YDWEScriptActAnimPlay_Defaults=2,1,0,0\n_YDWEScriptActAnimPlay_Limits=0,_,1,_,0,_,0,_\n_YDWEScriptActAnimPlay_Category=TC_SCRIPTSET\n\nYDWEScriptActAnimSpeed=0,real,integer,real\n_YDWEScriptActAnimSpeed_Defaults=2,1,1\n_YDWEScriptActAnimSpeed_Limits=0,_,1,_,_,_\n_YDWEScriptActAnimSpeed_Category=TC_SCRIPTSET\n\nYDWEScriptActAnimReset=0,real,integer\n_YDWEScriptActAnimReset_Defaults=2,1\n_YDWEScriptActAnimReset_Limits=0,_,1,_\n_YDWEScriptActAnimReset_Category=TC_SCRIPTSET\n\nYDWEActorWalkProperties=0,unitcode,integer,real,real\n_YDWEActorWalkProperties_Defaults=Edem,0,0,0\n_YDWEActorWalkProperties_Limits=_,_,0,_,0,_,0,_\n_YDWEActorWalkProperties_Category=TC_SCRIPTSET\n\nYDWEScriptActWalk=0,real,integer,real,real,real,real\n_YDWEScriptActWalk_Defaults=2,1,0,0,2,0\n_YDWEScriptActWalk_Limits=0,_,1,_,_,_,_,_,0,_,0,_\n_YDWEScriptActWalk_Category=TC_SCRIPTSET\n\nYDWEScriptActSlide=0,real,integer,real,real,real,real\n_YDWEScriptActSlide_Defaults=2,1,0,0,2,0\n_YDWEScriptActSlide_Limits=0,_,1,_,_,_,_,_,0,_,0,_\n_YDWEScriptActSlide_Category=TC_SCRIPTSET\n\nYDWEScriptActTurn=0,real,integer,real,real,turnclockwise\n_YDWEScriptActTurn_Defaults=2,1,0,2,turnclockwiseA\n_YDWEScriptActTurn_Limits=0,_,1,_,0,360,0,_,_,_\n_YDWEScriptActTurn_Category=TC_SCRIPTSET\n\nYDWEScriptActFace=0,real,integer,integer,headORchest,real,real,real,real\n_YDWEScriptActFace_Defaults=2,1,2,headORchestA,0,0,0,0\n_YDWEScriptActFace_Limits=0,_,1,_,1,_,_,_,_,_,_,_,_,_,_,_,0,_\n_YDWEScriptActFace_Category=TC_SCRIPTSET\n\nYDWEScriptActFaceReset=0,real,integer,real\n_YDWEScriptActFaceReset_Defaults=2,1,0\n_YDWEScriptActFaceReset_Limits=0,_,1,_,0,_\n_YDWEScriptActFaceReset_Category=TC_SCRIPTSET\n\nYDWEScriptActColour=0,real,integer,real,real,real,real,real\n_YDWEScriptActColour_Defaults=2,1,100,100,100,100,0\n_YDWEScriptActColour_Limits=0,_,1,_,0,100,0,100,0,100,0,100,0,_\n_YDWEScriptActColour_Category=TC_SCRIPTSET\n\nYDWEScriptActSize=0,real,integer,real,real\n_YDWEScriptActSize_Defaults=2,1,1.0,0\n_YDWEScriptActSize_Limits=0,_,1,_,0.01,_,0,_\n_YDWEScriptActSize_Category=TC_SCRIPTSET\n\nYDWECameraSetupAssign=0,camerasetup,integer\n_YDWECameraSetupAssign_Defaults=GetCurrentCameraSetup,1\n_YDWECameraSetupAssign_Limits=_,_,1,_\n_YDWECameraSetupAssign_Category=TC_SCRIPTSET\n\nYDWEScriptCamera=0,real,integer,real,camerachangetype\n_YDWEScriptCamera_Defaults=2,1,0,camerachangetypeA\n_YDWEScriptCamera_Limits=0,_,1,_,0,_,_,_\n_YDWEScriptCamera_Category=TC_SCRIPTSET\n\nYDWEScriptCameraStat=0,real,camerastattype,real,real,real,camerachangetype\n_YDWEScriptCameraStat_Defaults=2,camerastattypeA,0,200,200,camerachangetypeA\n_YDWEScriptCameraStat_Limits=0,_,1,_,0,_,_,_,_,_,_,_\n_YDWEScriptCameraStat_Category=TC_SCRIPTSET\n\nYDWEScriptCameraIgnoreTerrain=0,real,cameratgnoreterrain\n_YDWEScriptCameraIgnoreTerrain_Defaults=2,cameratgnoreterrainA\n_YDWEScriptCameraIgnoreTerrain_Limits=0,_,_,_\n_YDWEScriptCameraIgnoreTerrain_Category=TC_SCRIPTSET\n\nYDWEScriptActCameraLock=0,real,integer,real,real,real,boolean,real\n_YDWEScriptActCameraLock_Defaults=2,1,0,0,0,true,0\n_YDWEScriptActCameraLock_Limits=0,_,1,_,_,_,_,_,_,_,_,_,0,_\n_YDWEScriptActCameraLock_Category=TC_SCRIPTSET\n\nYDWEScriptActCameraLockReset=0,real,boolean,real\n_YDWEScriptActCameraLockReset_Defaults=2,true,0\n_YDWEScriptActCameraLockReset_Limits=0,_,_,_,0,_\n_YDWEScriptActCameraLockReset_Category=TC_SCRIPTSET\n\nYDWEScriptActCameraFace=0,real,integer,real,real,real,boolean,real\n_YDWEScriptActCameraFace_Defaults=2,1,0,0,0,true,0\n_YDWEScriptActCameraFace_Limits=0,_,1,_,_,_,_,_,_,_,_,_,0,_\n_YDWEScriptActCameraFace_Category=TC_SCRIPTSET\n\nYDWEScriptActCameraFaceReset=0,real,boolean,real\n_YDWEScriptActCameraFaceReset_Defaults=2,true,0\n_YDWEScriptActCameraFaceReset_Limits=0,_,_,_,0,_\n_YDWEScriptActCameraFaceReset_Category=TC_SCRIPTSET\n\nYDWEScriptFog=0,real,real,real,real,real,real,real\n_YDWEScriptFog_Defaults=2,3000,5000,0,0,0,0\n_YDWEScriptFog_Limits=0,_,0,_,0,_,0,100,0,100,0,100,0,_\n_YDWEScriptFog_Category=TC_SCRIPTSET\n\nYDWEScriptFade=0,real,real,real,real,real,real\n_YDWEScriptFade_Defaults=2,0,0,0,0,0\n_YDWEScriptFade_Limits=0,_,0,100,0,100,0,100,0,100,0,_\n_YDWEScriptFade_Category=TC_SCRIPTSET\n\nYDWEScriptPlaySound=0,real,string,real,integer\n_YDWEScriptPlaySound_Defaults=2,null,0,0,\n_YDWEScriptPlaySound_Limits=0,_,_,_,0,10,0,127\n_YDWEScriptPlaySound_Category=TC_SCRIPTSET\n\nYDWEScriptPointEffect=0,real,real,real,real,string,real\n_YDWEScriptPointEffect_Defaults=2,0,0,0,null,0\n_YDWEScriptPointEffect_Limits=0,_,_,_,_,_,_,_,_,_,0,_\n_YDWEScriptPointEffect_Category=TC_SCRIPTSET\n\nYDWEScriptActEffect=0,real,integer,string,string,real\n_YDWEScriptActEffect_Defaults=2,1,null,null,0\n_YDWEScriptActEffect_Limits=0,_,1,_,_,_,_,_,0,_\n_YDWEScriptActEffect_Category=TC_SCRIPTSET\n\n// Trigger actions\nDisableTrigger=0,trigger\n_DisableTrigger_Defaults=GetTriggeringTrigger\n_DisableTrigger_Category=TC_TRIGGER\n\nEnableTrigger=0,trigger\n_EnableTrigger_Defaults=GetTriggeringTrigger\n_EnableTrigger_Category=TC_TRIGGER\n\nConditionalTriggerExecute=0,trigger\n_ConditionalTriggerExecute_Defaults=_\n_ConditionalTriggerExecute_Category=TC_TRIGGER\n\nTriggerEvaluate=0,trigger\n_TriggerEvaluate_Defaults=_\n_TriggerEvaluate_Category=TC_TRIGGER\n\n\nYDWEActivateTrigger=0,trigger,onoffoption\n_YDWEActivateTrigger_Defaults=_,OnOffOn\n_YDWEActivateTrigger_Category=TC_TRIGGER\n\n\nYDWETimerRunTrigger=0,real,trigger\n_YDWETimerRunTrigger_Defaults=2,GetTriggeringTrigger\n_YDWETimerRunTrigger_Limits=0,_,_,_\n_YDWETimerRunTrigger_Category=TC_TRIGGER\n\nYDWETimerRunPeriodicTrigger=0,real,trigger,boolean,integer,integer\n_YDWETimerRunPeriodicTrigger_Defaults=2,GetTriggeringTrigger,false,5,0\n_YDWETimerRunPeriodicTrigger_Limits=0,_,_,_,_,_,0,_,_,_\n_YDWETimerRunPeriodicTrigger_Category=TC_TRIGGER\n\n//YDWETimerRunPeriodicTriggerFunction=0,real,trigger,boolean,integer,integer\n//_YDWETimerRunPeriodicTriggerFunction_Defaults=2,GetTriggeringTrigger,false,5,0\n//_YDWETimerRunPeriodicTriggerFunction_Limits=0,_,_,_,_,_,0,_,_,_\n//_YDWETimerRunPeriodicTriggerFunction_Category=TC_TRIGGER\n\nYDWETimerRunPeriodicTriggerOver=0,trigger,integer\n_YDWETimerRunPeriodicTriggerOver_Defaults=GetTriggeringTrigger,0\n_YDWETimerRunPeriodicTriggerOver_Category=TC_TRIGGER\n\nTriggerExecute=0,trigger\n_TriggerExecute_Defaults=_\n_TriggerExecute_Category=TC_TRIGGER\n\nQueuedTriggerAddBJ=0,trigger,checkingignoringoption\n_QueuedTriggerAddBJ_Defaults=_,CheckingIgnoringChecking\n_QueuedTriggerAddBJ_Category=TC_TRIGGER\n\nQueuedTriggerRemoveBJ=0,trigger\n_QueuedTriggerRemoveBJ_Defaults=GetTriggeringTrigger\n_QueuedTriggerRemoveBJ_Category=TC_TRIGGER\n\nQueuedTriggerClearBJ=0,nothing\n_QueuedTriggerClearBJ_Defaults=\n_QueuedTriggerClearBJ_Category=TC_TRIGGER\n\nQueuedTriggerClearInactiveBJ=0,nothing\n_QueuedTriggerClearInactiveBJ_Defaults=\n_QueuedTriggerClearInactiveBJ_Category=TC_TRIGGER\n\n// This function is handled internally by the editor\nAddTriggerEvent=1,trigger,eventcall\n_AddTriggerEvent_Defaults=GetTriggeringTrigger,_\n_AddTriggerEvent_Category=TC_TRIGGER\n\nDestroyTrigger=0,trigger\n_DestroyTrigger_Defaults=GetTriggeringTrigger\n_DestroyTrigger_Category=TC_TRIGGER\n\n\n// Unit actions\n\nCreateNUnitsAtLoc=0,integer,unitcode,player,location,real\n_CreateNUnitsAtLoc_Defaults=1,hfoo,Player00,_,RealUnitFacing\n_CreateNUnitsAtLoc_Limits=1,_,_,_,_,_,_,_,0,360\n_CreateNUnitsAtLoc_Category=TC_UNIT\n\nCreateNUnitsAtLocFacingLocBJ=0,integer,unitcode,player,location,location\n_CreateNUnitsAtLocFacingLocBJ_Defaults=1,hfoo,Player00,_,_\n_CreateNUnitsAtLocFacingLocBJ_Limits=1,_,_,_,_,_,_,_,_,_\n_CreateNUnitsAtLocFacingLocBJ_Category=TC_UNIT\n\n// CreateUnitAtLoc=0,player,unitcode,location,real\n//_ CreateUnitAtLoc_Defaults=Player00,hfoo,_,0\n//_ CreateUnitAtLoc_Category=TC_UNIT\n\n//最萌小汐\nUnit.CreateNUnitsAtLocMU=0,integer,unitcode,player,location,real\n_Unit.CreateNUnitsAtLocMU_Defaults=1,hfoo,Player00,_,RealUnitFacing\n_Unit.CreateNUnitsAtLocMU_Limits=1,_,_,_,_,_,_,_,0,360\n_Unit.CreateNUnitsAtLocMU_Category=TC_UNIT\n\nCreateCorpseLocBJ=0,unitcode,player,location\n_CreateCorpseLocBJ_Defaults=hfoo,Player00,_\n_CreateCorpseLocBJ_Category=TC_UNIT\n\nCreatePermanentCorpseLocBJ=1,corpsetype,unitcode,player,location,real\n_CreatePermanentCorpseLocBJ_Defaults=CorpseTypeBone,hfoo,Player00,_,GetRandomDirectionDeg\n_CreatePermanentCorpseLocBJ_Limits=_,_,_,_,_,_,_,_,0,360\n_CreatePermanentCorpseLocBJ_Category=TC_UNIT\n\n CreateUnit=0,player,unitcode,real,real,real\n_ CreateUnit_Defaults=_,_,_,_,RealUnitFacing\n_ CreateUnit_Category=TC_UNIT\n\n CreateUnitAtLoc=0,player,unitcode,location,real\n_ CreateUnitAtLoc_Defaults=Player00,hfoo,_,0\n_ CreateUnitAtLoc_Category=TC_UNIT\n\nKillUnit=0,unit\n_KillUnit_Defaults=GetTriggerUnit\n_KillUnit_Category=TC_UNIT\n\nRemoveUnit=0,unit\n_RemoveUnit_Defaults=GetTriggerUnit\n_RemoveUnit_Category=TC_UNIT\n\nYDWETimerRemoveUnit=0,real,unit\n_YDWETimerRemoveUnit_Defaults=2,GetTriggerUnit\n_YDWETimerRemoveUnit_Limits=0,_,_,_\n_YDWETimerRemoveUnit_Category=TC_UNIT\n\nExplodeUnitBJ=0,unit\n_ExplodeUnitBJ_Defaults=GetTriggerUnit\n_ExplodeUnitBJ_Category=TC_UNIT\n\nReplaceUnitBJ=0,unit,unitcode,unitstatemethod\n_ReplaceUnitBJ_Defaults=GetTriggerUnit,hfoo,UnitStateMethodRelative\n_ReplaceUnitBJ_Category=TC_UNIT\n\nShowUnit=0,unit,showhideoption\n_ShowUnit_Defaults=bj_lastCreatedUnit,ShowHideHide\n_ShowUnit_Category=TC_UNIT\n\nShowUnitHide=0,unit\n_ShowUnitHide_Defaults=_\n_ShowUnitHide_Category=TC_UNIT\n\nShowUnitShow=0,unit\n_ShowUnitShow_Defaults=_\n_ShowUnitShow_Category=TC_UNIT\n\nSetUnitColor=0,unit,playercolor\n_SetUnitColor_Defaults=GetTriggerUnit,Color00\n_SetUnitColor_Category=TC_UNIT\n\nSetUnitOwner=0,unit,player,colorchangeoption\n_SetUnitOwner_Defaults=_,Player00,ChangeColorTrue\n_SetUnitOwner_Category=TC_UNIT\n\n\nUnitShareVision=0,unit,player,onoffoption\n_UnitShareVision_Defaults=GetTriggerUnit,Player00,OnOffOn\n_UnitShareVision_Category=TC_UNIT\n\nUnitShareVisionBJ=0,sharedontoption,unit,player\n_UnitShareVisionBJ_Defaults=ShareDontOptionShare,GetTriggerUnit,Player00\n_UnitShareVisionBJ_Category=TC_UNIT\n\nSetUnitPosition=0,unit,real,real\n_SetUnitPosition_Defaults=GetTriggerUnit,0,0\n_SetUnitPosition_Category=TC_UNIT\n\nSetUnitPositionLoc=0,unit,location\n_SetUnitPositionLoc_Defaults=GetTriggerUnit,_\n_SetUnitPositionLoc_Category=TC_UNIT\n\n//最萌小汐\nUnit.SetUnitPositionLocMU=0,unit,location\n_Unit.SetUnitPositionLocMU_Defaults=GetTriggerUnit,_\n_Unit.SetUnitPositionLocMU_Category=TC_UNIT\n\nSetUnitPositionLocFacingBJ=0,unit,location,real\n_SetUnitPositionLocFacingBJ_Defaults=GetTriggerUnit,_,RealUnitFacing\n_SetUnitPositionLocFacingBJ_Category=TC_UNIT\n\nSetUnitPositionLocFacingLocBJ=0,unit,location,location\n_SetUnitPositionLocFacingLocBJ_Defaults=GetTriggerUnit,_,_\n_SetUnitPositionLocFacingLocBJ_Category=TC_UNIT\n\nSetUnitX=0,unit,real\n_SetUnitX_Defaults=GetTriggerUnit,0\n_SetUnitX_Category=TC_UNIT\n\nSetUnitY=0,unit,real\n_SetUnitY_Defaults=GetTriggerUnit,0\n_SetUnitY_Category=TC_UNIT\n\nUnit.SetUnitZ=0,unit,real\n_Unit.SetUnitZ_Defaults=GetTriggerUnit,0\n_Unit.SetUnitZ_Category=TC_UNIT\n\nSetUnitRallyPoint=1,unit,location\n_SetUnitRallyPoint_Defaults=GetTriggerUnit,_\n_SetUnitRallyPoint_Category=TC_UNIT\n\nSetUnitRallyUnit=1,unit,unit\n_SetUnitRallyUnit_Defaults=GetTriggerUnit,_\n_SetUnitRallyUnit_Category=TC_UNIT\n\nSetUnitRallyDestructable=1,unit,destructable\n_SetUnitRallyDestructable_Defaults=GetTriggerUnit,_\n_SetUnitRallyDestructable_Category=TC_UNIT\n\nSetUnitState=0,unit,unitstatesec,real\n_SetUnitState_Defaults=GetTriggerUnit,UnitStateLifeSec,100\n_SetUnitState_Category=TC_UNIT\n\nSetUnitLifePercentBJ=0,unit,real\n_SetUnitLifePercentBJ_Defaults=GetTriggerUnit,100\n_SetUnitLifePercentBJ_Limits=_,_,0,100\n_SetUnitLifePercentBJ_Category=TC_UNIT\n\nSetUnitManaPercentBJ=0,unit,real\n_SetUnitManaPercentBJ_Defaults=GetTriggerUnit,100\n_SetUnitManaPercentBJ_Limits=_,_,0,100\n_SetUnitManaPercentBJ_Category=TC_UNIT\n\nSetUnitLifeBJ=0,unit,real\n_SetUnitLifeBJ_Defaults=GetTriggerUnit,GetUnitStateSwap\n_SetUnitLifeBJ_Limits=_,_,0,_\n_SetUnitLifeBJ_Category=TC_UNIT\n\nSetUnitManaBJ=0,unit,real\n_SetUnitManaBJ_Defaults=GetTriggerUnit,0\n_SetUnitManaBJ_Limits=_,_,0,_\n_SetUnitManaBJ_Category=TC_UNIT\n\nSetUnitInvulnerable=0,unit,invulnerableoption\n_SetUnitInvulnerable_Defaults=GetTriggerUnit,InvulnerabilityInvulnerable\n_SetUnitInvulnerable_Category=TC_UNIT\n\nUnit.PauseUnitMU=0,unit,pauseunpauseoption,string\n_Unit.PauseUnitMU_Defaults=GetTriggerUnit,PauseUnpauseOptionPause,\"全局\"\n_Unit.PauseUnitMU_Category=TC_UNIT\n\nPauseUnit=0,unit,pauseunpauseoption\n_PauseUnit_Defaults=GetTriggerUnit,PauseUnpauseOptionPause\n_PauseUnit_Category=TC_YDHIDE\n\nPauseUnitBJ=0,pauseunpauseoption,unit\n_PauseUnitBJ_Defaults=PauseUnpauseOptionPause,GetTriggerUnit\n_PauseUnitBJ_Category=TC_YDHIDE\n\nPauseAllUnitsBJ=0,pauseunpauseoption\n_PauseAllUnitsBJ_Defaults=PauseUnpauseOptionPause\n_PauseAllUnitsBJ_Category=TC_UNIT\n\nUnitPauseTimedLife=1,unit,pauseunpauseoption\n_UnitPauseTimedLife_Defaults=GetTriggerUnit,PauseUnpauseOptionPause\n_UnitPauseTimedLife_Category=TC_UNIT\n\nUnitPauseTimedLifeBJ=1,pauseunpauseoption,unit\n_UnitPauseTimedLifeBJ_Defaults=PauseUnpauseOptionPause,GetTriggerUnit\n_UnitPauseTimedLifeBJ_Category=TC_UNIT\n\nUnitApplyTimedLife=1,unit,timedlifebuffcode,real\n_UnitApplyTimedLife_Defaults=GetTriggerUnit,TimedLifeBuffCodeWaterElemental,60\n_UnitApplyTimedLife_Limits=_,_,_,_,0,_\n_UnitApplyTimedLife_Category=TC_UNIT\n\nUnitApplyTimedLifeBJ=1,real,timedlifebuffcode,unit\n_UnitApplyTimedLifeBJ_Defaults=60,TimedLifeBuffCodeGeneric,GetTriggerUnit\n_UnitApplyTimedLifeBJ_Limits=0,_,_,_,_,_\n_UnitApplyTimedLifeBJ_Category=TC_UNIT\n\nSetUnitExplodedBJ=0,unit,explodedontoption\n_SetUnitExplodedBJ_Defaults=GetTriggerUnit,ExplodeDontExplode\n_SetUnitExplodedBJ_Category=TC_UNIT\n_SetUnitExplodedBJ_ScriptName=SetUnitExploded\n\nUnitSuspendDecay=0,unit,suspendresumeoption_R\n_UnitSuspendDecay_Defaults=GetTriggerUnit,SuspendResumeSuspend_R\n_UnitSuspendDecay_Category=TC_UNIT\n\nUnitSuspendDecayBJ=0,suspendresumeoption,unit\n_UnitSuspendDecayBJ_Defaults=SuspendResumeSuspend,GetTriggerUnit\n_UnitSuspendDecayBJ_Category=TC_UNIT\n\nUnitResetCooldown=1,unit\n_UnitResetCooldown_Defaults=GetTriggerUnit\n_UnitResetCooldown_Category=TC_UNIT\n\n//最萌小汐\nUnit.RefreshSkill=0,unit,abilcode\n_Unit.RefreshSkill_Defaults=GetTriggerUnit,_\n_Unit.RefreshSkill_Category=TC_UNIT\n\nUnitSetConstructionProgress=1,unit,integer\n_UnitSetConstructionProgress_Defaults=GetTriggerUnit,50\n_UnitSetConstructionProgress_Limits=_,_,0,100\n_UnitSetConstructionProgress_Category=TC_UNIT\n\nUnitSetUpgradeProgress=1,unit,integer\n_UnitSetUpgradeProgress_Defaults=GetTriggerUnit,50\n_UnitSetUpgradeProgress_Limits=_,_,0,100\n_UnitSetUpgradeProgress_Category=TC_UNIT\n\nUnitAddSleepPerm=0,unit,sleepwakeoption\n_UnitAddSleepPerm_Defaults=GetTriggerUnit,SleepWakeOptionSleep\n_UnitAddSleepPerm_Category=TC_UNIT\n\nUnitSetCanSleepBJ=0,unit,sleepwakeoption\n_UnitSetCanSleepBJ_Defaults=GetTriggerUnit,SleepWakeOptionSleep\n_UnitSetCanSleepBJ_Category=TC_UNIT\n_UnitSetCanSleepBJ_ScriptName=UnitAddSleep\n\nUnitWakeUpBJ=0,unit\n_UnitWakeUpBJ_Defaults=GetTriggerUnit\n_UnitWakeUpBJ_Category=TC_UNIT\n_UnitWakeUpBJ_ScriptName=UnitWakeUp\n\n//UnitIgnoreAlarm\n\nUnitGenerateAlarms=1,unit,onoffoption\n_UnitGenerateAlarms_Defaults=GetTriggerUnit,OnOffOff\n_UnitGenerateAlarms_Category=TC_UNIT\n\nRescueUnitBJ=0,unit,player,colorchangeoption\n_RescueUnitBJ_Defaults=_,Player00,ChangeColorTrue\n_RescueUnitBJ_Category=TC_UNIT\n\nSetUnitRescuable=0,unit,player,rescuableoption\n_SetUnitRescuable_Defaults=_,Player00,RescuableOptionRescuable\n_SetUnitRescuable_Category=TC_UNIT\n\nMakeUnitRescuableToForceBJ=0,unit,rescuableoption,force\n_MakeUnitRescuableToForceBJ_Defaults=_,RescuableOptionRescuable,Force00\n_MakeUnitRescuableToForceBJ_Category=TC_UNIT\n\nSetUnitRescueRange=0,unit,real\n_SetUnitRescueRange_Defaults=_,384\n_SetUnitRescueRange_Limits=_,_,0,_\n_SetUnitRescueRange_Category=TC_UNIT\n\nSetRescueUnitColorChangeBJ=0,colorchangeoption\n_SetRescueUnitColorChangeBJ_Defaults=ChangeColorFalse\n_SetRescueUnitColorChangeBJ_Category=TC_UNIT\n\nSetRescueBuildingColorChangeBJ=0,colorchangeoption\n_SetRescueBuildingColorChangeBJ_Defaults=ChangeColorFalse\n_SetRescueBuildingColorChangeBJ_Category=TC_UNIT\n\nSetUnitUseFood=1,unit,enabledisableoption\n_SetUnitUseFood_Defaults=_,EnableDisableDisable\n_SetUnitUseFood_Category=TC_UNIT\n\nSetUnitUseFoodBJ=1,enabledisableoption,unit\n_SetUnitUseFoodBJ_Defaults=EnableDisableDisable,_\n_SetUnitUseFoodBJ_Category=TC_UNIT\n\nSetUnitFacing=0,unit,real\n_SetUnitFacing_Defaults=_,RealUnitFacing\n_SetUnitFacing_Limits=_,_,_,_\n_SetUnitFacing_Category=TC_UNIT\n\nSetUnitFacingTimed=0,unit,real,real\n_SetUnitFacingTimed_Defaults=_,RealUnitFacing,0\n_SetUnitFacingTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingTimed_Category=TC_UNIT\n\nSetUnitFacingToFaceUnitTimed=0,unit,unit,real\n_SetUnitFacingToFaceUnitTimed_Defaults=_,_,0\n_SetUnitFacingToFaceUnitTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingToFaceUnitTimed_Category=TC_UNIT\n\nSetUnitFacingToFaceLocTimed=0,unit,location,real\n_SetUnitFacingToFaceLocTimed_Defaults=_,_,0\n_SetUnitFacingToFaceLocTimed_Limits=_,_,_,_,0,_\n_SetUnitFacingToFaceLocTimed_Category=TC_UNIT\n\nSetUnitMoveSpeed=0,unit,real\n_SetUnitMoveSpeed_Defaults=_,GetUnitDefaultMoveSpeed\n_SetUnitMoveSpeed_Category=TC_UNIT\n\nUnit.AddMoveSpeed=0,unit,real\n_Unit.AddMoveSpeed_Defaults=GetTriggerUnit,100\n_Unit.AddMoveSpeed_Category=TC_UNIT\n\nSetUnitPathing=0,unit,pathingoption\n_SetUnitPathing_Defaults=_,PathingOff\n_SetUnitPathing_Category=TC_UNIT\n\nSetUnitAcquireRangeBJ=0,unit,real\n_SetUnitAcquireRangeBJ_Defaults=_,_\n_SetUnitAcquireRangeBJ_Category=TC_UNIT\n_SetUnitAcquireRangeBJ_ScriptName=SetUnitAcquireRange\n\nSetUnitUserData=1,unit,integer\n_SetUnitUserData_Defaults=_,0\n_SetUnitUserData_Category=TC_UNIT\n\nUnitRemoveBuffs=0,unit,includeoption,includeoption\n_UnitRemoveBuffs_Defaults=GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitRemoveBuffs_Category=TC_UNIT\n\nUnitRemoveBuffsEx=1,unit,includeoption,includeoption,includeoptionnot,includeoptionnot,includeoption,includeoption,includeoptionnot\n_UnitRemoveBuffsEx_Defaults=GetTriggerUnit,InclusionInclude,InclusionInclude,InclusionIncludeNot,InclusionIncludeNot,InclusionInclude,InclusionInclude,InclusionIncludeNot\n_UnitRemoveBuffsEx_Category=TC_UNIT\n\nUnitRemoveBuffNT=1,unit,buffcode\n_UnitRemoveBuffNT_Defaults=GetTriggerUnit,_\n_UnitRemoveBuffNT_Category=TC_UNIT\n_UnitRemoveBuffNT_ScriptName=UnitRemoveAbility\n\nUnitRemoveBuffsBJ=0,bufftype,unit\n_UnitRemoveBuffsBJ_Defaults=BuffTypeAll,GetTriggerUnit\n_UnitRemoveBuffsBJ_Category=TC_UNIT\n\nUnitRemoveBuffsExBJ=1,buffpolarity,buffresist,unit,includeoption,includeoption\n_UnitRemoveBuffsExBJ_Defaults=BuffPolarityEither,BuffResistEither,GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitRemoveBuffsExBJ_Category=TC_UNIT\n\nUnitRemoveBuffBJ=1,buffcode,unit\n_UnitRemoveBuffBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveBuffBJ_Category=TC_UNIT\n\nUnitAddAbility=1,unit,abilcode\n_UnitAddAbility_Defaults=GetTriggerUnit,_\n_UnitAddAbility_Category=TC_UNIT\n\nUnitAddAbilityBJ=1,abilcode,unit\n_UnitAddAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitAddAbilityBJ_Category=TC_UNIT\n\n//最萌小汐\nUnit.UnitAddAbilityMU=1,unit,abilcode,integer\n_Unit.UnitAddAbilityMU_Defaults=GetTriggerUnit,_,2\n_Unit.UnitAddAbilityMU_Category=TC_UNIT\n\nUnitRemoveAbility=0,unit,abilcode\n_UnitRemoveAbility_Defaults=GetTriggerUnit,_\n_UnitRemoveAbility_Category=TC_UNIT\n\nUnitRemoveAbilityBJ=0,abilcode,unit\n_UnitRemoveAbilityBJ_Defaults=_,GetTriggerUnit\n_UnitRemoveAbilityBJ_Category=TC_UNIT\n\nUnitMakeAbilityPermanent=0,unit,onoffoption,abilcode\n_UnitMakeAbilityPermanent_Defaults=GetTriggerUnit,OnOffOn,_\n_UnitMakeAbilityPermanent_Category=TC_UNIT\n\nUnitAddType=1,unit,unittypeaddable\n_UnitAddType_Defaults=GetTriggerUnit,UnitTypeMechanicalAdd\n_UnitAddType_Category=TC_UNIT\n\nUnitAddTypeBJ=1,unittype,unit\n_UnitAddTypeBJ_Defaults=UnitTypeMechanical,GetTriggerUnit\n_UnitAddTypeBJ_Category=TC_UNIT\n\nUnitRemoveType=1,unit,unittypeaddable\n_UnitRemoveType_Defaults=GetTriggerUnit,UnitTypeMechanicalAdd\n_UnitRemoveType_Category=TC_UNIT\n\nUnitRemoveTypeBJ=1,unittype,unit\n_UnitRemoveTypeBJ_Defaults=UnitTypeMechanical,GetTriggerUnit\n_UnitRemoveTypeBJ_Category=TC_UNIT\n\nDecUnitAbilityLevel=1,unit,abilcode\n_DecUnitAbilityLevel_Defaults=GetTriggerUnit,_\n_DecUnitAbilityLevel_Category=TC_UNIT\n\nDecUnitAbilityLevelSwapped=1,abilcode,unit\n_DecUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_DecUnitAbilityLevelSwapped_Category=TC_UNIT\n\nIncUnitAbilityLevel=1,unit,abilcode\n_IncUnitAbilityLevel_Defaults=GetTriggerUnit,_\n_IncUnitAbilityLevel_Category=TC_UNIT\n\nIncUnitAbilityLevelSwapped=1,abilcode,unit\n_IncUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit\n_IncUnitAbilityLevelSwapped_Category=TC_UNIT\n\nSetUnitAbilityLevel=1,unit,abilcode,integer\n_SetUnitAbilityLevel_Defaults=GetTriggerUnit,_,1\n_SetUnitAbilityLevel_Limits=_,_,_,_,1,_\n_SetUnitAbilityLevel_Category=TC_UNIT\n\nSetUnitAbilityLevelSwapped=1,abilcode,unit,integer\n_SetUnitAbilityLevelSwapped_Defaults=_,GetTriggerUnit,1\n_SetUnitAbilityLevelSwapped_Limits=_,_,_,_,1,_\n_SetUnitAbilityLevelSwapped_Category=TC_UNIT\n\nYDWESetUnitAbilityState=1,unit,abilcode,AbilityState,real\n_YDWESetUnitAbilityState_Defaults=GetTriggerUnit,_,ABILITY_STATE_COOLDOWN,_\n_YDWESetUnitAbilityState_Category=TC_UNIT\n\nYDWESetUnitAbilityDataInteger=1,unit,abilcode,integer,AbilityDataInteger,integer\n_YDWESetUnitAbilityDataInteger_Defaults=GetTriggerUnit,_,1,ABILITY_DATA_COST,_\n_YDWESetUnitAbilityDataInteger_Limits=_,_,_,_,1,_,_,_,_,_\n_YDWESetUnitAbilityDataInteger_Category=TC_UNIT\n\nYDWESetUnitAbilityDataReal=1,unit,abilcode,integer,AbilityDataReal,real\n_YDWESetUnitAbilityDataReal_Defaults=GetTriggerUnit,_,1,ABILITY_DATA_COOL,_\n_YDWESetUnitAbilityDataReal_Limits=_,_,_,_,1,_,_,_,_,_\n_YDWESetUnitAbilityDataReal_Category=TC_UNIT\n\nYDWESetUnitAbilityDataString=1,unit,abilcode,integer,AbilityDataString,string\n_YDWESetUnitAbilityDataString_Defaults=GetTriggerUnit,_,1,ABILITY_DATA_TIP,_\n_YDWESetUnitAbilityDataString_Limits=_,_,_,_,1,_,_,_,_,_\n_YDWESetUnitAbilityDataString_Category=TC_UNIT\n\n\n\n\n\n\n\n\n\n\nIssueImmediateOrder=0,unit,unitordernotarg\n_IssueImmediateOrder_Defaults=GetTriggerUnit,UnitOrderStop\n_IssueImmediateOrder_Category=TC_UNIT\n\nIssuePointOrder=0,unit,unitorderptarg,real,real\n_IssuePointOrder_Defaults=GetTriggerUnit,UnitOrderMove,0,0\n_IssuePointOrder_Category=TC_UNIT\n\nIssuePointOrderLoc=0,unit,unitorderptarg,location\n_IssuePointOrderLoc_Defaults=GetTriggerUnit,UnitOrderMove,_\n_IssuePointOrderLoc_Category=TC_UNIT\n\n//最萌小汐\nUnit.IssuePointOrderLocMU=0,unit,unitorderptarg,location\n_Unit.IssuePointOrderLocMU_Defaults=GetTriggerUnit,UnitOrderMove,_\n_Unit.IssuePointOrderLocMU_Category=TC_UNIT\n\nIssueTargetOrder=0,unit,unitorderutarg,unit\n_IssueTargetOrder_Defaults=GetTriggerUnit,UnitOrderAttackUnit,_\n_IssueTargetOrder_Category=TC_UNIT\n\nIssueTargetDestructableOrder=0,unit,unitorderdtarg,destructable\n_IssueTargetDestructableOrder_Defaults=GetTriggerUnit,UnitOrderHarvestDestructible,_\n_IssueTargetDestructableOrder_Category=TC_UNIT\n_IssueTargetDestructableOrder_ScriptName=IssueTargetOrder\n\nIssueTargetItemOrder=0,unit,unitorderitarg,item\n_IssueTargetItemOrder_Defaults=GetTriggerUnit,UnitOrderSmartItem,_\n_IssueTargetItemOrder_Category=TC_UNIT\n_IssueTargetItemOrder_ScriptName=IssueTargetOrder\n\nIssueImmediateOrderById=0,unit,ordercodenotarg\n_IssueImmediateOrderById_Defaults=GetTriggerUnit,OrderCodeStop\n_IssueImmediateOrderById_Category=TC_UNIT\n\nIssuePointOrderById=0,unit,ordercodeptarg,real,real\n_IssuePointOrderById_Defaults=GetTriggerUnit,OrderCodeMove,0,0\n_IssuePointOrderById_Category=TC_UNIT\n\nIssuePointOrderByIdLoc=0,unit,ordercodeptarg,location\n_IssuePointOrderByIdLoc_Defaults=GetTriggerUnit,OrderCodeMove,_\n_IssuePointOrderByIdLoc_Category=TC_UNIT\n\n//最萌小汐\nUnit.IssuePointOrderByIdLocMU=0,unit,ordercodeptarg,location\n_Unit.IssuePointOrderByIdLocMU_Defaults=GetTriggerUnit,OrderCodeMove,_\n_Unit.IssuePointOrderByIdLocMU_Category=TC_UNIT\n\nIssueTargetOrderById=0,unit,ordercodeutarg,unit\n_IssueTargetOrderById_Defaults=GetTriggerUnit,OrderCodeAttackUnit,_\n_IssueTargetOrderById_Category=TC_UNIT\n\nIssueTargetDestructableOrderById=0,unit,ordercodedtarg,destructable\n_IssueTargetDestructableOrderById_Defaults=GetTriggerUnit,OrderCodeHarvestDestructible,_\n_IssueTargetDestructableOrderById_Category=TC_UNIT\n_IssueTargetDestructableOrderById_ScriptName=IssueTargetOrderById\n\nIssueTargetItemOrderById=0,unit,ordercodeitarg,item\n_IssueTargetItemOrderById_Defaults=GetTriggerUnit,OrderCodeSmartItem,_\n_IssueTargetItemOrderById_Category=TC_UNIT\n_IssueTargetItemOrderById_ScriptName=IssueTargetOrderById\n\nIssueTrainOrderByIdBJ=0,unit,unitcode\n_IssueTrainOrderByIdBJ_Defaults=GetTriggerUnit,hfoo\n_IssueTrainOrderByIdBJ_Category=TC_UNIT\n_IssueTrainOrderByIdBJ_ScriptName=IssueImmediateOrderById\n\nIssueUpgradeOrderByIdBJ=0,unit,techcode\n_IssueUpgradeOrderByIdBJ_Defaults=GetTriggerUnit,Rhde\n_IssueUpgradeOrderByIdBJ_Category=TC_UNIT\n_IssueUpgradeOrderByIdBJ_ScriptName=IssueImmediateOrderById\n\nIssueBuildOrderById=0,unit,unitcode,real,real\n_IssueBuildOrderById_Defaults=GetTriggerUnit,hbar,0,0\n_IssueBuildOrderById_Category=TC_UNIT\n\nIssueBuildOrderByIdLocBJ=0,unit,unitcode,location\n_IssueBuildOrderByIdLocBJ_Defaults=GetTriggerUnit,hbar,_\n_IssueBuildOrderByIdLocBJ_Category=TC_UNIT\n\nUnitDropItemPoint=1,unit,item,real,real\n_UnitDropItemPoint_Defaults=GetTriggerUnit,bj_lastCreatedItem,0,0\n_UnitDropItemPoint_Category=TC_UNIT\n\nUnitDropItemPointLoc=1,unit,item,location\n_UnitDropItemPointLoc_Defaults=GetTriggerUnit,GetLastCreatedItem,_\n_UnitDropItemPointLoc_Category=TC_UNIT\n\nUnitDropItemSlot=1,unit,item,integer\n_UnitDropItemSlot_Defaults=GetTriggerUnit,bj_lastCreatedItem,0\n_UnitDropItemSlot_Limits=_,_,_,_,0,5\n_UnitDropItemSlot_Category=TC_UNIT\n\nUnitDropItemSlotBJ=1,unit,item,integer\n_UnitDropItemSlotBJ_Defaults=GetTriggerUnit,GetLastCreatedItem,1\n_UnitDropItemSlotBJ_Limits=_,_,_,_,1,6\n_UnitDropItemSlotBJ_Category=TC_UNIT\n\nUnitDropItemTargetBJ=1,unit,item,unit\n_UnitDropItemTargetBJ_Defaults=GetTriggerUnit,GetLastCreatedItem,_\n_UnitDropItemTargetBJ_Category=TC_UNIT\n_UnitDropItemTargetBJ_ScriptName=UnitDropItemTarget\n\nIssueBuyUnitOrder=0,player,unit,unitcode\n_IssueBuyUnitOrder_Defaults=Player00,GetTriggerUnit,hfoo\n_IssueBuyUnitOrder_Category=TC_UNIT\n_IssueBuyUnitOrder_ScriptName=IssueNeutralImmediateOrderById\n\nIssueBuyItemOrder=0,player,unit,itemcode\n_IssueBuyItemOrder_Defaults=Player00,GetTriggerUnit,ckng\n_IssueBuyItemOrder_Category=TC_UNIT\n_IssueBuyItemOrder_ScriptName=IssueNeutralImmediateOrderById\n\nIssueNeutralImmediateOrder=0,player,unit,unitordernotarg\n_IssueNeutralImmediateOrder_Defaults=Player00,GetTriggerUnit,UnitOrderStop\n_IssueNeutralImmediateOrder_Category=TC_UNIT\n\nIssueNeutralPointOrder=0,player,unit,unitorderptarg,real,real\n_IssueNeutralPointOrder_Defaults=Player00,GetTriggerUnit,UnitOrderNeutralDetectAOE,0,0\n_IssueNeutralPointOrder_Category=TC_UNIT\n\nIssueNeutralTargetOrder=0,player,unit,unitorderutarg,unit\n_IssueNeutralTargetOrder_Defaults=Player00,GetTriggerUnit,UnitOrderNeutralInterAct,_\n_IssueNeutralTargetOrder_Category=TC_UNIT\n\nIssueNeutralTargetDestructableOrder=0,player,unit,unitorderdtarg,destructable\n_IssueNeutralTargetDestructableOrder_Defaults=Player00,GetTriggerUnit,UnitOrderHarvestDestructible,_\n_IssueNeutralTargetDestructableOrder_Category=TC_UNIT\n_IssueNeutralTargetDestructableOrder_ScriptName=IssueNeutralTargetOrder\n\nIssueNeutralTargetItemOrder=0,player,unit,unitorderitarg,item\n_IssueNeutralTargetItemOrder_Defaults=Player00,GetTriggerUnit,UnitOrderSmartItem,_\n_IssueNeutralTargetItemOrder_Category=TC_UNIT\n_IssueNeutralTargetItemOrder_ScriptName=IssueNeutralTargetOrder\n\nIssueNeutralImmediateOrderById=0,player,unit,ordercodenotarg\n_IssueNeutralImmediateOrderById_Defaults=Player00,GetTriggerUnit,OrderCodeStop\n_IssueNeutralImmediateOrderById_Category=TC_UNIT\n\nIssueNeutralPointOrderById=0,player,unit,ordercodeptarg,real,real\n_IssueNeutralPointOrderById_Defaults=Player00,GetTriggerUnit,OrderCodeNeutralDetectAOE,0,0\n_IssueNeutralPointOrderById_Category=TC_UNIT\n\nIssueNeutralTargetOrderById=0,player,unit,ordercodeutarg,unit\n_IssueNeutralTargetOrderById_Defaults=Player00,GetTriggerUnit,OrderCodeNeutralInterAct,_\n_IssueNeutralTargetOrderById_Category=TC_UNIT\n\nIssueNeutralTargetDestructableOrderById=0,player,unit,ordercodedtarg,destructable\n_IssueNeutralTargetDestructableOrderById_Defaults=Player00,GetTriggerUnit,OrderCodeHarvestDestructible,_\n_IssueNeutralTargetDestructableOrderById_Category=TC_UNIT\n_IssueNeutralTargetDestructableOrderById_ScriptName=IssueNeutralTargetOrderById\n\nIssueNeutralTargetItemOrderById=0,player,unit,ordercodeitarg,item\n_IssueNeutralTargetItemOrderById_Defaults=Player00,GetTriggerUnit,OrderCodeSmartItem,_\n_IssueNeutralTargetItemOrderById_Category=TC_UNIT\n_IssueNeutralTargetItemOrderById_ScriptName=IssueNeutralTargetOrderById\n\nYDWEIssueNeutralImmediateOrderById=0,player,unit,integer\n_YDWEIssueNeutralImmediateOrderById_Defaults=Player00,GetTriggerUnit,851972\n_YDWEIssueNeutralImmediateOrderById_Category=TC_UNIT\n_YDWEIssueNeutralImmediateOrderById_ScriptName=IssueNeutralImmediateOrderById\n\nYDWEIssueNeutralPointOrderById=0,player,unit,integer,real,real\n_YDWEIssueNeutralPointOrderById_Defaults=Player00,GetTriggerUnit,851983,0,0\n_YDWEIssueNeutralPointOrderById_Category=TC_UNIT\n_YDWEIssueNeutralPointOrderById_ScriptName=IssueNeutralPointOrderById\n\nYDWEIssueNeutralTargetOrderById=0,player,unit,integer,unit\n_YDWEIssueNeutralTargetOrderById_Defaults=Player00,GetTriggerUnit,851983,_\n_YDWEIssueNeutralTargetOrderById_Category=TC_UNIT\n_YDWEIssueNeutralTargetOrderById_ScriptName=IssueNeutralTargetOrderById\n\nYDWEIssueNeutralTargetDestructableOrderById=0,player,unit,integer,destructable\n_YDWEIssueNeutralTargetDestructableOrderById_Defaults=Player00,GetTriggerUnit,851983,_\n_YDWEIssueNeutralTargetDestructableOrderById_Category=TC_UNIT\n_YDWEIssueNeutralTargetDestructableOrderById_ScriptName=IssueNeutralTargetOrderById\n\nYDWEIssueNeutralTargetItemOrderById=0,player,unit,integer,item\n_YDWEIssueNeutralTargetItemOrderById_Defaults=Player00,GetTriggerUnit,851983,_\n_YDWEIssueNeutralTargetItemOrderById_Category=TC_UNIT\n_YDWEIssueNeutralTargetItemOrderById_ScriptName=IssueNeutralTargetOrderById\n\nUnitDamagePoint=1,unit,real,real,real,real,real,isnotoption,isnotoption,attacktype,damagetype,weapontype\n_UnitDamagePoint_Defaults=GetTriggerUnit,0,500,0,0,100,IsNotNot,IsNotNot,AttackTypeNormal,DamageTypeNormal,WEAPON_TYPE_WHOKNOWS\n_UnitDamagePoint_Category=TC_UNIT\n\nUnitDamagePointLoc=1,unit,real,real,location,real,attacktype,damagetype\n_UnitDamagePointLoc_Defaults=GetTriggerUnit,0,500,GetRectCenter,100,AttackTypeNormal,DamageTypeNormal\n_UnitDamagePointLoc_Category=TC_UNIT\n\nUnitDamageTarget=1,unit,unit,real,isnotoption,isnotoption,attacktype,damagetype,weapontype\n_UnitDamageTarget_Defaults=GetTriggerUnit,GetTriggerUnit,500,IsNotNot,IsNotNot,AttackTypeNormal,DamageTypeNormal,WEAPON_TYPE_WHOKNOWS\n_UnitDamageTarget_Category=TC_UNIT\n\nUnitDamageTargetBJ=1,unit,unit,real,attacktype,damagetype\n_UnitDamageTargetBJ_Defaults=GetTriggerUnit,GetTriggerUnit,500,AttackTypeNormal,DamageTypeNormal\n_UnitDamageTargetBJ_Category=TC_UNIT\n\nUnit.Heal=1,unit,unit,real\n_Unit.Heal_Defaults=GetTriggerUnit,GetTriggerUnit,500\n_Unit.Heal_Category=TC_UNIT\n\n\n\n// YD actions\nYDWECreateUnitPool=0,nothing\n_YDWECreateUnitPool_Defaults=\n_YDWECreateUnitPool_Category=TC_UNITPOOL\n\n// Unitpool actions\nUnitPoolAddUnitType=0,unitpool,unitcode,real\n_UnitPoolAddUnitType_Defaults=_,hfoo,1\n_UnitPoolAddUnitType_Category=TC_UNITPOOL\n\nUnitPoolRemoveUnitType=0,unitpool,unitcode\n_UnitPoolRemoveUnitType_Defaults=_,hfoo\n_UnitPoolRemoveUnitType_Category=TC_UNITPOOL\n\nPlaceRandomUnit=0,unitpool,player,real,real,real\n_PlaceRandomUnit_Defaults=_,Player00,0,0,0\n_PlaceRandomUnit_Category=TC_UNITPOOL\n\nYDWEPlaceRandomUnit=0,unitpool,player,real,real,real\n_YDWEPlaceRandomUnit_Defaults=bj_lastCreatedUnitPool,Player00,0,0,0\n_YDWEPlaceRandomUnit_Category=TC_UNITPOOL\n\nDestroyUnitPool=0,unitpool\n_DestroyUnitPool_Defaults=_\n_DestroyUnitPool_Category=TC_UNITPOOL\n\n\n// Unit Group actions\n// Specially handled by the editor\nForGroupMultiple=1,group\n_ForGroupMultiple_Defaults=_\n_ForGroupMultiple_Category=TC_UNITGROUP\n_ForGroupMultiple_ScriptName=ForGroupBJ\n\nForGroup=0,group,code\n_ForGroup_Defaults=_,DoNothing\n_ForGroup_Category=TC_UNITGROUP\n_ForGroup_ScriptName=ForGroupBJ\n\nGroupEnumUnitsInRange=0,group,real,real,real,boolexpr\n_GroupEnumUnitsInRange_Defaults=_,0,0,512,_\n_GroupEnumUnitsInRange_Limits=_,_,_,_,_,_,0,_,_,_\n_GroupEnumUnitsInRange_Category=TC_UNITGROUP\n\nGroupEnumUnitsInRangeCounted=0,group,real,real,real,boolexpr,integer\n_GroupEnumUnitsInRangeCounted_Defaults=_,0,0,512,_,5\n_GroupEnumUnitsInRangeCounted_Limits=_,_,_,_,_,_,0,_,_,_,0,_\n_GroupEnumUnitsInRangeCounted_Category=TC_UNITGROUP\n\nGroupEnumUnitsInRangeOfLoc=0,group,location,real,boolexpr\n_GroupEnumUnitsInRangeOfLoc_Defaults=_,_,512,_\n_GroupEnumUnitsInRangeOfLoc_Limits=_,_,_,_,0,_,_,_\n_GroupEnumUnitsInRangeOfLoc_Category=TC_UNITGROUP\n\nGroupEnumUnitsInRangeOfLocCounted=0,group,location,real,boolexpr,integer\n_GroupEnumUnitsInRangeOfLocCounted_Defaults=_,_,512,_,5\n_GroupEnumUnitsInRangeOfLocCounted_Limits=_,_,_,_,0,_,_,_,0,_\n_GroupEnumUnitsInRangeOfLocCounted_Category=TC_UNITGROUP\n\nGroupAddUnit=0,group,unit\n_GroupAddUnit_Defaults=_,GetTriggerUnit\n_GroupAddUnit_Category=TC_UNITGROUP\n\nGroupAddUnitSimple=0,unit,group\n_GroupAddUnitSimple_Defaults=GetTriggerUnit,_\n_GroupAddUnitSimple_Category=TC_UNITGROUP\n\nGroupAddGroup=0,group,group\n_GroupAddGroup_Defaults=_,_\n_GroupAddGroup_Category=TC_UNITGROUP\n\nGroupRemoveUnit=0,group,unit\n_GroupRemoveUnit_Defaults=_,GetTriggerUnit\n_GroupRemoveUnit_Category=TC_UNITGROUP\n\nGroupRemoveUnitSimple=0,unit,group\n_GroupRemoveUnitSimple_Defaults=GetTriggerUnit,_\n_GroupRemoveUnitSimple_Category=TC_UNITGROUP\n\nGroupRemoveGroup=0,group,group\n_GroupRemoveGroup_Defaults=_,_\n_GroupRemoveGroup_Category=TC_UNITGROUP\n\nGroupClear=0,group\n_GroupClear_Defaults=_\n_GroupClear_Category=TC_UNITGROUP\n\nDestroyGroup=0,group\n_DestroyGroup_Defaults=_\n_DestroyGroup_Category=TC_UNITGROUP\n\nGroupImmediateOrder=0,group,unitordernotarg\n_GroupImmediateOrder_Defaults=_,UnitOrderStop\n_GroupImmediateOrder_Category=TC_UNITGROUP\n\nGroupPointOrder=0,group,unitorderptarg,real,real\n_GroupPointOrder_Defaults=_,UnitOrderMove,0,0\n_GroupPointOrder_Category=TC_UNITGROUP\n\nGroupPointOrderLoc=0,group,unitorderptarg,location\n_GroupPointOrderLoc_Defaults=_,UnitOrderMove,_\n_GroupPointOrderLoc_Category=TC_UNITGROUP\n\nGroupTargetOrder=0,group,unitorderutarg,unit\n_GroupTargetOrder_Defaults=_,UnitOrderAttackUnit,_\n_GroupTargetOrder_Category=TC_UNITGROUP\n\nGroupTargetDestructableOrder=0,group,unitorderdtarg,destructable\n_GroupTargetDestructableOrder_Defaults=_,UnitOrderHarvestDestructible,_\n_GroupTargetDestructableOrder_Category=TC_UNITGROUP\n_GroupTargetDestructableOrder_ScriptName=GroupTargetOrder\n\nGroupTargetItemOrder=0,group,unitorderitarg,item\n_GroupTargetItemOrder_Defaults=_,UnitOrderAttackItem,_\n_GroupTargetItemOrder_Category=TC_UNITGROUP\n_GroupTargetItemOrder_ScriptName=GroupTargetOrder\n\nGroupImmediateOrderById=0,group,ordercodenotarg\n_GroupImmediateOrderById_Defaults=_,OrderCodeStop\n_GroupImmediateOrderById_Category=TC_UNITGROUP\n\nGroupPointOrderById=0,group,ordercodeptarg,real,real\n_GroupPointOrderById_Defaults=_,OrderCodeMove,0,0\n_GroupPointOrderById_Category=TC_UNITGROUP\n\nGroupPointOrderByIdLoc=0,group,ordercodeptarg,location\n_GroupPointOrderByIdLoc_Defaults=_,OrderCodeMove,_\n_GroupPointOrderByIdLoc_Category=TC_UNITGROUP\n\nGroupTargetOrderById=0,group,ordercodeutarg,unit\n_GroupTargetOrderById_Defaults=_,OrderCodeAttackUnit,_\n_GroupTargetOrderById_Category=TC_UNITGROUP\n\nGroupTargetDestructableOrderById=0,group,ordercodedtarg,destructable\n_GroupTargetDestructableOrderById_Defaults=_,OrderCodeHarvestDestructible,_\n_GroupTargetDestructableOrderById_Category=TC_UNITGROUP\n_GroupTargetDestructableOrderById_ScriptName=GroupTargetOrder\n\nGroupTargetItemOrderById=0,group,ordercodeitarg,item\n_GroupTargetItemOrderById_Defaults=_,OrderCodeAttackItem,_\n_GroupTargetItemOrderById_Category=TC_UNITGROUP\n_GroupTargetItemOrderById_ScriptName=GroupTargetOrder\n\nGroupTrainOrderByIdBJ=0,group,unitcode\n_GroupTrainOrderByIdBJ_Defaults=GetUnitsInRectAll,hfoo\n_GroupTrainOrderByIdBJ_Category=TC_UNITGROUP\n_GroupTrainOrderByIdBJ_ScriptName=GroupImmediateOrderById\n\n\n// Ubersplat actions\nCreateUbersplatBJ=1,location,ubersplattype,real,real,real,real,allowdontoption,allowdontoption\n_CreateUbersplatBJ_Defaults=_,UbersplatTypeNGOL,100,100,100,0,AllowDontDont,AllowDontDont\n_CreateUbersplatBJ_Category=TC_UBERSPLAT\n\nDestroyUbersplat=1,ubersplat\n_DestroyUbersplat_Defaults=GetLastCreatedUbersplat\n_DestroyUbersplat_Category=TC_UBERSPLAT\n\nResetUbersplat=1,ubersplat\n_ResetUbersplat_Defaults=GetLastCreatedUbersplat\n_ResetUbersplat_Category=TC_UBERSPLAT\n\nFinishUbersplat=1,ubersplat\n_FinishUbersplat_Defaults=GetLastCreatedUbersplat\n_FinishUbersplat_Category=TC_UBERSPLAT\n\nShowUbersplat=1,ubersplat,showhideoption\n_ShowUbersplat_Defaults=bj_lastCreatedUbersplat,ShowHideShow\n_ShowUbersplat_Category=TC_UBERSPLAT\n\nShowUbersplatBJ=1,showhideoption,ubersplat\n_ShowUbersplatBJ_Defaults=ShowHideShow,GetLastCreatedUbersplat\n_ShowUbersplatBJ_Category=TC_UBERSPLAT\n\nSetUbersplatRender=1,ubersplat,enabledisableoption\n_SetUbersplatRender_Defaults=GetLastCreatedUbersplat,EnableDisableEnable\n_SetUbersplatRender_Category=TC_UBERSPLAT\n\nSetUbersplatRenderAlways=1,ubersplat,enabledisableoption\n_SetUbersplatRenderAlways_Defaults=GetLastCreatedUbersplat,EnableDisableEnable\n_SetUbersplatRenderAlways_Category=TC_UBERSPLAT\n\n\n// Location actions\nMoveLocation=0,location,real,real\n_MoveLocation_Defaults=_,0,0\n_MoveLocation_Category=TC_LOCATION\n\nRemoveLocation=0,location\n_RemoveLocation_Defaults=\n_RemoveLocation_Category=TC_LOCATION\n\n\n// Cinematic actions\nTransmissionFromUnitWithNameBJ=0,force,unit,StringExt,sound,StringExt,addsettooption,real,waitdontoption\n_TransmissionFromUnitWithNameBJ_Defaults=GetPlayersAll,_,_,SoundNull,_,AddSetToAdd,0,WaitDontWait\n_TransmissionFromUnitWithNameBJ_Category=TC_CINEMATIC\n\nTransmissionFromUnitTypeWithNameBJ=0,force,player,unitcode,StringExt,location,sound,StringExt,addsettooption,real,waitdontoption\n_TransmissionFromUnitTypeWithNameBJ_Defaults=GetPlayersAll,Player00,hfoo,_,_,SoundNull,_,AddSetToAdd,0,WaitDontWait\n_TransmissionFromUnitTypeWithNameBJ_Category=TC_CINEMATIC\n\nForceCinematicSubtitlesBJ=1,onoffoption\n_ForceCinematicSubtitlesBJ_Defaults=OnOffOn\n_ForceCinematicSubtitlesBJ_Category=TC_CINEMATIC\n_ForceCinematicSubtitlesBJ_ScriptName=ForceCinematicSubtitles\n\nCinematicModeBJ=0,onoffoption,force\n_CinematicModeBJ_Defaults=OnOffOn,GetPlayersAll\n_CinematicModeBJ_Category=TC_CINEMATIC\n\nCinematicModeExBJ=1,onoffoption,force,real\n_CinematicModeExBJ_Defaults=OnOffOn,GetPlayersAll,0.2\n_CinematicModeExBJ_Category=TC_CINEMATIC\n\nCinematicFadeBJ=0,fadetypeoption,real,cinefiltertexture,real,real,real,real\n_CinematicFadeBJ_Defaults=FadeTypeOptionFadeOutIn,2,CineFilterTextureWhite,0,0,0,0\n_CinematicFadeBJ_Limits=_,_,0,_,_,_,0,100,0,100,0,100,0,100\n_CinematicFadeBJ_Category=TC_CINEMATIC\n\nCinematicFilterGenericBJ=0,real,blendmode,cinefiltertexture,real,real,real,real,real,real,real,real\n_CinematicFilterGenericBJ_Defaults=2,BlendModeBlend,CineFilterTextureWhite,100,100,100,100,0,0,0,0\n_CinematicFilterGenericBJ_Limits=0,_,_,_,_,_,0,100,0,100,0,100,0,100,0,100,0,100,0,100,0,100\n_CinematicFilterGenericBJ_Category=TC_CINEMATIC\n\nDisplayCineFilterBJ=0,showhideoption\n_DisplayCineFilterBJ_Defaults=ShowHideHide\n_DisplayCineFilterBJ_Category=TC_CINEMATIC\n_DisplayCineFilterBJ_ScriptName=DisplayCineFilter\n\nPingMinimap=0,real,real,real\n_PingMinimap_Defaults=0,0,1\n_PingMinimap_Limits=_,_,_,_,0,_\n_PingMinimap_Category=TC_CINEMATIC\n\nPingMinimapLocForForce=0,force,location,real\n_PingMinimapLocForForce_Defaults=GetPlayersAll,_,1\n_PingMinimapLocForForce_Limits=_,_,_,_,0,_\n_PingMinimapLocForForce_Category=TC_CINEMATIC\n\nPingMinimapEx=1,real,real,real,integer,integer,integer,pingstyle\n_PingMinimapEx_Defaults=0,0,1,0,255,0,PingStyleNormal\n_PingMinimapEx_Limits=_,_,_,_,0,_,0,255,0,255,0,255,_,_\n_PingMinimapEx_Category=TC_CINEMATIC\n\nPingMinimapLocForForceEx=1,force,location,real,minimappingstyle,real,real,real\n_PingMinimapLocForForceEx_Defaults=GetPlayersAll,_,1,MinimapPingStyleSimple,100,100,100\n_PingMinimapLocForForceEx_Limits=_,_,_,_,0,_,_,_,0,100,0,100,0,100\n_PingMinimapLocForForceEx_Category=TC_CINEMATIC\n\nUnitAddIndicator=0,unit,integer,integer,integer,integer\n_UnitAddIndicator_Defaults=_,255,255,255,255\n_UnitAddIndicator_Limits=_,_,0,255,0,255,0,255,0,255\n_UnitAddIndicator_Category=TC_CINEMATIC\n_UnitAddIndicator_ScriptName=AddIndicator\n\nUnitAddIndicatorBJ=0,unit,real,real,real,real\n_UnitAddIndicatorBJ_Defaults=_,100,100,100,0\n_UnitAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_UnitAddIndicatorBJ_Category=TC_CINEMATIC\n\nDestructableAddIndicator=0,destructable,integer,integer,integer,integer\n_DestructableAddIndicator_Defaults=_,255,255,255,255\n_DestructableAddIndicator_Limits=_,_,0,255,0,255,0,255,0,255\n_DestructableAddIndicator_Category=TC_CINEMATIC\n_DestructableAddIndicator_ScriptName=AddIndicator\n\nDestructableAddIndicatorBJ=0,destructable,real,real,real,real\n_DestructableAddIndicatorBJ_Defaults=_,100,100,100,0\n_DestructableAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_DestructableAddIndicatorBJ_Category=TC_CINEMATIC\n\nItemAddIndicator=0,item,integer,integer,integer,integer\n_ItemAddIndicator_Defaults=_,255,255,255,255\n_ItemAddIndicator_Limits=_,_,0,255,0,255,0,255,0,255\n_ItemAddIndicator_Category=TC_CINEMATIC\n_ItemAddIndicator_ScriptName=AddIndicator\n\nItemAddIndicatorBJ=0,item,real,real,real,real\n_ItemAddIndicatorBJ_Defaults=_,100,100,100,0\n_ItemAddIndicatorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_ItemAddIndicatorBJ_Category=TC_CINEMATIC\n\nShowInterface=0,onoffnotoption,real\n_ShowInterface_Defaults=OnOffNotOff,2\n_ShowInterface_Limits=_,_,0,_\n_ShowInterface_Category=TC_CINEMATIC\n\nShowInterfaceForceOff=0,force,real\n_ShowInterfaceForceOff_Defaults=GetPlayersAll,2\n_ShowInterfaceForceOff_Limits=_,_,0,_\n_ShowInterfaceForceOff_Category=TC_CINEMATIC\n\nShowInterfaceForceOn=0,force,real\n_ShowInterfaceForceOn_Defaults=GetPlayersAll,2\n_ShowInterfaceForceOn_Limits=_,_,0,_\n_ShowInterfaceForceOn_Category=TC_CINEMATIC\n\nEnableUserControl=0,onoffoption\n_EnableUserControl_Defaults=OnOffOn\n_EnableUserControl_Category=TC_CINEMATIC\n\nSetUserControlForceOff=0,force\n_SetUserControlForceOff_Defaults=GetPlayersAll\n_SetUserControlForceOff_Category=TC_CINEMATIC\n\nSetUserControlForceOn=0,force\n_SetUserControlForceOn_Defaults=GetPlayersAll\n_SetUserControlForceOn_Category=TC_CINEMATIC\n\nEnableOcclusion=0,enabledisableoption\n_EnableOcclusion_Defaults=EnableDisableDisable\n_EnableOcclusion_Category=TC_CINEMATIC\n\nEnableOcclusionBJ=0,enabledisableoption,force\n_EnableOcclusionBJ_Defaults=EnableDisableDisable,GetPlayersAll\n_EnableOcclusionBJ_Category=TC_CINEMATIC\n\nEnableWorldFogBoundary=0,enabledisableoption\n_EnableWorldFogBoundary_Defaults=EnableDisableDisable\n_EnableWorldFogBoundary_Category=TC_CINEMATIC\n\nEnableWorldFogBoundaryBJ=0,enabledisableoption,force\n_EnableWorldFogBoundaryBJ_Defaults=EnableDisableDisable,GetPlayersAll\n_EnableWorldFogBoundaryBJ_Category=TC_CINEMATIC\n\n\n// Animation actions\nSetUnitAnimation=0,unit,string\n_SetUnitAnimation_Defaults=_,\"stand\"\n_SetUnitAnimation_Category=TC_ANIMATION\n\nSetUnitAnimationByIndex=0,unit,integer\n_SetUnitAnimationByIndex_Defaults=_,0\n_SetUnitAnimationByIndex_Category=TC_ANIMATION\n\nSetUnitAnimationWithRarity=0,unit,string,raritycontrol\n_SetUnitAnimationWithRarity_Defaults=_,\"stand\",RarityControlFrequent\n_SetUnitAnimationWithRarity_Category=TC_ANIMATION\n\nQueueUnitAnimationBJ=0,unit,string\n_QueueUnitAnimationBJ_Defaults=_,\"stand\"\n_QueueUnitAnimationBJ_Category=TC_ANIMATION\n_QueueUnitAnimationBJ_ScriptName=QueueUnitAnimation\n\nResetUnitAnimation=0,unit\n_ResetUnitAnimation_Defaults=_\n_ResetUnitAnimation_Category=TC_ANIMATION\n\nAddUnitAnimationProperties=0,unit,string,addremoveoption\n_AddUnitAnimationProperties_Defaults=_,\"alternate\",AddRemoveAdd\n_AddUnitAnimationProperties_Category=TC_ANIMATION\n\nAddUnitAnimationPropertiesBJ=0,addremoveoption,string,unit\n_AddUnitAnimationPropertiesBJ_Defaults=AddRemoveAdd,\"alternate\",_\n_AddUnitAnimationPropertiesBJ_Category=TC_ANIMATION\n\nSetUnitLookAt=0,unit,unitfacingbone,unit,real,real,real\n_SetUnitLookAt_Defaults=_,UnitFacingBoneHead,_,0,0,90\n_SetUnitLookAt_Category=TC_ANIMATION\n\nResetUnitLookAt=0,unit\n_ResetUnitLookAt_Defaults=_\n_ResetUnitLookAt_Category=TC_ANIMATION\n\nSetUnitScale=0,unit,real,real,real\n_SetUnitScale_Defaults=_,1,1,1\n_SetUnitScale_Limits=_,_,0,_,0,_,0,_\n_SetUnitScale_Category=TC_ANIMATION\n\nSetUnitScalePercent=0,unit,real,real,real\n_SetUnitScalePercent_Defaults=_,100,100,100\n_SetUnitScalePercent_Limits=_,_,0,_,0,_,0,_\n_SetUnitScalePercent_Category=TC_ANIMATION\n\nSetUnitVertexColor=0,unit,integer,integer,integer,integer\n_SetUnitVertexColor_Defaults=_,255,255,255,255\n_SetUnitVertexColor_Limits=_,_,0,255,0,255,0,255,0,255\n_SetUnitVertexColor_Category=TC_ANIMATION\n\nSetUnitVertexColorBJ=0,unit,real,real,real,real\n_SetUnitVertexColorBJ_Defaults=_,100,100,100,0\n_SetUnitVertexColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_SetUnitVertexColorBJ_Category=TC_ANIMATION\n\nUnit.ResetVertexColor=0,unit\n_Unit.ResetVertexColor_Defaults=GetEnumUnit\n_Unit.ResetVertexColor_Category=TC_ANIMATION\n\nSetUnitTimeScale=0,unit,real\n_SetUnitTimeScale_Defaults=_,1\n_SetUnitTimeScale_Limits=_,_,0,_\n_SetUnitTimeScale_Category=TC_ANIMATION\n\nSetUnitTimeScalePercent=0,unit,real\n_SetUnitTimeScalePercent_Defaults=_,100\n_SetUnitTimeScalePercent_Limits=_,_,0,_\n_SetUnitTimeScalePercent_Category=TC_ANIMATION\n\nSetUnitTurnSpeedBJ=0,unit,real\n_SetUnitTurnSpeedBJ_Defaults=GetTriggerUnit,0.5\n_SetUnitTurnSpeedBJ_Limits=_,_,0,1\n_SetUnitTurnSpeedBJ_Category=TC_ANIMATION\n_SetUnitTurnSpeedBJ_ScriptName=SetUnitTurnSpeed\n\nSetUnitBlendTimeBJ=0,unit,real\n_SetUnitBlendTimeBJ_Defaults=GetTriggerUnit,_\n_SetUnitBlendTimeBJ_Category=TC_ANIMATION\n_SetUnitBlendTimeBJ_ScriptName=SetUnitBlendTime\n\nSetUnitFlyHeightBJ=0,unit,real,real\n_SetUnitFlyHeightBJ_Defaults=GetTriggerUnit,_,_\n_SetUnitFlyHeightBJ_Category=TC_ANIMATION\n_SetUnitFlyHeightBJ_ScriptName=SetUnitFlyHeight\n\nSetUnitPropWindow=0,unit,real\n_SetUnitPropWindow_Defaults=GetTriggerUnit,_\n_SetUnitPropWindow_Category=TC_ANIMATION\n\nSetUnitPropWindowBJ=0,unit,real\n_SetUnitPropWindowBJ_Defaults=GetTriggerUnit,_\n_SetUnitPropWindowBJ_Category=TC_ANIMATION\n\nSetDestructableAnimationBJ=0,destructable,string\n_SetDestructableAnimationBJ_Defaults=_,\"stand\"\n_SetDestructableAnimationBJ_Category=TC_ANIMATION\n_SetDestructableAnimationBJ_ScriptName=SetDestructableAnimation\n\nQueueDestructableAnimationBJ=0,destructable,string\n_QueueDestructableAnimationBJ_Defaults=_,\"stand\"\n_QueueDestructableAnimationBJ_Category=TC_ANIMATION\n_QueueDestructableAnimationBJ_ScriptName=QueueDestructableAnimation\n\nSetDestructableAnimationSpeed=1,destructable,real\n_SetDestructableAnimationSpeed_Defaults=_,1.0\n_SetDestructableAnimationSpeed_Category=TC_ANIMATION\n\nSetDestAnimationSpeedPercent=1,destructable,real\n_SetDestAnimationSpeedPercent_Defaults=_,100\n_SetDestAnimationSpeedPercent_Category=TC_ANIMATION\n\nSetDoodadAnimationRect=0,rect,doodadcode,string,enabledisableoption\n_SetDoodadAnimationRect_Defaults=bj_mapInitialPlayableArea,_,\"death\",EnableDisableDisable\n_SetDoodadAnimationRect_Category=TC_ANIMATION\n\nSetDoodadAnimationRectBJ=0,string,doodadcode,rect\n_SetDoodadAnimationRectBJ_Defaults=\"death\",_,GetPlayableMapRect\n_SetDoodadAnimationRectBJ_Category=TC_ANIMATION\n\nSetDoodadAnimation=0,real,real,real,doodadcode,nearestonlyoption,string,enabledisableoption\n_SetDoodadAnimation_Defaults=0,0,128,_,NearestOnlyOff,\"death\",EnableDisableDisable\n_SetDoodadAnimation_Category=TC_ANIMATION\n\nSetDoodadAnimationBJ=0,string,doodadcode,real,location\n_SetDoodadAnimationBJ_Defaults=\"death\",_,128,_\n_SetDoodadAnimationBJ_Category=TC_ANIMATION\n\n\n// Dialog actions\nDialogDisplay=0,player,dialog,showhideoption\n_DialogDisplay_Defaults=Player00,_,ShowHideShow\n_DialogDisplay_Category=TC_DIALOG\n\nDialogDisplayBJ=0,showhideoption,dialog,player\n_DialogDisplayBJ_Defaults=ShowHideShow,_,Player00\n_DialogDisplayBJ_Category=TC_DIALOG\n\nDialogSetMessageBJ=0,dialog,StringExt\n_DialogSetMessageBJ_Defaults=_,_\n_DialogSetMessageBJ_Category=TC_DIALOG\n_DialogSetMessageBJ_ScriptName=DialogSetMessage\n\nDialogAddButtonBJ=0,dialog,StringExt\n_DialogAddButtonBJ_Defaults=_,_\n_DialogAddButtonBJ_Category=TC_DIALOG\n\nDialogAddButtonWithHotkeyBJ=0,dialog,StringExt,hotkeyint\n_DialogAddButtonWithHotkeyBJ_Defaults=_,_,HotKeyIntNull\n_DialogAddButtonWithHotkeyBJ_Category=TC_DIALOG\n\nDialogAddQuitButton=0,dialog,useskipoption,StringExt,hotkeyint\n_DialogAddQuitButton_Defaults=_,UseSkipOptionUse,_,HotKeyIntNull\n_DialogAddQuitButton_Category=TC_DIALOG\n\nDialogClearBJ=0,dialog\n_DialogClearBJ_Category=TC_DIALOG\n_DialogClearBJ_ScriptName=DialogClear\n\nDialogDestroy=0,dialog\n_DialogDestroy_Category=TC_DIALOG\n\n//Melee Game actions\nMeleeStartingVisibility=0,nothing\n_MeleeStartingVisibility_Defaults=\n_MeleeStartingVisibility_Category=TC_MELEE\n\nMeleeStartingHeroLimit=0,nothing\n_MeleeStartingHeroLimit_Defaults=\n_MeleeStartingHeroLimit_Category=TC_MELEE\n\nMeleeGrantHeroItems=0,nothing\n_MeleeGrantHeroItems_Defaults=\n_MeleeGrantHeroItems_Category=TC_MELEE\n\nMeleeStartingResources=0,nothing\n_MeleeStartingResources_Defaults=\n_MeleeStartingResources_Category=TC_MELEE\n\nMeleeClearExcessUnits=0,nothing\n_MeleeClearExcessUnits_Defaults=\n_MeleeClearExcessUnits_Category=TC_MELEE\n\nMeleeStartingUnits=0,nothing\n_MeleeStartingUnits_Defaults=\n_MeleeStartingUnits_Category=TC_MELEE\n\nMeleeStartingAI=0,nothing\n_MeleeStartingAI_Defaults=\n_MeleeStartingAI_Category=TC_MELEE\n\nMeleeInitVictoryDefeat=0,nothing\n_MeleeInitVictoryDefeat_Defaults=\n_MeleeInitVictoryDefeat_Category=TC_MELEE\n\nMeleeStartingUnitsForPlayer=1,race,player,location,includeoption\n_MeleeStartingUnitsForPlayer_Defaults=RaceHuman,Player00,GetPlayerStartLocationLoc,InclusionInclude\n_MeleeStartingUnitsForPlayer_Category=TC_MELEE\n\n\n// Multiboard actions\nCreateMultiboardBJ=1,integer,integer,StringExt\n_CreateMultiboardBJ_Defaults=1,1,_\n_CreateMultiboardBJ_Limits=1,16,1,32,_,512\n_CreateMultiboardBJ_Category=TC_MULTIBOARD\n\nDestroyMultiboardBJ=1,multiboard\n_DestroyMultiboardBJ_Defaults=GetLastCreatedMultiboard\n_DestroyMultiboardBJ_Category=TC_MULTIBOARD\n_DestroyMultiboardBJ_ScriptName=DestroyMultiboard\n\nMultiboardDisplay=1,multiboard,showhideoption\n_MultiboardDisplay_Defaults=bj_lastCreatedMultiboard,ShowHideHide\n_MultiboardDisplay_Category=TC_MULTIBOARD\n\nMultiboardDisplayBJ=1,showhideoption,multiboard\n_MultiboardDisplayBJ_Defaults=ShowHideHide,GetLastCreatedMultiboard\n_MultiboardDisplayBJ_Category=TC_MULTIBOARD\n\nMultiboardSuppressDisplay=1,onoffoption\n_MultiboardSuppressDisplay_Defaults=OnOffOn\n_MultiboardSuppressDisplay_Category=TC_MULTIBOARD\n\nMultiboardAllowDisplayBJ=1,showhideoption\n_MultiboardAllowDisplayBJ_Defaults=ShowHideHide\n_MultiboardAllowDisplayBJ_Category=TC_MULTIBOARD\n\nMultiboardMinimize=1,multiboard,minimizeoption\n_MultiboardMinimize_Defaults=bj_lastCreatedMultiboard,Minimize\n_MultiboardMinimize_Category=TC_MULTIBOARD\n\nMultiboardMinimizeBJ=1,minimizeoption,multiboard\n_MultiboardMinimizeBJ_Defaults=Minimize,GetLastCreatedMultiboard\n_MultiboardMinimizeBJ_Category=TC_MULTIBOARD\n\nMultiboardClear=1,multiboard\n_MultiboardClear_Defaults=GetLastCreatedMultiboard\n_MultiboardClear_Category=TC_MULTIBOARD\n\nMultiboardSetTitleText=1,multiboard,StringExt\n_MultiboardSetTitleText_Defaults=GetLastCreatedMultiboard,_\n_MultiboardSetTitleText_Limits=_,_,_,512\n_MultiboardSetTitleText_Category=TC_MULTIBOARD\n\nMultiboardSetTitleTextColor=1,multiboard,integer,integer,integer,integer\n_MultiboardSetTitleTextColor_Defaults=bj_lastCreatedMultiboard,255,204,51,255\n_MultiboardSetTitleTextColor_Limits=_,_,0,255,0,255,0,255,0,255\n_MultiboardSetTitleTextColor_Category=TC_MULTIBOARD\n\nMultiboardSetTitleTextColorBJ=1,multiboard,real,real,real,real\n_MultiboardSetTitleTextColorBJ_Defaults=GetLastCreatedMultiboard,100,80,20,0\n_MultiboardSetTitleTextColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_MultiboardSetTitleTextColorBJ_Category=TC_MULTIBOARD\n\nMultiboardSetRowCount=1,multiboard,integer\n_MultiboardSetRowCount_Defaults=GetLastCreatedMultiboard,1\n_MultiboardSetRowCount_Limits=_,_,1,32\n_MultiboardSetRowCount_Category=TC_MULTIBOARD\n\nMultiboardSetColumnCount=1,multiboard,integer\n_MultiboardSetColumnCount_Defaults=GetLastCreatedMultiboard,1\n_MultiboardSetColumnCount_Limits=_,_,1,16\n_MultiboardSetColumnCount_Category=TC_MULTIBOARD\n\nMultiboardSetItemStyle=1,multiboarditem,showhideoption,showhideoption\n_MultiboardSetItemStyle_Defaults=_,ShowHideShow,ShowHideShow\n_MultiboardSetItemStyle_Category=TC_MULTIBOARD\n\nMultiboardSetItemValue=1,multiboarditem,StringExt\n_MultiboardSetItemValue_Category=TC_MULTIBOARD\n\nMultiboardSetItemValueColor=1,multiboarditem,integer,integer,integer,integer\n_MultiboardSetItemValueColor_Defaults=_,255,204,51,255\n_MultiboardSetItemValueColor_Limits=_,_,0,255,0,255,0,255,0,255\n_MultiboardSetItemValueColor_Category=TC_MULTIBOARD\n\nMultiboardSetItemWidth=1,multiboarditem,real\n_MultiboardSetItemWidth_Defaults=_,0.03\n_MultiboardSetItemWidth_Limits=_,_,0,1\n_MultiboardSetItemWidth_Category=TC_MULTIBOARD\n\nMultiboardSetItemIcon=1,multiboarditem,imagefile\n_MultiboardSetItemIcon_Defaults=_,\"UI\\Feedback\\Resources\\ResourceGold.blp\"\n_MultiboardSetItemIcon_Category=TC_MULTIBOARD\n\nMultiboardSetItemsStyle=1,multiboard,showhideoption,showhideoption\n_MultiboardSetItemsStyle_Defaults=bj_lastCreatedMultiboard,ShowHideShow,ShowHideShow\n_MultiboardSetItemsStyle_Category=TC_MULTIBOARD\n\nMultiboardSetItemsValue=1,multiboard,StringExt\n_MultiboardSetItemsStyle_Defaults=bj_lastCreatedMultiboard,_\n_MultiboardSetItemsValue_Category=TC_MULTIBOARD\n\nMultiboardSetItemsValueColor=1,multiboard,integer,integer,integer,integer\n_MultiboardSetItemsValueColor_Defaults=bj_lastCreatedMultiboard,255,204,51,255\n_MultiboardSetItemsValueColor_Limits=_,_,0,255,0,255,0,255,0,255\n_MultiboardSetItemsValueColor_Category=TC_MULTIBOARD\n\nMultiboardSetItemsWidth=1,multiboard,real\n_MultiboardSetItemsWidth_Defaults=bj_lastCreatedMultiboard,0.03\n_MultiboardSetItemsWidth_Limits=_,_,0,1\n_MultiboardSetItemsWidth_Category=TC_MULTIBOARD\n\nMultiboardSetItemsIcon=1,multiboard,imagefile\n_MultiboardSetItemsIcon_Defaults=bj_lastCreatedMultiboard,\"UI\\Feedback\\Resources\\ResourceGold.blp\"\n_MultiboardSetItemsIcon_Category=TC_MULTIBOARD\n\nMultiboardSetItemStyleBJ=1,multiboard,integer,integer,showhideoption,showhideoption\n_MultiboardSetItemStyleBJ_Defaults=GetLastCreatedMultiboard,1,1,ShowHideShow,ShowHideShow\n_MultiboardSetItemStyleBJ_Limits=_,_,0,_,0,_,_,_,_,_\n_MultiboardSetItemStyleBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemValueBJ=1,multiboard,integer,integer,StringExt\n_MultiboardSetItemValueBJ_Defaults=GetLastCreatedMultiboard,1,1,_\n_MultiboardSetItemValueBJ_Limits=_,_,0,_,0,_,_,128\n_MultiboardSetItemValueBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemColorBJ=1,multiboard,integer,integer,real,real,real,real\n_MultiboardSetItemColorBJ_Defaults=GetLastCreatedMultiboard,1,1,100,80,20,0\n_MultiboardSetItemColorBJ_Limits=_,_,0,_,0,_,0,100,0,100,0,100,0,100\n_MultiboardSetItemColorBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemWidthBJ=1,multiboard,integer,integer,real\n_MultiboardSetItemWidthBJ_Defaults=GetLastCreatedMultiboard,1,1,3\n_MultiboardSetItemWidthBJ_Limits=_,_,0,_,0,_,0,100\n_MultiboardSetItemWidthBJ_Category=TC_MULTIBOARD\n\nMultiboardSetItemIconBJ=1,multiboard,integer,integer,imagefile\n_MultiboardSetItemIconBJ_Defaults=GetLastCreatedMultiboard,1,1,\"UI\\Feedback\\Resources\\ResourceGold.blp\"\n_MultiboardSetItemIconBJ_Limits=_,_,0,_,0,_,_,_\n_MultiboardSetItemIconBJ_Category=TC_MULTIBOARD\n\nMultiboardReleaseItem=1,multiboarditem\n_MultiboardReleaseItem_Category=TC_MULTIBOARD\n\n\n// Environment actions\nAddWeatherEffectSaveLast=0,rect,weathereffectcode\n_AddWeatherEffectSaveLast_Defaults=GetPlayableMapRect,WeatherAshenvaleHeavyRain\n_AddWeatherEffectSaveLast_Category=TC_ENVIRONMENT\n\nEnableWeatherEffect=0,weathereffect,onoffoption\n_EnableWeatherEffect_Defaults=GetLastCreatedWeatherEffect,OnOffOn\n_EnableWeatherEffect_Category=TC_ENVIRONMENT\n\nRemoveWeatherEffectBJ=0,weathereffect\n_RemoveWeatherEffectBJ_Defaults=GetLastCreatedWeatherEffect\n_RemoveWeatherEffectBJ_Category=TC_ENVIRONMENT\n_RemoveWeatherEffectBJ_ScriptName=RemoveWeatherEffect\n\nTerrainDeformationCraterBJ=1,real,cratertype,location,real,real\n_TerrainDeformationCraterBJ_Defaults=0.5,CraterTypeTemporary,_,512,64\n_TerrainDeformationCraterBJ_Limits=0.01,_,_,_,_,_,1,_,_,_\n_TerrainDeformationCraterBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationRippleBJ=1,real,rippletype,location,real,real,real,real,real\n_TerrainDeformationRippleBJ_Defaults=4,RippleTypeNormal,_,1024,1024,64,1,512\n_TerrainDeformationRippleBJ_Limits=0.01,_,_,_,_,_,0,_,1,_,_,_,0.01,_,1,_\n_TerrainDeformationRippleBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationWaveBJ=1,real,location,location,real,real,real\n_TerrainDeformationWaveBJ_Defaults=0.5,_,_,256,96,0\n_TerrainDeformationWaveBJ_Limits=0.01,_,_,_,_,_,0,_,_,_,0,_\n_TerrainDeformationWaveBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformationRandomBJ=1,real,location,real,real,real,real\n_TerrainDeformationRandomBJ_Defaults=4,_,512,-32,32,0.1\n_TerrainDeformationRandomBJ_Limits=0.01,_,_,_,0,_,_,_,_,_,0.01,_\n_TerrainDeformationRandomBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformStop=1,terraindeformation,integer\n_TerrainDeformStop_Defaults=bj_lastCreatedTerrainDeformation,0\n_TerrainDeformStop_Limits=_,_,0,_\n_TerrainDeformStop_Category=TC_ENVIRONMENT\n\nTerrainDeformationStopBJ=1,terraindeformation,real\n_TerrainDeformationStopBJ_Defaults=GetLastCreatedTerrainDeformation,0\n_TerrainDeformationStopBJ_Limits=_,_,0,_\n_TerrainDeformationStopBJ_Category=TC_ENVIRONMENT\n\nTerrainDeformStopAll=1,nothing\n_TerrainDeformStopAll_Defaults=\n_TerrainDeformStopAll_Category=TC_ENVIRONMENT\n\nSetWaterDeforms=1,onoffoption\n_SetWaterDeforms_Defaults=OnOffOn\n_SetWaterDeforms_Category=TC_ENVIRONMENT\n\nSetTerrainType=1,real,real,terraintype,integer,integer,terrainshape\n_SetTerrainType_Defaults=0,0,TerrainTypeLdrt,-1,1,TerrainShapeCircle\n_SetTerrainType_Category=TC_ENVIRONMENT\n\nSetTerrainTypeBJ=1,location,terraintype,integer,integer,terrainshape\n_SetTerrainTypeBJ_Defaults=_,TerrainTypeLdrt,-1,1,TerrainShapeCircle\n_SetTerrainTypeBJ_Category=TC_ENVIRONMENT\n\nSetTerrainPathable=1,real,real,pathingtype,onoffoption\n_SetTerrainPathable_Defaults=0,0,PathingTypeWalkability,OnOffOn\n_SetTerrainPathable_Category=TC_ENVIRONMENT\n\nSetTerrainPathableBJ=1,location,pathingtype,onoffoption\n_SetTerrainPathableBJ_Defaults=_,PathingTypeWalkability,OnOffOn\n_SetTerrainPathableBJ_Category=TC_ENVIRONMENT\n\nSetWaterBaseColor=1,integer,integer,integer,integer\n_SetWaterBaseColor_Defaults=255,255,255,255\n_SetWaterBaseColor_Limits=0,255,0,255,0,255,0,255\n_SetWaterBaseColor_Category=TC_ENVIRONMENT\n\nSetWaterBaseColorBJ=1,real,real,real,real\n_SetWaterBaseColorBJ_Defaults=100,100,100,0\n_SetWaterBaseColorBJ_Limits=0,100,0,100,0,100,0,100\n_SetWaterBaseColorBJ_Category=TC_ENVIRONMENT\n\nSetSkyModel=0,skymodelstring\n_SetSkyModel_Defaults=SkyModelNone\n_SetSkyModel_Category=TC_ENVIRONMENT\n\nSetTerrainFogEx=0,fogstyle,real,real,real,real,real,real\n_SetTerrainFogEx_Defaults=FogStyleLinear,1000,8000,0,1,1,1\n_SetTerrainFogEx_Limits=_,_,0,_,0,_,0,_,0,1,0,1,0,1\n_SetTerrainFogEx_Category=TC_ENVIRONMENT\n\nSetTerrainFogExBJ=0,fogstyle,real,real,real,real,real,real\n_SetTerrainFogExBJ_Defaults=FogStyleLinear,1000,8000,0,100,100,100\n_SetTerrainFogExBJ_Limits=_,_,0,_,0,_,0,_,0,100,0,100,0,100\n_SetTerrainFogExBJ_Category=TC_ENVIRONMENT\n\nResetTerrainFogBJ=0,nothing\n_ResetTerrainFogBJ_Defaults=\n_ResetTerrainFogBJ_Category=TC_ENVIRONMENT\n_ResetTerrainFogBJ_ScriptName=ResetTerrainFog\n\n//SetBlightPoint\n//SetBlightLoc\n\nSetBlightRect=0,player,rect,createremoveoption\n_SetBlightRect_Defaults=Player00,bj_mapInitialPlayableArea,CreateRemoveCreate\n_SetBlightRect_Category=TC_ENVIRONMENT\n\nSetBlightRectBJ=0,createremoveoption,player,rect\n_SetBlightRectBJ_Defaults=CreateRemoveCreate,Player00,GetPlayableMapRect\n_SetBlightRectBJ_Category=TC_ENVIRONMENT\n\nSetBlight=0,player,real,real,real,createremoveoption\n_SetBlight_Defaults=Player00,0,0,512,CreateRemoveCreate\n_SetBlight_Limits=_,_,_,_,_,_,0,_,_,_\n_SetBlight_Category=TC_ENVIRONMENT\n\nSetBlightRadiusLocBJ=0,createremoveoption,player,location,real\n_SetBlightRadiusLocBJ_Defaults=CreateRemoveCreate,Player00,_,512\n_SetBlightRadiusLocBJ_Limits=_,_,_,_,_,_,0,_\n_SetBlightRadiusLocBJ_Category=TC_ENVIRONMENT\n\n\n// Countdown Timer actions\n//TimerStart\nStartTimerBJ=0,timer,periodicoption,real\n_StartTimerBJ_Defaults=_,PeriodicOptionOneTime,30\n_StartTimerBJ_Limits=_,_,_,_,0,_\n_StartTimerBJ_Category=TC_TIMER\n\nPauseTimer=0,timer\n_PauseTimer_Defaults=bj_lastStartedTimer\n_PauseTimer_Category=TC_TIMER\n\nTimerStart=0,timer,real,periodicoption,scriptcode\n_TimerStart_Defaults=_,0.03,PeriodicOptionOneTime,_\n_TimerStart_Limits=_,_,_,_,0,_,_\n_TimerStart_Category=TC_TIMER\n\nResumeTimer=0,timer\n_ResumeTimer_Defaults=bj_lastStartedTimer\n_ResumeTimer_Category=TC_TIMER\n\nPauseTimerBJ=0,pauseresumeoption,timer\n_PauseTimerBJ_Defaults=PauseResumePause,GetLastCreatedTimerBJ\n_PauseTimerBJ_Category=TC_TIMER\n\nDestroyTimer=0,timer\n_DestroyTimer_Defaults=bj_lastStartedTimer\n_DestroyTimer_Category=TC_TIMER\n\nYDWETimerDestroyTimer=0,real,timer\n_YDWETimerDestroyTimer_Defaults=2,GetLastCreatedTimerBJ\n_YDWETimerDestroyTimer_Limits=0,_,_,_\n_YDWETimerDestroyTimer_Category=TC_TIMER\n\nCreateTimerDialogBJ=0,timer,StringExt\n_CreateTimerDialogBJ_Defaults=GetLastCreatedTimerBJ,_\n_CreateTimerDialogBJ_Category=TC_TIMER\n\nDestroyTimerDialogBJ=0,timerdialog\n_DestroyTimerDialogBJ_Defaults=GetLastCreatedTimerDialogBJ\n_DestroyTimerDialogBJ_Category=TC_TIMER\n_DestroyTimerDialogBJ_ScriptName=DestroyTimerDialog\n\nTimerDialogDisplay=0,timerdialog,showhideoption\n_TimerDialogDisplay_Defaults=bj_lastCreatedTimerDialog,ShowHideHide\n_TimerDialogDisplay_Category=TC_TIMER\n\nTimerDialogDisplayBJ=0,showhideoption,timerdialog\n_TimerDialogDisplayBJ_Defaults=ShowHideHide,GetLastCreatedTimerDialogBJ\n_TimerDialogDisplayBJ_Category=TC_TIMER\n\nTimerDialogDisplayForPlayerBJ=1,showhideoption,timerdialog,player\n_TimerDialogDisplayForPlayerBJ_Defaults=ShowHideHide,GetLastCreatedTimerDialogBJ,Player00\n_TimerDialogDisplayForPlayerBJ_Category=TC_TIMER\n\nTimerDialogSetTitleBJ=0,timerdialog,StringExt\n_TimerDialogSetTitleBJ_Defaults=GetLastCreatedTimerDialogBJ,_\n_TimerDialogSetTitleBJ_Category=TC_TIMER\n_TimerDialogSetTitleBJ_ScriptName=TimerDialogSetTitle\n\nTimerDialogSetTitleColor=0,timerdialog,integer,integer,integer,integer\n_TimerDialogSetTitleColor_Defaults=bj_lastCreatedTimerDialog,255,204,51,255\n_TimerDialogSetTitleColor_Limits=_,_,0,255,0,255,0,255,0,255\n_TimerDialogSetTitleColor_Category=TC_TIMER\n\nTimerDialogSetTitleColorBJ=0,timerdialog,real,real,real,real\n_TimerDialogSetTitleColorBJ_Defaults=GetLastCreatedTimerDialogBJ,100,80,20,0\n_TimerDialogSetTitleColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_TimerDialogSetTitleColorBJ_Category=TC_TIMER\n\nTimerDialogSetTimeColor=0,timerdialog,integer,integer,integer,integer\n_TimerDialogSetTimeColor_Defaults=bj_lastCreatedTimerDialog,255,204,51,255\n_TimerDialogSetTimeColor_Limits=_,_,0,255,0,255,0,255,0,255\n_TimerDialogSetTimeColor_Category=TC_TIMER\n\nTimerDialogSetTimeColorBJ=0,timerdialog,real,real,real,real\n_TimerDialogSetTimeColorBJ_Defaults=GetLastCreatedTimerDialogBJ,100,80,20,0\n_TimerDialogSetTimeColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_TimerDialogSetTimeColorBJ_Category=TC_TIMER\n\nTimerDialogSetSpeed=0,timerdialog,real\n_TimerDialogSetSpeed_Defaults=bj_lastCreatedTimerDialog,1\n_TimerDialogSetSpeed_Category=TC_TIMER\n\n\n// Camera actions\nCameraSetupApplyForceDuration=0,camerasetup,cameraapplyoption,real\n_CameraSetupApplyForceDuration_Defaults=_,CameraApply,0\n_CameraSetupApplyForceDuration_Limits=_,_,_,_,0,_\n_CameraSetupApplyForceDuration_Category=TC_CAMERA\n\nCameraSetupApplyForPlayer=0,cameraapplyoption,camerasetup,player,real\n_CameraSetupApplyForPlayer_Defaults=CameraApply,_,Player00,0\n_CameraSetupApplyForPlayer_Limits=_,_,_,_,_,_,0,_\n_CameraSetupApplyForPlayer_Category=TC_CAMERA\n\nPanCameraToTimed=0,real,real,real\n_PanCameraToTimed_Defaults=0,0,0\n_PanCameraToTimed_Limits=_,_,_,_,0,_\n_PanCameraToTimed_Category=TC_CAMERA\n\nPanCameraToTimedLocForPlayer=0,player,location,real\n_PanCameraToTimedLocForPlayer_Defaults=Player00,_,0\n_PanCameraToTimedLocForPlayer_Limits=_,_,_,_,0,_\n_PanCameraToTimedLocForPlayer_Category=TC_CAMERA\n\nPanCameraToTimedWithZ=0,real,real,real,real\n_PanCameraToTimedWithZ_Defaults=0,0,0,0\n_PanCameraToTimedWithZ_Limits=_,_,_,_,_,_,0,_\n_PanCameraToTimedWithZ_Category=TC_CAMERA\n\nPanCameraToTimedLocWithZForPlayer=0,player,location,real,real\n_PanCameraToTimedLocWithZForPlayer_Defaults=Player00,_,0,0\n_PanCameraToTimedLocWithZForPlayer_Limits=_,_,_,_,_,_,0,_\n_PanCameraToTimedLocWithZForPlayer_Category=TC_CAMERA\n\nSmartCameraPanBJ=0,player,location,real\n_SmartCameraPanBJ_Defaults=Player00,_,0.5\n_SmartCameraPanBJ_Limits=_,_,_,_,0,_\n_SmartCameraPanBJ_Category=TC_CAMERA\n\nSetCameraField=0,camerafield,real,real\n_SetCameraField_Defaults=CameraFieldTargetDistance,CameraSetupGetField,0\n_SetCameraField_Limits=_,_,_,_,0,_\n_SetCameraField_Category=TC_CAMERA\n\nSetCameraFieldForPlayer=0,player,camerafield,real,real\n_SetCameraFieldForPlayer_Defaults=Player00,CameraFieldTargetDistance,CameraSetupGetFieldSwap,0\n_SetCameraFieldForPlayer_Limits=_,_,_,_,_,_,0,_\n_SetCameraFieldForPlayer_Category=TC_CAMERA\n\nSetCameraRotateMode=1,real,real,real,real\n_SetCameraRotateMode_Defaults=0,0,RealPi,2\n_SetCameraRotateMode_Limits=_,_,_,_,_,_,0,_\n_SetCameraRotateMode_Category=TC_CAMERA\n\nRotateCameraAroundLocBJ=1,real,location,player,real\n_RotateCameraAroundLocBJ_Defaults=90,_,Player00,2\n_RotateCameraAroundLocBJ_Limits=_,_,_,_,_,_,0,_\n_RotateCameraAroundLocBJ_Category=TC_CAMERA\n\nSetCameraTargetController=0,unit,real,real,cameraorientationoption\n_SetCameraTargetController_Defaults=GetTriggerUnit,0,0,CameraOrientationNormal\n_SetCameraTargetController_Category=TC_CAMERA\n\nSetCameraTargetControllerNoZForPlayer=0,player,unit,real,real,cameraorientationoption\n_SetCameraTargetControllerNoZForPlayer_Defaults=Player00,GetTriggerUnit,0,0,CameraOrientationNormal\n_SetCameraTargetControllerNoZForPlayer_Category=TC_CAMERA\n\nSetCameraOrientController=0,unit,real,real\n_SetCameraOrientController_Defaults=GetTriggerUnit,0,0\n_SetCameraOrientController_Category=TC_CAMERA\n\nSetCameraOrientControllerForPlayerBJ=0,player,unit,real,real\n_SetCameraOrientControllerForPlayerBJ_Defaults=Player00,GetTriggerUnit,0,0\n_SetCameraOrientControllerForPlayerBJ_Category=TC_CAMERA\n\nSetCinematicCamera=0,modelfile\n_SetCinematicCamera_Defaults=\"cinematic.mdl\"\n_SetCinematicCamera_Category=TC_CAMERA\n\nSetCinematicCameraForPlayer=0,player,modelfile\n_SetCinematicCameraForPlayer_Defaults=Player00,\"cinematic.mdl\"\n_SetCinematicCameraForPlayer_Category=TC_CAMERA\n\nStopCamera=0\n_StopCamera_Defaults=\n_StopCamera_Category=TC_CAMERA\n\nStopCameraForPlayerBJ=0,player\n_StopCameraForPlayerBJ_Defaults=Player00\n_StopCameraForPlayerBJ_Category=TC_CAMERA\n\nResetToGameCamera=0,real\n_ResetToGameCamera_Defaults=0,nothing\n_ResetToGameCamera_Limits=0,_\n_ResetToGameCamera_Category=TC_CAMERA\n\nResetToGameCameraForPlayer=0,player,real\n_ResetToGameCameraForPlayer_Defaults=Player00,0\n_ResetToGameCameraForPlayer_Limits=_,_,0,_\n_ResetToGameCameraForPlayer_Category=TC_CAMERA\n\nCameraSetSmoothingFactorBJ=0,real\n_CameraSetSmoothingFactorBJ_Defaults=1\n_CameraSetSmoothingFactorBJ_Limits=0,_\n_CameraSetSmoothingFactorBJ_Category=TC_CAMERA\n_CameraSetSmoothingFactorBJ_ScriptName=CameraSetSmoothingFactor\n\nCameraResetSmoothingFactorBJ=0,nothing\n_CameraResetSmoothingFactorBJ_Defaults=\n_CameraResetSmoothingFactorBJ_Category=TC_CAMERA\n\n//CameraSetSourceNoise\n//CameraSetTargetNoise\n\nCameraSetSourceNoiseEx=0,real,real,vertonlyoption\n_CameraSetSourceNoiseEx_Defaults=10,0.1,VertOnlyOff\n_CameraSetSourceNoiseEx_Category=TC_CAMERA\n\nCameraSetSourceNoiseForPlayer=0,player,real,real\n_CameraSetSourceNoiseForPlayer_Defaults=Player00,10,0.1\n_CameraSetSourceNoiseForPlayer_Category=TC_CAMERA\n\nCameraSetTargetNoiseEx=0,real,real,vertonlyoption\n_CameraSetTargetNoiseEx_Defaults=10,0.1,VertOnlyOff\n_CameraSetTargetNoiseEx_Category=TC_CAMERA\n\nCameraSetTargetNoiseForPlayer=0,player,real,real\n_CameraSetTargetNoiseForPlayer_Defaults=Player00,10,0.1\n_CameraSetTargetNoiseForPlayer_Category=TC_CAMERA\n\nCameraSetEQNoiseForPlayer=1,player,real\n_CameraSetEQNoiseForPlayer_Defaults=Player00,3\n_CameraSetEQNoiseForPlayer_Limits=_,_,0,_\n_CameraSetEQNoiseForPlayer_Category=TC_CAMERA\n\nCameraClearNoiseForPlayer=0,player\n_CameraClearNoiseForPlayer_Defaults=Player00\n_CameraClearNoiseForPlayer_Category=TC_CAMERA\n\nSetCameraBounds=0,real,real,real,real,real,real,real,real\n_SetCameraBounds_Category=TC_CAMERA\n\nAdjustCameraBoundsForPlayerBJ=0,cameraboundsadjusttype,player,real,real,real,real\n_AdjustCameraBoundsForPlayerBJ_Defaults=CameraBoundsAdjustAdd,Player00,0,0,0,0\n_AdjustCameraBoundsForPlayerBJ_Category=TC_CAMERA\n\nSetCameraBoundsToRectForPlayerBJ=0,player,rect\n_SetCameraBoundsToRectForPlayerBJ_Defaults=Player00,_\n_SetCameraBoundsToRectForPlayerBJ_Category=TC_CAMERA\n\nSetCameraQuickPosition=0,real,real\n_SetCameraQuickPosition_Defaults=0,0\n_SetCameraQuickPosition_Category=TC_CAMERA\n\nSetCameraQuickPositionLocForPlayer=0,player,location\n_SetCameraQuickPositionLocForPlayer_Defaults=Player00,_\n_SetCameraQuickPositionLocForPlayer_Category=TC_CAMERA\n\n\n// Visibility actions\nFogEnable=0,enableddisabledoption\n_FogEnable_Defaults=EnabledDisabledDisabled\n_FogEnable_Category=TC_YDHIDE\n\nFogEnableOn=0,nothing\n_FogEnableOn_Defaults=\n_FogEnableOn_Category=TC_YDHIDE\n\nFogEnableOff=0,nothing\n_FogEnableOff_Defaults=\n_FogEnableOff_Category=TC_YDHIDE\n\nFogMaskEnable=0,enableddisabledoption\n_FogMaskEnable_Defaults=EnabledDisabledDisabled\n_FogMaskEnable_Category=TC_VISIBILITY\n\nFogMaskEnableOn=0,nothing\n_FogMaskEnableOn_Defaults=\n_FogMaskEnableOn_Category=TC_VISIBILITY\n\nFogMaskEnableOff=0,nothing\n_FogMaskEnableOff_Defaults=\n_FogMaskEnableOff_Category=TC_VISIBILITY\n\nCreateFogModifierRectBJ=0,enableddisabledoption,player,fogstate,rect\n_CreateFogModifierRectBJ_Defaults=EnabledDisabledEnabled,Player00,FogStateVisible,GetPlayableMapRect\n_CreateFogModifierRectBJ_Category=TC_VISIBILITY\n\nCreateFogModifierRadiusLocBJ=0,enableddisabledoption,player,fogstate,location,real\n_CreateFogModifierRadiusLocBJ_Defaults=EnabledDisabledEnabled,Player00,FogStateVisible,_,512\n_CreateFogModifierRadiusLocBJ_Limits=_,_,_,_,_,_,_,_,0,_\n_CreateFogModifierRadiusLocBJ_Category=TC_VISIBILITY\n\nFogModifierStart=0,fogmodifier\n_FogModifierStart_Defaults=GetLastCreatedFogModifier\n_FogModifierStart_Category=TC_VISIBILITY\n\nFogModifierStop=0,fogmodifier\n_FogModifierStop_Defaults=GetLastCreatedFogModifier\n_FogModifierStop_Category=TC_VISIBILITY\n\nDestroyFogModifier=0,fogmodifier\n_DestroyFogModifier_Defaults=GetLastCreatedFogModifier\n_DestroyFogModifier_Category=TC_VISIBILITY\n\nSetFogStateRect=0,player,fogstate,rect,sharevisionoption\n_SetFogStateRect_Defaults=Player00,FogStateVisible,_,ShareVisionShare\n_SetFogStateRect_Category=TC_VISIBILITY\n\nSetFogStateRadius=0,player,fogstate,real,real,real,sharevisionoption\n_SetFogStateRadius_Defaults=Player00,FogStateVisible,0,0,512,ShareVisionShare\n_SetFogStateRadius_Category=TC_VISIBILITY\n\n\n// Destructable actions\nCreateDestructableLoc=0,destructablecode,location,real,real,integer\n_CreateDestructableLoc_Defaults=LTlt,_,GetRandomDirectionDeg,1,0\n_CreateDestructableLoc_Limits=_,_,_,_,_,_,0,_,0,_\n_CreateDestructableLoc_Category=TC_DESTRUCT\n\nCreateDeadDestructableLocBJ=0,destructablecode,location,real,real,integer\n_CreateDeadDestructableLocBJ_Defaults=LTlt,_,GetRandomDirectionDeg,1,0\n_CreateDeadDestructableLocBJ_Limits=_,_,_,_,_,_,0,_,0,_\n_CreateDeadDestructableLocBJ_Category=TC_DESTRUCT\n\nKillDestructable=0,destructable\n_KillDestructable_Defaults=GetLastCreatedDestructable\n_KillDestructable_Category=TC_DESTRUCT\n\nRemoveDestructable=0,destructable\n_RemoveDestructable_Defaults=GetLastCreatedDestructable\n_RemoveDestructable_Category=TC_DESTRUCT\n\nDestructableRestoreLife=0,destructable,real,showhideoption\n_DestructableRestoreLife_Defaults=GetLastCreatedDestructable,GetDestructableMaxLife,ShowHideShow\n_DestructableRestoreLife_Category=TC_DESTRUCT\n\nShowDestructable=1,destructable,showhideoption\n_ShowDestructable_Defaults=bj_lastCreatedDestructable,ShowHideHide\n_ShowDestructable_Category=TC_DESTRUCT\n\nShowDestructableBJ=1,showhideoption,destructable\n_ShowDestructableBJ_Defaults=ShowHideHide,GetLastCreatedDestructable\n_ShowDestructableBJ_Category=TC_DESTRUCT\n\nSetDestructableLifePercentBJ=0,destructable,real\n_SetDestructableLifePercentBJ_Defaults=GetLastCreatedDestructable,100\n_SetDestructableLifePercentBJ_Limits=_,_,0,100\n_SetDestructableLifePercentBJ_Category=TC_DESTRUCT\n\nSetDestructableLife=0,destructable,real\n_SetDestructableLife_Defaults=GetLastCreatedDestructable,GetDestructableMaxLife\n_SetDestructableLife_Limits=_,_,0,_\n_SetDestructableLife_Category=TC_DESTRUCT\n\nSetDestructableMaxLifeBJ=0,destructable,real\n_SetDestructableMaxLifeBJ_Defaults=GetLastCreatedDestructable,100\n_SetDestructableMaxLifeBJ_Limits=_,_,0,_\n_SetDestructableMaxLifeBJ_Category=TC_DESTRUCT\n_SetDestructableMaxLifeBJ_ScriptName=SetDestructableMaxLife\n\nModifyGateBJ=0,gateoperation,destructable\n_ModifyGateBJ_Defaults=GateOperationOpen,_\n_ModifyGateBJ_Category=TC_DESTRUCT\n\nChangeElevatorWalls=1,elevatorwallop,elevatorwalltype,destructable\n_ChangeElevatorWalls_Defaults=ElevatorWallOpClose,ElevatorWallTypeAll,_\n_ChangeElevatorWalls_Category=TC_DESTRUCT\n\nChangeElevatorHeight=1,destructable,integer\n_ChangeElevatorHeight_Defaults=_,1\n_ChangeElevatorHeight_Limits=_,_,1,3\n_ChangeElevatorHeight_Category=TC_DESTRUCT\n\nSetDestructableInvulnerableBJ=0,destructable,invulnerableoption\n_SetDestructableInvulnerableBJ_Defaults=GetLastCreatedDestructable,InvulnerabilityInvulnerable\n_SetDestructableInvulnerableBJ_Category=TC_DESTRUCT\n_SetDestructableInvulnerableBJ_ScriptName=SetDestructableInvulnerable\n\nSetDestructableOccluderHeight=1,destructable,real\n_SetDestructableOccluderHeight_Defaults=_,128\n_SetDestructableOccluderHeight_Category=TC_DESTRUCT\n\nEnumDestructablesInRectAllMultiple=1,rect\n_EnumDestructablesInRectAllMultiple_Defaults=GetPlayableMapRect\n_EnumDestructablesInRectAllMultiple_Category=TC_DESTRUCT\n_EnumDestructablesInRectAllMultiple_ScriptName=EnumDestructablesInRectAll\n\nEnumDestructablesInCircleBJMultiple=1,real,location\n_EnumDestructablesInCircleBJMultiple_Defaults=256,_\n_EnumDestructablesInCircleBJMultiple_Category=TC_DESTRUCT\n_EnumDestructablesInCircleBJMultiple_ScriptName=EnumDestructablesInCircleBJ\n\nEnumDestructablesInRectAll=0,rect,code\n_EnumDestructablesInRectAll_Defaults=GetPlayableMapRect,DoNothing\n_EnumDestructablesInRectAll_Category=TC_DESTRUCT\n\nEnumDestructablesInCircleBJ=0,real,location,code\n_EnumDestructablesInCircleBJ_Defaults=256,_,DoNothing\n_EnumDestructablesInCircleBJ_Category=TC_DESTRUCT\n\n\n// Leaderboard actions\nCreateLeaderboardBJ=0,force,StringExt\n_CreateLeaderboardBJ_Defaults=GetPlayersAll,_\n_CreateLeaderboardBJ_Category=TC_LEADERBOARD\n\nDestroyLeaderboardBJ=0,leaderboard\n_DestroyLeaderboardBJ_Defaults=GetLastCreatedLeaderboard\n_DestroyLeaderboardBJ_Category=TC_LEADERBOARD\n_DestroyLeaderboardBJ_ScriptName=DestroyLeaderboard\n\nLeaderboardClear=0,leaderboard\n_LeaderboardClear_Defaults=bj_lastCreatedLeaderboard\n_LeaderboardClear_Category=TC_LEADERBOARD\n\nLeaderboardSortItemsBJ=0,leaderboard,leaderboardsortoption,ascendingoption\n_LeaderboardSortItemsBJ_Defaults=GetLastCreatedLeaderboard,LeaderboardSortByValue,AscendingOptionDescending\n_LeaderboardSortItemsBJ_Category=TC_LEADERBOARD\n\nLeaderboardDisplay=0,leaderboard,showhideoption\n_LeaderboardDisplay_Defaults=bj_lastCreatedLeaderboard,ShowHideHide\n_LeaderboardDisplay_Category=TC_LEADERBOARD\n\nLeaderboardDisplayBJ=0,showhideoption,leaderboard\n_LeaderboardDisplayBJ_Defaults=ShowHideHide,GetLastCreatedLeaderboard\n_LeaderboardDisplayBJ_Category=TC_LEADERBOARD\n\nPlayerSetLeaderboard=0,player,leaderboard\n_PlayerSetLeaderboard_Defaults=Player00,bj_lastCreatedLeaderboard\n_PlayerSetLeaderboard_Category=TC_LEADERBOARD\n\nLeaderboardSetLabelBJ=0,leaderboard,StringExt\n_LeaderboardSetLabelBJ_Defaults=GetLastCreatedLeaderboard,_\n_LeaderboardSetLabelBJ_Category=TC_LEADERBOARD\n_LeaderboardSetLabelBJ_ScriptName=LeaderboardSetLabel\n\nLeaderboardSetLabelColor=0,leaderboard,integer,integer,integer,integer\n_LeaderboardSetLabelColor_Defaults=bj_lastCreatedLeaderboard,255,204,51,255\n_LeaderboardSetLabelColor_Limits=_,_,0,255,0,255,0,255,0,255\n_LeaderboardSetLabelColor_Category=TC_LEADERBOARD\n\nLeaderboardSetLabelColorBJ=0,leaderboard,real,real,real,real\n_LeaderboardSetLabelColorBJ_Defaults=GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetLabelColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetLabelColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetValueColor=0,leaderboard,integer,integer,integer,integer\n_LeaderboardSetValueColor_Defaults=bj_lastCreatedLeaderboard,255,204,51,255\n_LeaderboardSetValueColor_Limits=_,_,0,255,0,255,0,255,0,255\n_LeaderboardSetValueColor_Category=TC_LEADERBOARD\n\nLeaderboardSetValueColorBJ=0,leaderboard,real,real,real,real\n_LeaderboardSetValueColorBJ_Defaults=GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetValueColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetValueColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetStyleBJ=0,leaderboard,showhideoption,showhideoption,showhideoption,showhideoption\n_LeaderboardSetStyleBJ_Defaults=GetLastCreatedLeaderboard,ShowHideShow,ShowHideShow,ShowHideShow,ShowHideShow\n_LeaderboardSetStyleBJ_Category=TC_LEADERBOARD\n_LeaderboardSetStyleBJ_ScriptName=LeaderboardSetStyle\n\nLeaderboardAddItemBJ=0,player,leaderboard,StringExt,integer\n_LeaderboardAddItemBJ_Defaults=Player00,GetLastCreatedLeaderboard,_,0\n_LeaderboardAddItemBJ_Category=TC_LEADERBOARD\n\nLeaderboardRemovePlayerItemBJ=0,player,leaderboard\n_LeaderboardRemovePlayerItemBJ_Defaults=Player00,GetLastCreatedLeaderboard\n_LeaderboardRemovePlayerItemBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemLabelBJ=0,player,leaderboard,StringExt\n_LeaderboardSetPlayerItemLabelBJ_Defaults=Player00,GetLastCreatedLeaderboard,_\n_LeaderboardSetPlayerItemLabelBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemLabelColorBJ=0,player,leaderboard,real,real,real,real\n_LeaderboardSetPlayerItemLabelColorBJ_Defaults=Player00,GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetPlayerItemLabelColorBJ_Limits=_,_,_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetPlayerItemLabelColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemValueBJ=0,player,leaderboard,integer\n_LeaderboardSetPlayerItemValueBJ_Defaults=Player00,GetLastCreatedLeaderboard,0\n_LeaderboardSetPlayerItemValueBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemValueColorBJ=0,player,leaderboard,real,real,real,real\n_LeaderboardSetPlayerItemValueColorBJ_Defaults=Player00,GetLastCreatedLeaderboard,100,80,20,0\n_LeaderboardSetPlayerItemValueColorBJ_Limits=_,_,_,_,0,100,0,100,0,100,0,100\n_LeaderboardSetPlayerItemValueColorBJ_Category=TC_LEADERBOARD\n\nLeaderboardSetPlayerItemStyleBJ=0,player,leaderboard,showhideoption,showhideoption,showhideoption\n_LeaderboardSetPlayerItemStyleBJ_Defaults=Player00,GetLastCreatedLeaderboard,ShowHideShow,ShowHideShow,ShowHideShow\n_LeaderboardSetPlayerItemStyleBJ_Category=TC_LEADERBOARD\n\n\n// Text Tag actions\ntext.CreateText=0,player,unit,StringExt,real,real,real,real,real,real,real,boolean,real,real,showTo\n_text.CreateText_Defaults=GetOwningPlayer,GetTriggerUnit,_,10,100,100,100,0,58,90,false,2,3,showToC\n_text.CreateText_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100,0,_,_,_,_,_,0,_,0,_,0,2\n_text.CreateText_Category=TC_TEXTTAG\n\nCreateTextTagLocBJ=1,StringExt,location,real,real,real,real,real,real\n_CreateTextTagLocBJ_Defaults=_,_,0,10,100,100,100,0\n_CreateTextTagLocBJ_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100\n_CreateTextTagLocBJ_Category=TC_TEXTTAG\n\nCreateTextTagUnitBJ=1,StringExt,unit,real,real,real,real,real,real\n_CreateTextTagUnitBJ_Defaults=_,_,0,10,100,100,100,0\n_CreateTextTagUnitBJ_Limits=_,_,_,_,_,_,1,_,0,100,0,100,0,100,0,100\n_CreateTextTagUnitBJ_Category=TC_TEXTTAG\n\nDestroyTextTagBJ=1,texttag\n_DestroyTextTagBJ_Defaults=GetLastCreatedTextTag\n_DestroyTextTagBJ_Category=TC_TEXTTAG\n_DestroyTextTagBJ_ScriptName=DestroyTextTag\n\nYDWETimerDestroyTextTag=1,real,texttag\n_YDWETimerDestroyTextTag_Defaults=2,GetLastCreatedTextTag\n_YDWETimerDestroyTextTag_Limits=0,_,_,_\n_YDWETimerDestroyTextTag_Category=TC_TEXTTAG\n\nSetTextTagVisibility=1,texttag,showhideoption\n_SetTextTagVisibility_Defaults=bj_lastCreatedTextTag,ShowHideShow\n_SetTextTagVisibility_Category=TC_TEXTTAG\n\nShowTextTagForceBJ=1,showhideoption,texttag,force\n_ShowTextTagForceBJ_Defaults=ShowHideShow,GetLastCreatedTextTag,GetPlayersAll\n_ShowTextTagForceBJ_Category=TC_TEXTTAG\n\nSetTextTagVelocity=1,texttag,real,real\n_SetTextTagVelocity_Defaults=bj_lastCreatedTextTag,64,90\n_SetTextTagVelocity_Category=TC_TEXTTAG\n\nSetTextTagVelocityBJ=1,texttag,real,real\n_SetTextTagVelocityBJ_Defaults=GetLastCreatedTextTag,64,90\n_SetTextTagVelocityBJ_Category=TC_TEXTTAG\n\nSetTextTagColor=1,texttag,integer,integer,integer,integer\n_SetTextTagColor_Defaults=bj_lastCreatedTextTag,255,255,255,255\n_SetTextTagColor_Limits=_,_,0,255,0,255,0,255,0,255\n_SetTextTagColor_Category=TC_TEXTTAG\n\nSetTextTagColorBJ=1,texttag,real,real,real,real\n_SetTextTagColorBJ_Defaults=GetLastCreatedTextTag,100,100,100,0\n_SetTextTagColorBJ_Limits=_,_,0,100,0,100,0,100,0,100\n_SetTextTagColorBJ_Category=TC_TEXTTAG\n\nSetTextTagPos=1,texttag,real,real,real\n_SetTextTagPos_Defaults=bj_lastCreatedTextTag,0,0,0\n_SetTextTagPos_Category=TC_TEXTTAG\n\nSetTextTagPosBJ=1,texttag,location,real\n_SetTextTagPosBJ_Defaults=GetLastCreatedTextTag,_,0\n_SetTextTagPosBJ_Category=TC_TEXTTAG\n\nSetTextTagPosUnitBJ=1,texttag,unit,real\n_SetTextTagPosUnitBJ_Defaults=GetLastCreatedTextTag,_,0\n_SetTextTagPosUnitBJ_Category=TC_TEXTTAG\n_SetTextTagPosUnitBJ_ScriptName=SetTextTagPosUnit\n\nSetTextTagText=1,texttag,StringExt,real\n_SetTextTagText_Defaults=bj_lastCreatedTextTag,_,0.23\n_SetTextTagText_Category=TC_TEXTTAG\n\nSetTextTagTextBJ=1,texttag,StringExt,real\n_SetTextTagTextBJ_Defaults=GetLastCreatedTextTag,_,10\n_SetTextTagTextBJ_Category=TC_TEXTTAG\n\nSetTextTagSuspendedBJ=1,texttag,enabledisableoption\n_SetTextTagSuspendedBJ_Defaults=GetLastCreatedTextTag,EnableDisableEnable\n_SetTextTagSuspendedBJ_Category=TC_TEXTTAG\n_SetTextTagSuspendedBJ_ScriptName=SetTextTagSuspended\n\nSetTextTagPermanentBJ=1,texttag,enabledisableoption\n_SetTextTagPermanentBJ_Defaults=GetLastCreatedTextTag,EnableDisableEnable\n_SetTextTagPermanentBJ_Category=TC_TEXTTAG\n_SetTextTagPermanentBJ_ScriptName=SetTextTagPermanent\n\nSetTextTagLifespanBJ=1,texttag,real\n_SetTextTagLifespanBJ_Defaults=GetLastCreatedTextTag,5\n_SetTextTagLifespanBJ_Category=TC_TEXTTAG\n_SetTextTagLifespanBJ_ScriptName=SetTextTagLifespan\n\nSetTextTagFadepointBJ=1,texttag,real\n_SetTextTagFadepointBJ_Defaults=GetLastCreatedTextTag,4\n_SetTextTagFadepointBJ_Category=TC_TEXTTAG\n_SetTextTagFadepointBJ_ScriptName=SetTextTagFadepoint\n\nSetTextTagAgeBJ=1,texttag,real\n_SetTextTagAgeBJ_Defaults=GetLastCreatedTextTag,0\n_SetTextTagAgeBJ_Category=TC_TEXTTAG\n_SetTextTagAgeBJ_ScriptName=SetTextTagAge\n\n\n//region actions\nRegionAddRect=0,region,rect\n_RegionAddRect_Defaults=_\n_RegionAddRect_Category=TC_REGION\n\nRegionClearRect=0,region,rect\n_RegionClearRect_Defaults=_\n_RegionClearRect_Category=TC_REGION\n\nRegionAddCell=0,region,real,real\n_RegionAddCell_Defaults=_,0,0\n_RegionAddCell_Category=TC_REGION\n\nRegionAddCellAtLoc=0,region,location\n_RegionAddCellAtLoc_Defaults=_,_\n_RegionAddCellAtLoc_Category=TC_REGION\n\nRegionClearCell=0,region,real,real\n_RegionClearCell_Defaults=_,0,0\n_RegionClearCell_Category=TC_REGION\n\nRegionClearCellAtLoc=0,region,location\n_RegionClearCellAtLoc_Defaults=_,_\n_RegionClearCellAtLoc_Category=TC_REGION\n\nRemoveRegion=0,region\n_RemoveRegion_Defaults=_\n_RemoveRegion_Category=TC_REGION\n\n\n// Rect actions\nSetRect=0,rect,real,real,real,real\n_SetRect_Defaults=_,0,0,0,0\n_SetRect_Category=TC_RECT\n\nSetRectFromLoc=0,rect,location,location\n_SetRectFromLoc_Defaults=_,_,_\n_SetRectFromLoc_Category=TC_RECT\n\nMoveRectTo=0,rect,real,real\n_MoveRectTo_Defaults=_,0,0\n_MoveRectTo_Category=TC_RECT\n\nMoveRectToLoc=0,rect,location\n_MoveRectToLoc_Defaults=_,_\n_MoveRectToLoc_Category=TC_RECT\n\nRemoveRect=0,rect\n_RemoveRect_Defaults=_\n_RemoveRect_Category=TC_RECT\n\n\n// Quest actions\nQuestMessageBJ=0,force,questmessagetype,StringExt\n_QuestMessageBJ_Defaults=GetPlayersAll,QuestMessageTypeUpdated,_\n_QuestMessageBJ_Category=TC_QUEST\n\nCreateQuestBJ=0,questtypeoption,StringExt,StringExt,imagefile\n_CreateQuestBJ_Defaults=QuestTypeReqDiscovered,_,_,\"ReplaceableTextures\\CommandButtons\\BTNAmbush.blp\"\n_CreateQuestBJ_Limits=_,_,_,24,_,_,_,_\n_CreateQuestBJ_Category=TC_QUEST\n\nDestroyQuestBJ=0,quest\n_DestroyQuestBJ_Defaults=GetLastCreatedQuestBJ\n_DestroyQuestBJ_Category=TC_QUEST\n_DestroyQuestBJ_ScriptName=DestroyQuest\n\nQuestSetEnabled=0,quest,enabledisableoption\n_QuestSetEnabled_Defaults=bj_lastCreatedQuest,EnableDisableDisable\n_QuestSetEnabled_Category=TC_QUEST\n\nQuestSetEnabledBJ=0,enabledisableoption,quest\n_QuestSetEnabledBJ_Defaults=EnableDisableDisable,GetLastCreatedQuestBJ\n_QuestSetEnabledBJ_Category=TC_QUEST\n\nQuestSetCompletedBJ=0,quest,completionoption\n_QuestSetCompletedBJ_Defaults=GetLastCreatedQuestBJ,CompletionOptionCompleted\n_QuestSetCompletedBJ_Category=TC_QUEST\n_QuestSetCompletedBJ_ScriptName=QuestSetCompleted\n\nQuestSetFailedBJ=0,quest,failureoption\n_QuestSetFailedBJ_Defaults=GetLastCreatedQuestBJ,FailureOptionFailed\n_QuestSetFailedBJ_Category=TC_QUEST\n_QuestSetFailedBJ_ScriptName=QuestSetFailed\n\nQuestSetDiscoveredBJ=0,quest,discoveredoption\n_QuestSetDiscoveredBJ_Defaults=GetLastCreatedQuestBJ,DiscoveredOptionDiscovered\n_QuestSetDiscoveredBJ_Category=TC_QUEST\n_QuestSetDiscoveredBJ_ScriptName=QuestSetDiscovered\n\nQuestSetTitleBJ=0,quest,StringExt\n_QuestSetTitleBJ_Defaults=GetLastCreatedQuestBJ,_\n_QuestSetTitleBJ_Category=TC_QUEST\n_QuestSetTitleBJ_ScriptName=QuestSetTitle\n\nQuestSetDescriptionBJ=0,quest,StringExt\n_QuestSetDescriptionBJ_Defaults=GetLastCreatedQuestBJ,_\n_QuestSetDescriptionBJ_Category=TC_QUEST\n_QuestSetDescriptionBJ_ScriptName=QuestSetDescription\n\nCreateQuestItemBJ=0,quest,StringExt\n_CreateQuestItemBJ_Defaults=GetLastCreatedQuestBJ,_\n_CreateQuestItemBJ_Category=TC_QUEST\n\nQuestItemSetCompletedBJ=0,questitem,completionoption\n_QuestItemSetCompletedBJ_Defaults=GetLastCreatedQuestItemBJ,CompletionOptionCompleted\n_QuestItemSetCompletedBJ_Category=TC_QUEST\n_QuestItemSetCompletedBJ_ScriptName=QuestItemSetCompleted\n\nQuestItemSetDescriptionBJ=0,questitem,StringExt\n_QuestItemSetDescriptionBJ_Defaults=GetLastCreatedQuestItemBJ,_\n_QuestItemSetDescriptionBJ_Category=TC_QUEST\n_QuestItemSetDescriptionBJ_ScriptName=QuestItemSetDescription\n\nCreateDefeatConditionBJ=0,StringExt\n_CreateDefeatConditionBJ_Defaults=_\n_CreateDefeatConditionBJ_Category=TC_QUEST\n\nDestroyDefeatConditionBJ=0,defeatcondition\n_DestroyDefeatConditionBJ_Defaults=GetLastCreatedDefeatConditionBJ\n_DestroyDefeatConditionBJ_Category=TC_QUEST\n_DestroyDefeatConditionBJ_ScriptName=DestroyDefeatCondition\n\nDefeatConditionSetDescriptionBJ=0,defeatcondition,StringExt\n_DefeatConditionSetDescriptionBJ_Defaults=GetLastCreatedDefeatConditionBJ,_\n_DefeatConditionSetDescriptionBJ_Category=TC_QUEST\n_DefeatConditionSetDescriptionBJ_ScriptName=DefeatConditionSetDescription\n\nFlashQuestDialogButtonBJ=0,nothing\n_FlashQuestDialogButtonBJ_Defaults=\n_FlashQuestDialogButtonBJ_Category=TC_QUEST\n_FlashQuestDialogButtonBJ_ScriptName=FlashQuestDialogButton\n\n\n// Lightning actions\nAddLightningLoc=1,lightningtype,location,location\n_AddLightningLoc_Defaults=LightningTypeCLPB,_,_\n_AddLightningLoc_Category=TC_LIGHTNING\n\nDestroyLightningBJ=1,lightning\n_DestroyLightningBJ_Defaults=GetLastCreatedLightningBJ\n_DestroyLightningBJ_Category=TC_LIGHTNING\n_DestroyLightningBJ_ScriptName=DestroyLightning\n\nYDWETimerDestroyLightning=1,real,lightning\n_YDWETimerDestroyLightning_Defaults=2,GetLastCreatedLightningBJ\n_YDWETimerDestroyLightning_Limits=0,_,_,_\n_YDWETimerDestroyLightning_Category=TC_LIGHTNING\n\n//MoveLightning\n\nMoveLightningEx=1,lightning,allowdontoption,real,real,real,real,real,real\n_MoveLightningEx_Defaults=bj_lastCreatedLightning,AllowDontDont,0,0,0,0,0,0\n_MoveLightningEx_Category=TC_LIGHTNING\n\nbaka.MoveLightningEx2=1,lightning,allowdontoption,real,real,real,real,real,real\n_baka.MoveLightningEx2_Defaults=bj_lastCreatedLightning,AllowDontDont,0,0,0,0,0,0\n_baka.MoveLightningEx2_Category=TC_LIGHTNING\n\nMoveLightningLoc=1,lightning,location,location\n_MoveLightningLoc_Defaults=GetLastCreatedLightningBJ,_,_\n_MoveLightningLoc_Category=TC_LIGHTNING\n\nSetLightningColorBJ=1,lightning,real,real,real,real\n_SetLightningColorBJ_Defaults=GetLastCreatedLightningBJ,1,1,1,1\n_SetLightningColorBJ_Category=TC_LIGHTNING\n_SetLightningColorBJ_ScriptName=SetLightningColor\n\n\n// Sound actions\nPlaySoundBJ=0,sound\n_PlaySoundBJ_Defaults=_\n_PlaySoundBJ_Category=TC_SOUND\n\nPlaySoundAtPointBJ=1,sound,real,location,real\n_PlaySoundAtPointBJ_Defaults=_,100,_,0\n_PlaySoundAtPointBJ_Limits=_,_,0,100,_,_,_,_\n_PlaySoundAtPointBJ_Category=TC_SOUND\n\nSound.PlaySoundAtPointBJ2=1,sound,real,location,real\n_Sound.PlaySoundAtPointBJ2_Defaults=_,100,_,0\n_Sound.PlaySoundAtPointBJ2_Limits=_,_,0,100,_,_,_,_\n_Sound.PlaySoundAtPointBJ2_Category=TC_SOUND\n\nPlaySoundOnUnitBJ=1,sound,real,unit\n_PlaySoundOnUnitBJ_Defaults=_,100,_\n_PlaySoundOnUnitBJ_Limits=_,_,0,100,_,_\n_PlaySoundOnUnitBJ_Category=TC_SOUND\n\nPlaySoundFromOffsetBJ=1,sound,real,real\n_PlaySoundFromOffsetBJ_Defaults=_,100,0,0\n_PlaySoundFromOffsetBJ_Limits=_,_,0,100,0,_,0,_\n_PlaySoundFromOffsetBJ_Category=TC_SOUND\n\nStopSoundBJ=0,sound,fadedontoption\n_StopSoundBJ_Defaults=_,FadeDontFade\n_StopSoundBJ_Category=TC_SOUND\n\nKillSoundWhenDoneBJ=0,sound\n_KillSoundWhenDoneBJ_Defaults=_\n_KillSoundWhenDoneBJ_Category=TC_SOUND\n_KillSoundWhenDoneBJ_ScriptName=KillSoundWhenDone\n\nSetSoundVolume=0,sound,integer\n_SetSoundVolume_Defaults=_,127\n_SetSoundVolume_Limits=_,_,0,127\n_SetSoundVolume_Category=TC_SOUND\n\nSetSoundVolumeBJ=0,sound,real\n_SetSoundVolumeBJ_Defaults=_,100\n_SetSoundVolumeBJ_Limits=_,_,0,100\n_SetSoundVolumeBJ_Category=TC_SOUND\n\nSetSoundPlayPosition=1,sound,integer\n_SetSoundPlayPosition_Defaults=_,0\n_SetSoundPlayPosition_Limits=_,_,0,_\n_SetSoundPlayPosition_Category=TC_SOUND\n\nSetSoundOffsetBJ=1,real,sound\n_SetSoundOffsetBJ_Defaults=0,_\n_SetSoundOffsetBJ_Limits=0,_,_,_\n_SetSoundOffsetBJ_Category=TC_SOUND\n\nSetSoundDistanceCutoffBJ=0,sound,real\n_SetSoundDistanceCutoffBJ_Defaults=_,_\n_SetSoundDistanceCutoffBJ_Category=TC_SOUND\n_SetSoundDistanceCutoffBJ_ScriptName=SetSoundDistanceCutoff\n\nSetSoundPitchBJ=0,sound,real\n_SetSoundPitchBJ_Defaults=_,_\n_SetSoundPitchBJ_Category=TC_SOUND\n_SetSoundPitchBJ_ScriptName=SetSoundPitch\n\nAttachSoundToUnitBJ=0,sound,unit\n_AttachSoundToUnitBJ_Defaults=_,_\n_AttachSoundToUnitBJ_Category=TC_SOUND\n_AttachSoundToUnitBJ_ScriptName=AttachSoundToUnit\n\nSetSoundPosition=0,sound,real,real,real\n_SetSoundPosition_Defaults=_,0,0,0\n_SetSoundPosition_Category=TC_SOUND\n\nSetSoundPositionLocBJ=0,sound,location,real\n_SetSoundPositionLocBJ_Defaults=_,_,0\n_SetSoundPositionLocBJ_Category=TC_SOUND\n//_SetSoundPositionLocBJ_ScriptName=TC_SOUND\n\nSetSoundDistances=0,sound,real,real\n_SetSoundDistances_Defaults=_,_,_\n_SetSoundDistances_Limits=_,_,0,_,0,_\n_SetSoundDistances_Category=TC_SOUND\n\nSetStackedSoundBJ=0,addremoveoption,sound,rect\n_SetStackedSoundBJ_Defaults=AddRemoveAdd,_,_\n_SetStackedSoundBJ_Category=TC_SOUND\n\nSetAmbientDaySound=0,ambientthemeday\n_SetAmbientDaySound_Defaults=AmbientThemeDayL\n_SetAmbientDaySound_Category=TC_SOUND\n\nSetAmbientNightSound=0,ambientthemenight\n_SetAmbientNightSound_Defaults=AmbientThemeNightL\n_SetAmbientNightSound_Category=TC_SOUND\n\nEnableDawnDusk=0,enabledisableoption\n_EnableDawnDusk_Defaults=EnableDisableEnable\n_EnableDawnDusk_Category=TC_SOUND\n\nSetMapMusic=0,musicfile,enabledisableoption,integer\n_SetMapMusic_Defaults=MusicFileMusic,EnableDisableEnable,0\n_SetMapMusic_Category=TC_SOUND\n\nSetMapMusicIndexedBJ=0,musicfile,integer\n_SetMapMusicIndexedBJ_Defaults=MusicFileMusic,0\n_SetMapMusicIndexedBJ_Category=TC_SOUND\n\nSetMapMusicRandomBJ=0,musicfile\n_SetMapMusicRandomBJ_Defaults=MusicFileMusic\n_SetMapMusicRandomBJ_Category=TC_SOUND\n\nClearMapMusicBJ=0,nothing\n_ClearMapMusicBJ_Defaults=\n_ClearMapMusicBJ_Category=TC_SOUND\n_ClearMapMusicBJ_ScriptName=ClearMapMusic\n\n//PlayMusic\n//PlayMusicEx\n\nPlayMusicBJ=0,musicfile\n_PlayMusicBJ_Defaults=_\n_PlayMusicBJ_Category=TC_SOUND\n\nPlayMusicExBJ=1,musicfile,real,real\n_PlayMusicExBJ_Defaults=_,0,0\n_PlayMusicExBJ_Limits=_,_,0,_,0,_\n_PlayMusicExBJ_Category=TC_SOUND\n\nStopMusicBJ=0,fadedontoption\n_StopMusicBJ_Defaults=FadeDontFade\n_StopMusicBJ_Category=TC_SOUND\n_StopMusicBJ_ScriptName=StopMusic\n\nResumeMusicBJ=0,nothing\n_ResumeMusicBJ_Defaults=\n_ResumeMusicBJ_Category=TC_SOUND\n_ResumeMusicBJ_ScriptName=ResumeMusic\n\nSetMusicVolume=0,integer\n_SetMusicVolume_Defaults=127\n_SetMusicVolume_Limits=0,127\n_SetMusicVolume_Category=TC_SOUND\n\nSetMusicVolumeBJ=0,real\n_SetMusicVolumeBJ_Defaults=100\n_SetMusicVolumeBJ_Limits=0,100\n_SetMusicVolumeBJ_Category=TC_SOUND\n\nSetMusicPlayPosition=1,integer\n_SetMusicPlayPosition_Defaults=0\n_SetMusicPlayPosition_Limits=0,_\n_SetMusicPlayPosition_Category=TC_SOUND\n\nSetMusicOffsetBJ=1,real\n_SetMusicOffsetBJ_Defaults=0\n_SetMusicOffsetBJ_Limits=0,_\n_SetMusicOffsetBJ_Category=TC_SOUND\n\nPlayThematicMusic=0,musictheme\n_PlayThematicMusic_Defaults=MusicThemeHeroicVictory\n_PlayThematicMusic_Category=TC_SOUND\n_PlayThematicMusic_ScriptName=PlayThematicMusic\n\nPlayThematicMusicBJ=0,musictheme\n_PlayThematicMusicBJ_Defaults=MusicThemeHeroicVictory\n_PlayThematicMusicBJ_Category=TC_SOUND\n_PlayThematicMusicBJ_ScriptName=PlayThematicMusic\n\nPlayThematicMusicEx=1,musictheme,integer\n_PlayThematicMusicEx_Defaults=MusicThemeHeroicVictory,0\n_PlayThematicMusicEx_Limits=_,_,0,_\n_PlayThematicMusicEx_Category=TC_SOUND\n\nPlayThematicMusicExBJ=1,musictheme,real\n_PlayThematicMusicExBJ_Defaults=MusicThemeHeroicVictory,0\n_PlayThematicMusicExBJ_Limits=_,_,0,_\n_PlayThematicMusicExBJ_Category=TC_SOUND\n\nEndThematicMusic=0,nothing\n_EndThematicMusic_Defaults=\n_EndThematicMusic_Category=TC_SOUND\n_EndThematicMusic_ScriptName=EndThematicMusic\n\nEndThematicMusicBJ=0,nothing\n_EndThematicMusicBJ_Defaults=\n_EndThematicMusicBJ_Category=TC_SOUND\n_EndThematicMusicBJ_ScriptName=EndThematicMusic\n\nSetThematicMusicPlayPosition=1,integer\n_SetThematicMusicPlayPosition_Defaults=0\n_SetThematicMusicPlayPosition_Limits=0,_\n_SetThematicMusicPlayPosition_Category=TC_SOUND\n\nSetThematicMusicOffsetBJ=1,real\n_SetThematicMusicOffsetBJ_Defaults=0\n_SetThematicMusicOffsetBJ_Limits=0,_\n_SetThematicMusicOffsetBJ_Category=TC_SOUND\n\nVolumeGroupSetVolume=0,volumegroup,real\n_VolumeGroupSetVolume_Defaults=VolumeGroupMusic,1\n_VolumeGroupSetVolume_Limits=_,_,0,1\n_VolumeGroupSetVolume_Category=TC_SOUND\n\nVolumeGroupSetVolumeBJ=0,volumegroup,real\n_VolumeGroupSetVolumeBJ_Defaults=VolumeGroupMusic,100\n_VolumeGroupSetVolumeBJ_Limits=_,_,0,100\n_VolumeGroupSetVolumeBJ_Category=TC_SOUND\n\nSetCineModeVolumeGroupsBJ=0,nothing\n_SetCineModeVolumeGroupsBJ_Defaults=\n_SetCineModeVolumeGroupsBJ_Category=TC_SOUND\n\nSetSpeechVolumeGroupsBJ=0,nothing\n_SetSpeechVolumeGroupsBJ_Defaults=\n_SetSpeechVolumeGroupsBJ_Category=TC_SOUND\n\nVolumeGroupResetBJ=0,nothing\n_VolumeGroupResetBJ_Defaults=\n_VolumeGroupResetBJ_Category=TC_SOUND\n\n\n// Special Effect actions\nAddSpecialEffectLocBJ=0,location,modelfile\n_AddSpecialEffectLocBJ_Defaults=_,\"Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl\"\n_AddSpecialEffectLocBJ_Category=TC_SPECIALEFFECT\n\nEffect.AddSpecialEffectLocMU=0,location,modelfile\n_Effect.AddSpecialEffectLocMU_Defaults=_,\"Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl\"\n_Effect.AddSpecialEffectLocMU_Category=TC_SPECIALEFFECT\n\nAddSpecialEffectTargetUnitBJ=0,string,unit,modelfile\n_AddSpecialEffectTargetUnitBJ_Defaults=\"overhead\",GetTriggerUnit,\"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl\"\n_AddSpecialEffectTargetUnitBJ_Category=TC_SPECIALEFFECT\n\nDestroyEffectBJ=0,effect\n_DestroyEffectBJ_Defaults=GetLastCreatedEffectBJ\n_DestroyEffectBJ_Category=TC_SPECIALEFFECT\n_DestroyEffectBJ_ScriptName=DestroyEffect\n\nYDWETimerDestroyEffect=1,real,effect\n_YDWETimerDestroyEffect_Defaults=2,bj_lastCreatedEffect\n_YDWETimerDestroyEffect_Limits=0,_,_,_\n_YDWETimerDestroyEffect_Category=TC_SPECIALEFFECT\n\n// Image actions\nCreateImageBJ=1,string,real,location,real,imagetype\n_CreateImageBJ_Defaults=\"ReplaceableTextures\\Splats\\AuraRune9b.blp\",256,_,0,ImageTypeIndicator\n_CreateImageBJ_Category=TC_IMAGE\n\nDestroyImage=1,image\n_DestroyImage_Defaults=\n_DestroyImage_Category=TC_IMAGE\n\nShowImage=1,image,showhideoption\n_ShowImage_Defaults=bj_lastCreatedImage,ShowHideShow\n_ShowImage_Category=TC_IMAGE\n\nShowImageBJ=1,showhideoption,image\n_ShowImageBJ_Defaults=ShowHideShow,GetLastCreatedImage\n_ShowImageBJ_Category=TC_IMAGE\n\nSetImageConstantHeight=1,image,enabledisableoption,real\n_SetImageConstantHeight_Defaults=_,EnableDisableEnable,0\n_SetImageConstantHeight_Category=TC_IMAGE\n\nSetImagePosition=1,image,real,real,real\n_SetImagePosition_Defaults=bj_lastCreatedImage,0,0,0\n_SetImagePosition_Category=TC_IMAGE\n\nSetImagePositionBJ=1,image,location,real\n_SetImagePositionBJ_Defaults=GetLastCreatedImage,_,0\n_SetImagePositionBJ_Category=TC_IMAGE\n\nSetImageColor=1,image,integer,integer,integer,integer\n_SetImageColor_Defaults=bj_lastCreatedImage,255,255,255,255\n_SetImageColor_Limits=_,_,0,255,0,255,0,255,0,255\n_SetImageColor_Category=TC_IMAGE\n\nSetImageColorBJ=1,image,real,real,real,real\n_SetImageColorBJ_Defaults=GetLastCreatedImage,100.0,100.0,100.0,0.0\n_SetImageColorBJ_Limits=_,_,0.0,100.0,0.0,100.0,0.0,100.0,0.0,100.0\n_SetImageColorBJ_Category=TC_IMAGE\n\nSetImageRender=1,image,enabledisableoption\n_SetImageRender_Defaults=GetLastCreatedImage,EnableDisableEnable\n_SetImageRender_Category=TC_IMAGE\n\nSetImageRenderAlways=1,image,enabledisableoption\n_SetImageRenderAlways_Defaults=GetLastCreatedImage,EnableDisableEnable\n_SetImageRenderAlways_Category=TC_IMAGE\n\nSetImageAboveWater=1,image,enabledisableoption,enabledisableoption\n_SetImageAboveWater_Defaults=GetLastCreatedImage,EnableDisableEnable,EnableDisableEnable\n_SetImageAboveWater_Category=TC_IMAGE\n\nSetImageType=1,image,imagetype\n_SetImageType_Defaults=GetLastCreatedImage,ImageTypeIndicator\n_SetImageType_Category=TC_IMAGE\n\n\n// Player actions\nSetPlayerState=0,player,playerstate,integer\n_SetPlayerState_Defaults=Player00,PlayerStateGold,750\n_SetPlayerState_Category=TC_PLAYER\n_SetPlayerState_ScriptName=SetPlayerStateBJ\n\nAdjustPlayerStateBJ=0,integer,player,playerstate\n_AdjustPlayerStateBJ_Defaults=1000,Player00,PlayerStateGold\n_AdjustPlayerStateBJ_Category=TC_PLAYER\n\nSetPlayerFlag=0,player,playerflag,onoffintoption\n_SetPlayerFlag_Defaults=PlayerNA,PlayerFlagGivesBounty,OnOffIntOff\n_SetPlayerFlag_Category=TC_PLAYER\n_SetPlayerFlag_ScriptName=SetPlayerState\n\nSetPlayerFlagBJ=0,playerflag,onoffoption,player\n_SetPlayerFlagBJ_Defaults=PlayerFlagGivesBounty,OnOffOff,PlayerNA\n_SetPlayerFlagBJ_Category=TC_PLAYER\n\nSetPlayerTaxRate=1,player,player,playerresource,integer\n_SetPlayerTaxRate_Defaults=Player00,Player01,PlayerResourceGold,0\n_SetPlayerTaxRate_Limits=_,_,_,_,_,_,0,100\n_SetPlayerTaxRate_Category=TC_PLAYER\n\nSetPlayerTaxRateBJ=1,integer,playerresource,player,player\n_SetPlayerTaxRateBJ_Defaults=0,PlayerResourceGold,Player00,Player01\n_SetPlayerTaxRateBJ_Limits=0,100,_,_,_,_,_,_\n_SetPlayerTaxRateBJ_Category=TC_PLAYER\n\nSetPlayerTeam=1,player,integer\n_SetPlayerTeam_Defaults=Player00,0\n_SetPlayerTeam_Category=TC_PLAYER\n\nEnableCreepSleepBJ=1,enabledisableoption\n_EnableCreepSleepBJ_Defaults=EnableDisableDisable\n_EnableCreepSleepBJ_Category=TC_PLAYER\n\nSetPlayerAllianceStateBJ=0,player,player,alliancesetting\n_SetPlayerAllianceStateBJ_Defaults=Player00,Player01,AllianceSettingAlliedVision\n_SetPlayerAllianceStateBJ_Category=TC_PLAYER\n\nSetPlayerAlliance=0,player,player,alliancetype,onoffoption\n_SetPlayerAlliance_Defaults=Player00,Player01,AllianceTypePassive,OnOffOn\n_SetPlayerAlliance_Category=TC_PLAYER\n\nSetPlayerAllianceBJ=0,player,alliancetype,onoffoption,player\n_SetPlayerAllianceBJ_Defaults=Player00,AllianceTypePassive,OnOffOn,Player01\n_SetPlayerAllianceBJ_Category=TC_PLAYER\n\nSetPlayerAbilityAvailable=0,player,abilcode,enabledisableoption\n_SetPlayerAbilityAvailable_Defaults=Player00,_,EnableDisableDisable\n_SetPlayerAbilityAvailable_Category=TC_PLAYER\n\nSetPlayerAbilityAvailableBJ=0,enabledisableoption,abilcode,player\n_SetPlayerAbilityAvailableBJ_Defaults=EnableDisableDisable,_,Player00\n_SetPlayerAbilityAvailableBJ_Category=TC_PLAYER\n\nSetPlayerUnitAvailableBJ=0,unitcode,availabilityoption,player\n_SetPlayerUnitAvailableBJ_Defaults=hfoo,AvailabilityOptionAvailable,Player00\n_SetPlayerUnitAvailableBJ_Category=TC_PLAYER\n\nSetPlayerUnitMaxAllowed=1,unitcode,integer,player\n_SetPlayerUnitMaxAllowed_Defaults=hfoo,1,Player00\n_SetPlayerUnitMaxAllowed_Limits=_,_,-1,_,_,_\n_SetPlayerUnitMaxAllowed_Category=TC_PLAYER\n_SetPlayerUnitMaxAllowed_ScriptName=SetPlayerTechMaxAllowedSwap\n\nSetPlayerMaxHeroesAllowed=1,integer,player\n_SetPlayerMaxHeroesAllowed_Defaults=3,Player00\n_SetPlayerMaxHeroesAllowed_Limits=-1,_,_,_\n_SetPlayerMaxHeroesAllowed_Category=TC_PLAYER\n\nAddPlayerTechResearched=0,player,techcode,integer\n_AddPlayerTechResearched_Defaults=Player00,_,0\n_AddPlayerTechResearched_Limits=_,_,_,_,0,_\n_AddPlayerTechResearched_Category=TC_PLAYER\n//_AddPlayerTechResearched_ScriptName=AddPlayerTechResearched\n\nSetPlayerTechResearchedSwap=0,techcode,integer,player\n_SetPlayerTechResearchedSwap_Defaults=_,0,Player00\n_SetPlayerTechResearchedSwap_Limits=_,_,0,_,_,_\n_SetPlayerTechResearchedSwap_Category=TC_PLAYER\n\nSetPlayerTechMaxAllowedSwap=0,techcode,integer,player\n_SetPlayerTechMaxAllowedSwap_Defaults=_,0,Player00\n_SetPlayerTechMaxAllowedSwap_Limits=_,_,0,_,_,_\n_SetPlayerTechMaxAllowedSwap_Category=TC_PLAYER\n\nSetPlayerColor=0,player,playercolor\n_SetPlayerColor_Defaults=Player00,Color00\n_SetPlayerColor_Category=TC_PLAYER\n\nSetPlayerColorBJ=0,player,playercolor,playerchangecoloroption\n_SetPlayerColorBJ_Defaults=Player00,Color00,PlayerChangeColorChange\n_SetPlayerColorBJ_Category=TC_PLAYER\n\nSetPlayerHandicap=0,player,real\n_SetPlayerHandicap_Defaults=Player00,1\n_SetPlayerHandicap_Limits=_,_,0.01,10000\n_SetPlayerHandicap_Category=TC_PLAYER\n\nSetPlayerHandicapBJ=0,player,real\n_SetPlayerHandicapBJ_Defaults=Player00,100\n_SetPlayerHandicapBJ_Limits=_,_,1,10000\n_SetPlayerHandicapBJ_Category=TC_PLAYER\n\nSetPlayerOnScoreScreen=0,player,showhideoption\n_SetPlayerOnScoreScreen_Defaults=Player00,ShowHideHide\n_SetPlayerOnScoreScreen_Category=TC_PLAYER\n\nSetPlayerOnScoreScreenBJ=0,showhideoption,player\n_SetPlayerOnScoreScreenBJ_Defaults=ShowHideHide,Player00\n_SetPlayerOnScoreScreenBJ_Category=TC_PLAYER\n\nSetPlayerName=1,player,StringExt\n_SetPlayerName_Defaults=Player00,_\n_SetPlayerName_Category=TC_PLAYER\n\nRemovePlayer=0,player,playergameresult\n_RemovePlayer_Defaults=Player00,GameResultLose\n_RemovePlayer_Category=TC_PLAYER\n\nYDWEDisplayChat=0,player,ChatRecipient,StringExt\n_YDWEDisplayChat_Defaults=Player00,CHAT_RECIPIENT_ALL,_\n_YDWEDisplayChat_Category=TC_PLAYER\n\n// Player Group actions\n// Specially handled by the editor\nForForceMultiple=1,force\n_ForForceMultiple_Defaults=GetPlayersAll\n_ForForceMultiple_Category=TC_PLAYERGROUP\n_ForForceMultiple_ScriptName=ForForce\n\nForForce=0,force,code\n_ForForce_Defaults=GetPlayersAll,DoNothing\n_ForForce_Category=TC_PLAYERGROUP\n\nForceAddPlayer=0,force,player\n_ForceAddPlayer_Defaults=_,Player00\n_ForceAddPlayer_Category=TC_PLAYERGROUP\n\nForceAddPlayerSimple=0,player,force\n_ForceAddPlayerSimple_Defaults=Player00,_\n_ForceAddPlayerSimple_Category=TC_PLAYERGROUP\n\nForceRemovePlayer=0,force,player\n_ForceRemovePlayer_Defaults=_,Player00\n_ForceRemovePlayer_Category=TC_PLAYERGROUP\n\nForceRemovePlayerSimple=0,player,force\n_ForceRemovePlayerSimple_Defaults=Player00,_\n_ForceRemovePlayerSimple_Category=TC_PLAYERGROUP\n\nForceClear=0,force\n_ForceClear_Defaults=_\n_ForceClear_Category=TC_PLAYERGROUP\n\nSetForceAllianceStateBJ=1,force,force,alliancesetting\n_SetForceAllianceStateBJ_Defaults=GetPlayersAll,GetPlayersAll,AllianceSettingAlliedVision\n_SetForceAllianceStateBJ_Category=TC_PLAYERGROUP\n\nDestroyForce=0,force\n_DestroyForce_Defaults=_\n_DestroyForce_Category=TC_PLAYERGROUP\n\n\n// Item actions\nCreateItemLoc=0,itemcode,location\n_CreateItemLoc_Defaults=texp,_\n_CreateItemLoc_Category=TC_ITEM\n\nCreateItem=0,itemcode,real,real\n_CreateItem_Defaults=texp,_,_\n_CreateItem_Category=TC_ITEM\n\nRemoveItem=0,item\n_RemoveItem_Defaults=GetLastCreatedItem\n_RemoveItem_Category=TC_ITEM\n\nYDWETimerRemoveItem=0,real,item\n_YDWETimerRemoveItem_Defaults=2,GetLastCreatedItem\n_YDWETimerRemoveItem_Limits=0,_,_,_\n_YDWETimerRemoveItem_Category=TC_ITEM\n\nYDWEItemAbilityStorage=0,itemcode,abilcode\n_YDWEItemAbilityStorage_Defaults=spsh,AIfg\n_YDWEItemAbilityStorage_Category=TC_ITEM\n\nSetItemVisible=1,item,showhideoption\n_SetItemVisible_Defaults=bj_lastCreatedItem,ShowHideHide\n_SetItemVisible_Category=TC_ITEM\n\nSetItemVisibleBJ=1,showhideoption,item\n_SetItemVisibleBJ_Defaults=ShowHideHide,GetLastCreatedItem\n_SetItemVisibleBJ_Category=TC_ITEM\n\nSetItemPosition=0,item,real,real\n_SetItemPosition_Defaults=bj_lastCreatedItem,0,0\n_SetItemPosition_Category=TC_ITEM\n\nSetItemPositionLoc=0,item,location\n_SetItemPositionLoc_Defaults=GetLastCreatedItem,_\n_SetItemPositionLoc_Category=TC_ITEM\n\nSetItemLifeBJ=0,item,real\n_SetItemLifeBJ_Defaults=GetLastCreatedItem,50\n_SetItemLifeBJ_Limits=_,_,0,_\n_SetItemLifeBJ_Category=TC_ITEM\n_SetItemLifeBJ_ScriptName=SetWidgetLife\n\nSetItemCharges=1,item,integer\n_SetItemCharges_Defaults=GetLastCreatedItem,1\n_SetItemCharges_Limits=_,_,0,_\n_SetItemCharges_Category=TC_ITEM\n\nSetItemInvulnerableBJ=0,item,invulnerableoption\n_SetItemInvulnerableBJ_Defaults=GetLastCreatedItem,InvulnerabilityInvulnerable\n_SetItemInvulnerableBJ_Category=TC_ITEM\n_SetItemInvulnerableBJ_ScriptName=SetItemInvulnerable\n\nSetItemPawnable=1,item,pawnableoption\n_SetItemPawnable_Defaults=GetLastCreatedItem,PawnableOptionPawnable\n_SetItemPawnable_Category=TC_ITEM\n\nSetItemDroppableBJ=0,item,dropnodropoption\n_SetItemDroppableBJ_Defaults=GetLastCreatedItem,DropNoDropOptionNoDrop\n_SetItemDroppableBJ_Category=TC_ITEM\n_SetItemDroppableBJ_ScriptName=SetItemDroppable\n\nSetItemDropID=0,item,unitcode\n_SetItemDropID_Defaults=GetLastCreatedItem,hfoo\n_SetItemDropID_Category=TC_ITEM\n\nSetItemDropOnDeathBJ=0,item,droppableoption\n_SetItemDropOnDeathBJ_Defaults=GetLastCreatedItem,DroppableOptionDrop\n_SetItemDropOnDeathBJ_Category=TC_ITEM\n_SetItemDropOnDeathBJ_ScriptName=SetItemDropOnDeath\n\nSetItemPlayerBJ=0,item,player,colorchangeoption\n_SetItemPlayerBJ_Defaults=GetLastCreatedItem,Player00,ChangeColorTrue\n_SetItemPlayerBJ_Category=TC_ITEM\n_SetItemPlayerBJ_ScriptName=SetItemPlayer\n\nSetItemUserData=1,item,integer\n_SetItemUserData_Defaults=_,0\n_SetItemUserData_Category=TC_ITEM\n\nEnumItemsInRectBJMultiple=1,rect\n_EnumItemsInRectBJMultiple_Defaults=GetPlayableMapRect\n_EnumItemsInRectBJMultiple_Category=TC_ITEM\n_EnumItemsInRectBJMultiple_ScriptName=EnumItemsInRectBJ\n\nEnumItemsInRectBJ=1,rect,code\n_EnumItemsInRectBJ_Defaults=GetPlayableMapRect,DoNothing\n_EnumItemsInRectBJ_Category=TC_ITEM\n\n\n// Itempool actions\nYDWECreateItemPool=0,nothing\n_YDWECreateItemPool_Defaults=\n_YDWECreateItemPool_Category=TC_ITEMPOOL\n\nItemPoolAddItemType=0,itempool,itemcode,real\n_ItemPoolAddItemType_Defaults=_,texp,1\n_ItemPoolAddItemType_Category=TC_ITEMPOOL\n\n//ItemPoolAddItemType=0,itempool,itemcode,real\n//_ItemPoolAddItemType_Defaults=_,texp,1\n//_ItemPoolAddItemType_Category=TC_ITEMPOOL\n\nItemPoolRemoveItemType=0,itempool,itemcode\n_ItemPoolRemoveItemType_Defaults=_,texp\n_ItemPoolRemoveItemType_Category=TC_ITEMPOOL\n\nPlaceRandomItem=0,itempool,real,real\n_PlaceRandomItem_Defaults=_,0,0\n_PlaceRandomItem_Category=TC_ITEMPOOL\n\nYDWEPlaceRandomItem=0,itempool,real,real\n_YDWEPlaceRandomItem_Defaults=bj_lastCreatedItemPool,0,0\n_YDWEPlaceRandomItem_Category=TC_ITEMPOOL\n\nDestroyItemPool=0,itempool\n_DestroyItemPool_Defaults=_\n_DestroyItemPool_Category=TC_ITEMPOOL\n\n\n// Selection actions\nClearSelectionForPlayer=1,player\n_ClearSelectionForPlayer_Defaults=Player00\n_ClearSelectionForPlayer_Category=TC_UNITSEL\n\nSelectGroupForPlayerBJ=1,group,player\n_SelectGroupForPlayerBJ_Defaults=_,Player00\n_SelectGroupForPlayerBJ_Category=TC_UNITSEL\n\nSelectUnitForPlayerSingle=1,unit,player\n_SelectUnitForPlayerSingle_Defaults=GetTriggerUnit,Player00\n_SelectUnitForPlayerSingle_Category=TC_UNITSEL\n\nSelectUnitAddForPlayer=1,unit,player\n_SelectUnitAddForPlayer_Defaults=GetTriggerUnit,Player00\n_SelectUnitAddForPlayer_Category=TC_UNITSEL\n\nSelectUnitRemoveForPlayer=1,unit,player\n_SelectUnitRemoveForPlayer_Defaults=GetTriggerUnit,Player00\n_SelectUnitRemoveForPlayer_Category=TC_UNITSEL\n\nClearSelection=0,nothing\n_ClearSelection_Defaults=\n_ClearSelection_Category=TC_UNITSEL\n\nSelectGroupBJ=0,group\n_SelectGroupBJ_Defaults=_\n_SelectGroupBJ_Category=TC_UNITSEL\n\nSelectUnitSingle=0,unit\n_SelectUnitSingle_Defaults=GetTriggerUnit\n_SelectUnitSingle_Category=TC_UNITSEL\n\nSelectUnitAdd=0,unit\n_SelectUnitAdd_Defaults=GetTriggerUnit\n_SelectUnitAdd_Category=TC_UNITSEL\n\nSelectUnitRemove=0,unit\n_SelectUnitRemove_Defaults=GetTriggerUnit\n_SelectUnitRemove_Category=TC_UNITSEL\n\n\n// Hero actions\nSelectHeroSkill=0,unit,heroskillcode\n_SelectHeroSkill_Defaults=GetTriggerUnit,HeroSkillBlizzard\n_SelectHeroSkill_Category=TC_HERO\n\nSetHeroLevelNT=0,unit,integer,showhideoption\n_SetHeroLevelNT_Defaults=GetTriggerUnit,2,ShowHideHide\n_SetHeroLevelNT_Limits=_,_,1,_,_,_\n_SetHeroLevelNT_Category=TC_HERO\n_SetHeroLevelNT_ScriptName=SetHeroLevel\n\nUnitStripHeroLevel=0,unit,integer\n_UnitStripHeroLevel_Defaults=GetTriggerUnit,1\n_UnitStripHeroLevel_Limits=_,_,1,_\n_UnitStripHeroLevel_Category=TC_HERO\n\nSetHeroLevel=0,unit,integer,showhideoption\n_SetHeroLevel_Defaults=GetTriggerUnit,2,ShowHideHide\n_SetHeroLevel_Limits=_,_,1,_,_,_\n_SetHeroLevel_Category=TC_HERO\n_SetHeroLevel_ScriptName=SetHeroLevelBJ\n\nSetHeroXP=0,unit,integer,showhideoption\n_SetHeroXP_Defaults=GetTriggerUnit,4000,ShowHideHide\n_SetHeroXP_Limits=_,_,0,_,_,_\n_SetHeroXP_Category=TC_HERO\n\nAddHeroXP=0,unit,integer,showhideoption\n_AddHeroXP_Defaults=GetTriggerUnit,1000,ShowHideHide\n_AddHeroXP_Category=TC_HERO\n\nAddHeroXPSwapped=0,integer,unit,showhideoption\n_AddHeroXPSwapped_Defaults=1000,GetTriggerUnit,ShowHideHide\n_AddHeroXPSwapped_Category=TC_HERO\n\nSuspendHeroXP=0,unit,suspendresumeoption_R\n_SuspendHeroXP_Defaults=GetTriggerUnit,SuspendResumeSuspend_R\n_SuspendHeroXP_Category=TC_HERO\n\nSuspendHeroXPBJ=0,enabledisableoption,unit\n_SuspendHeroXPBJ_Defaults=EnableDisableDisable,GetTriggerUnit\n_SuspendHeroXPBJ_Category=TC_HERO\n\nSetPlayerHandicapXP=0,player,real\n_SetPlayerHandicapXP_Defaults=Player00,1\n_SetPlayerHandicapXP_Limits=_,_,0,_\n_SetPlayerHandicapXP_Category=TC_HERO\n\nSetPlayerHandicapXPBJ=0,player,real\n_SetPlayerHandicapXPBJ_Defaults=Player00,100\n_SetPlayerHandicapXPBJ_Limits=_,_,0,_\n_SetPlayerHandicapXPBJ_Category=TC_HERO\n\nReviveHero=0,unit,real,real,showhideoption\n_ReviveHero_Defaults=_,0,0,ShowHideHide\n_ReviveHero_Category=TC_HERO\n\nReviveHeroLoc=0,unit,location,showhideoption\n_ReviveHeroLoc_Defaults=_,_,ShowHideHide\n_ReviveHeroLoc_Category=TC_HERO\n\nSetHeroStr=1,unit,integer,enabledisableoption\n_SetHeroStr_Defaults=_,10,EnableDisableEnable\n_SetHeroStr_Category=TC_HERO\n\nSetHeroAgi=1,unit,integer,enabledisableoption\n_SetHeroAgi_Defaults=_,10,EnableDisableEnable\n_SetHeroAgi_Category=TC_HERO\n\nSetHeroInt=1,unit,integer,enabledisableoption\n_SetHeroInt_Defaults=_,10,EnableDisableEnable\n_SetHeroInt_Category=TC_HERO\n\nModifyHeroStat=1,herostat,unit,modifymethod,integer\n_ModifyHeroStat_Defaults=HeroStatStr,_,ModifyMethodAdd,10\n_ModifyHeroStat_Category=TC_HERO\n\nUnitModifySkillPoints=1,unit,integer\n_UnitModifySkillPoints_Defaults=_,1\n_UnitModifySkillPoints_Category=TC_HERO\n\nModifyHeroSkillPoints=1,unit,modifymethod,integer\n_ModifyHeroSkillPoints_Defaults=_,ModifyMethodAdd,1\n_ModifyHeroSkillPoints_Category=TC_HERO\n\nSetReservedLocalHeroButtons=1,integer\n_SetReservedLocalHeroButtons_Defaults=3\n_SetReservedLocalHeroButtons_Limits=0,6\n_SetReservedLocalHeroButtons_Category=TC_HERO\n\nUnitAddItem=0,unit,item\n_UnitAddItem_Defaults=GetTriggerUnit,GetLastCreatedItem\n_UnitAddItem_Category=TC_HERO\n\nUnitAddItemSwapped=0,item,unit\n_UnitAddItemSwapped_Defaults=GetLastCreatedItem,GetTriggerUnit\n_UnitAddItemSwapped_Category=TC_HERO\n\nUnitAddItemByIdSwapped=0,itemcode,unit\n_UnitAddItemByIdSwapped_Defaults=texp,GetTriggerUnit\n_UnitAddItemByIdSwapped_Category=TC_HERO\n\nUnitAddItemToSlotById=0,unit,itemcode,integer\n_UnitAddItemToSlotById_Defaults=GetTriggerUnit,texp,0\n_UnitAddItemToSlotById_Category=TC_HERO\n\nUnitRemoveItemSwapped=0,item,unit\n_UnitRemoveItemSwapped_Defaults=_,_\n_UnitRemoveItemSwapped_Category=TC_HERO\n\nUnitRemoveItemFromSlotSwapped=0,integer,unit\n_UnitRemoveItemFromSlotSwapped_Defaults=1,_\n_UnitRemoveItemFromSlotSwapped_Limits=1,6,_,_\n_UnitRemoveItemFromSlotSwapped_Category=TC_HERO\n\nUnitUseItem=0,unit,item\n_UnitUseItem_Defaults=_,GetLastCreatedItem\n_UnitUseItem_Category=TC_HERO\n\nUnitUseItemPoint=0,unit,item,real,real\n_UnitUseItemPoint_Defaults=_,GetLastCreatedItem,0,0\n_UnitUseItemPoint_Category=TC_HERO\n\nUnitUseItemPointLoc=0,unit,item,location\n_UnitUseItemPointLoc_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemPointLoc_Category=TC_HERO\n\nUnitUseItemTarget=0,unit,item,unit\n_UnitUseItemTarget_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemTarget_Category=TC_HERO\n\nUnitUseItemDestructable=0,unit,item,destructable\n_UnitUseItemDestructable_Defaults=_,GetLastCreatedItem,_\n_UnitUseItemDestructable_Category=TC_HERO\n_UnitUseItemDestructable_ScriptName=UnitUseItemTarget\n\n\n// Game actions\nDisplayTextToPlayer=0,player,real,real,StringExt\n_DisplayTextToPlayer_Defaults=Player00,0,0,_\n_DisplayTextToPlayer_Category=TC_GAME\n\nDisplayTimedTextToPlayer=0,player,real,real,real,StringExt\n_DisplayTimedTextToPlayer_Defaults=Player00,0,0,30,_\n_DisplayTimedTextToPlayer_Category=TC_GAME\n\nDisplayTextToForce=0,force,StringExt\n_DisplayTextToForce_Defaults=GetPlayersAll,_\n_DisplayTextToForce_Category=TC_GAME\n\nDisplayTimedTextToForce=0,force,real,StringExt\n_DisplayTimedTextToForce_Defaults=GetPlayersAll,30,_\n_DisplayTimedTextToForce_Limits=_,_,0,_,_,_\n_DisplayTimedTextToForce_Category=TC_GAME\n\nBJDebugMsg=0,StringExt\n_BJDebugMsg_Defaults=_\n_BJDebugMsg_Category=TC_GAME\n\nClearTextMessagesBJ=0,force\n_ClearTextMessagesBJ_Defaults=GetPlayersAll\n_ClearTextMessagesBJ_Category=TC_GAME\n\nClearTextMessages=0,nothing\n_ClearTextMessages_Category=TC_GAME\n\nPauseGame=0,pauseresumeoption\n_PauseGame_Defaults=PauseResumePause\n_PauseGame_Category=TC_GAME\n\nPauseGameOn=0,nothing\n_PauseGameOn_Defaults=\n_PauseGameOn_Category=TC_GAME\n\nPauseGameOff=0,nothing\n_PauseGameOff_Defaults=\n_PauseGameOff_Category=TC_GAME\n\nSetGameSpeed=0,gamespeed\n_SetGameSpeed_Defaults=GameSpeedNormal\n_SetGameSpeed_Category=TC_GAME\n\nLockGameSpeedBJ=0,nothing\n_LockGameSpeedBJ_Defaults=\n_LockGameSpeedBJ_Category=TC_GAME\n\nUnlockGameSpeedBJ=0,nothing\n_UnlockGameSpeedBJ_Defaults=\n_UnlockGameSpeedBJ_Category=TC_GAME\n\nSetMapFlag=0,mapflag,onoffoption\n_SetMapFlag_Defaults=MapFlagUseHandicaps,OnOffOn\n_SetMapFlag_Category=TC_GAME\n\nSetGameDifficulty=0,gamedifficulty\n_SetGameDifficulty_Defaults=GameDifficultyNormal\n_SetGameDifficulty_Category=TC_GAME\n\nSetTimeOfDay=0,real\n_SetTimeOfDay_Defaults=12\n_SetTimeOfDay_Limits=0,24\n_SetTimeOfDay_Category=TC_GAME\n\nSetTimeOfDayScale=0,real\n_SetTimeOfDayScale_Defaults=100\n_SetTimeOfDayScale_Defaults=0,_\n_SetTimeOfDayScale_Category=TC_GAME\n\nSetTimeOfDayScalePercentBJ=0,real\n_SetTimeOfDayScalePercentBJ_Defaults=100\n_SetTimeOfDayScalePercentBJ_Defaults=0,_\n_SetTimeOfDayScalePercentBJ_Category=TC_GAME\n\nUseTimeOfDayBJ=0,onoffoption\n_UseTimeOfDayBJ_Defaults=OnOffOff\n_UseTimeOfDayBJ_Category=TC_GAME\n\nDoNotSaveReplay=0\n_DoNotSaveReplay_Defaults=\n_DoNotSaveReplay_Category=TC_GAME\n\nCheat=1,string\n_Cheat_Defaults=\"greedisgood 999999\"\n_Cheat_Category=TC_GAME\n\nShareEverythingWithTeam=0,player\n_ShareEverythingWithTeam_Defaults=Player00\n_ShareEverythingWithTeam_Category=TC_GAME\n\nMakeUnitsPassiveForPlayer=0,player\n_MakeUnitsPassiveForPlayer_Defaults=Player00\n_MakeUnitsPassiveForPlayer_Category=TC_GAME\n\nCustomVictoryBJ=0,player,useskipoption,useskipoption\n_CustomVictoryBJ_Defaults=Player00,UseSkipOptionUse,UseSkipOptionUse\n_CustomVictoryBJ_Category=TC_GAME\n\nCustomDefeatBJ=0,player,StringExt\n_CustomDefeatBJ_Defaults=Player00,WESTRING_PEVENT_DEFEAT_MSG\n_CustomDefeatBJ_Category=TC_GAME\n\nSetNextLevelBJ=0,string\n_SetNextLevelBJ_Defaults=\"Maps\\MapName.w3m\"\n_SetNextLevelBJ_Category=TC_GAME\n\nChangeLevel=1,anyfile,useskipoption\n_ChangeLevel_Defaults=\"LoadFile.w3z\",UseSkipOptionSkip\n_ChangeLevel_Category=TC_GAME\n\nSaveGame=1,anyfile\n_SaveGame_Defaults=\"SaveFile.w3z\"\n_SaveGame_Category=TC_GAME\n\nLoadGameBJ=1,anyfile,useskipoption\n_LoadGameBJ_Defaults=\"LoadFile.w3z\",UseSkipOptionSkip\n_LoadGameBJ_Category=TC_GAME\n_LoadGameBJ_ScriptName=LoadGame\n\nSaveAndLoadGameBJ=1,anyfile,anyfile,useskipoption\n_SaveAndLoadGameBJ_Defaults=\"SaveFile.w3z\",\"LoadFile.w3z\",UseSkipOptionSkip\n_SaveAndLoadGameBJ_Category=TC_GAME\n\nSaveAndChangeLevelBJ=1,anyfile,anyfile,useskipoption\n_SaveAndChangeLevelBJ_Defaults=\"SaveFile.w3z\",\"Maps\\MapName.w3x\",UseSkipOptionSkip\n_SaveAndChangeLevelBJ_Category=TC_GAME\n\nRenameSaveDirectoryBJ=1,anyfile,anyfile\n_RenameSaveDirectoryBJ_Defaults=_,_\n_RenameSaveDirectoryBJ_Category=TC_GAME\n_RenameSaveDirectoryBJ_ScriptName=RenameSaveDirectory\n\nRemoveSaveDirectoryBJ=1,anyfile\n_RemoveSaveDirectoryBJ_Defaults=_\n_RemoveSaveDirectoryBJ_Category=TC_GAME\n_RemoveSaveDirectoryBJ_ScriptName=RemoveSaveDirectory\n\nCopySaveGameBJ=1,anyfile,anyfile\n_CopySaveGameBJ_Defaults=_,_\n_CopySaveGameBJ_Category=TC_GAME\n_CopySaveGameBJ_ScriptName=CopySaveGame\n\nSetCampaignMenuRaceBJ=0,campaignindex\n_SetCampaignMenuRaceBJ_Defaults=CampaignIndexH\n_SetCampaignMenuRaceBJ_Category=TC_GAME\n\nSetMissionAvailableBJ=0,enabledisableoption,missionindex\n_SetMissionAvailableBJ_Defaults=EnableDisableEnable,MissionIndexH01\n_SetMissionAvailableBJ_Category=TC_GAME\n\nSetCampaignAvailableBJ=0,enabledisableoption,campaignindex\n_SetCampaignAvailableBJ_Defaults=EnableDisableEnable,CampaignIndexH\n_SetCampaignAvailableBJ_Category=TC_GAME\n\nSetCinematicAvailableBJ=0,enabledisableoption,cinematicindex\n_SetCinematicAvailableBJ_Defaults=EnableDisableEnable,CinematicIndexHED\n_SetCinematicAvailableBJ_Category=TC_GAME\n\nShowCustomCampaignButton=1,showhideoption,integer\n_ShowCustomCampaignButton_Defaults=ShowHideShow,1\n_ShowCustomCampaignButton_Limits=_,_,1,_\n_ShowCustomCampaignButton_Category=TC_GAME\n\nDisableRestartMission=1,boolean\n_DisableRestartMission_Defaults=false\n_DisableRestartMission_Category=TC_GAME\n\nSetAllyColorFilterState=1,integer\n_SetAllyColorFilterState_Defaults=0\n_SetAllyColorFilterState_Limits=0,2\n_SetAllyColorFilterState_Category=TC_GAME\n\nSetCreepCampFilterState=1,showhideoption\n_SetCreepCampFilterState_Defaults=ShowHideHide\n_SetCreepCampFilterState_Category=TC_GAME\n\nEnableMinimapFilterButtons=1,enabledisableoption,enabledisableoption\n_EnableMinimapFilterButtons_Defaults=EnableDisableDisable,EnableDisableDisable\n_EnableMinimapFilterButtons_Category=TC_GAME\n\nEnableSelect=1,enabledisableoption,enabledisableoption\n_EnableSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnableSelect_Category=TC_GAME\n\nEnableDragSelect=1,enabledisableoption,enabledisableoption\n_EnableDragSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnableDragSelect_Category=TC_GAME\n\nEnablePreSelect=1,enabledisableoption,enabledisableoption\n_EnablePreSelect_Defaults=EnableDisableEnable,EnableDisableEnable\n_EnablePreSelect_Category=TC_GAME\n\nForceUIKeyBJ=0,player,string\n_ForceUIKeyBJ_Defaults=Player00,\"A\"\n_ForceUIKeyBJ_Category=TC_GAME\n\nForceUICancelBJ=0,player\n_ForceUICancelBJ_Defaults=Player00\n_ForceUICancelBJ_Category=TC_GAME\n\n//PreloadStart\n//PreloadRefresh\n//PreloadEndEx\n//PreloadGenClear\n//PreloadGenStart\n//PreloadGenEnd\n\nPreload=0,anyfile\n_Preload_Defaults=_\n_Preload_Category=TC_GAME\n\nPreloadEnd=0,real\n_PreloadEnd_Defaults=0.5\n_PreloadEnd_Category=TC_GAME\n\nPreloader=0,preloadfile\n_Preloader_Defaults=\n_Preloader_Category=TC_GAME\n\n\n// Game Cache actions\nInitGameCacheBJ=0,string\n_InitGameCacheBJ_Defaults=\"MapName.w3v\"\n_InitGameCacheBJ_Category=TC_GAMECACHE\n\nSaveGameCacheBJ=0,gamecache\n_SaveGameCacheBJ_Defaults=GetLastCreatedGameCacheBJ\n_SaveGameCacheBJ_Category=TC_GAMECACHE\n_SaveGameCacheBJ_ScriptName=SaveGameCache\n\nStoreUnitBJ=0,unit,string,string,gamecache\n_StoreUnitBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreUnitBJ_Category=TC_GAMECACHE\n\nStoreReal=0,gamecache,string,string,real\n_StoreReal_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_,_\n_StoreReal_Category=TC_GAMECACHE\n\nStoreInteger=0,gamecache,string,string,integer\n_StoreInteger_Defaults=GetLastCreatedGameCacheBJ,_,_\n_StoreInteger_Category=TC_GAMECACHE\n\nStoreBoolean=0,gamecache,string,string,boolean\n_StoreBoolean_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_,_\n_StoreBoolean_Category=TC_GAMECACHE\n\nStoreString=0,gamecache,string,string,string\n_StoreString_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_,_\n_StoreString_Category=TC_GAMECACHE\n\nRestoreUnitLocFacingAngleBJ=0,string,string,gamecache,player,location,real\n_RestoreUnitLocFacingAngleBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ,Player00,_,0\n_RestoreUnitLocFacingAngleBJ_Category=TC_GAMECACHE\n\nRestoreUnitLocFacingPointBJ=0,string,string,gamecache,player,location,location\n_RestoreUnitLocFacingPointBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ,Player00,_,_\n_RestoreUnitLocFacingPointBJ_Category=TC_GAMECACHE\n\nReloadGameCachesFromDisk=1,nothing\n_ReloadGameCachesFromDisk_Defaults=\n_ReloadGameCachesFromDisk_Category=TC_GAMECACHE\n\nFlushGameCacheBJ=1,gamecache\n_FlushGameCacheBJ_Defaults=GetLastCreatedGameCacheBJ\n_FlushGameCacheBJ_Category=TC_GAMECACHE\n_FlushGameCacheBJ_ScriptName=FlushGameCache\n\nFlushStoredMission=1,gamecache,string\n_FlushStoredMission_Defaults=GetLastCreatedGameCacheBJ,\"Category\"\n_FlushStoredMission_Category=TC_GAMECACHE\n\n// Hashtable actions\nInitHashtableBJ=0\n_InitHashtableBJ_Defaults=\n_InitHashtableBJ_Category=TC_HASHTABLE\n\nInitHashtable=0\n_InitHashtable_Defaults=\n_InitHashtable_Category=TC_HASHTABLE\n\nSaveRealBJ=0,real,integer,integer,hashtable\n_SaveRealBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveRealBJ_Category=TC_HASHTABLE\n\nSaveReal=0,hashtable,integer,integer,real\n_SaveReal_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveReal_Category=TC_HASHTABLE\n\nSaveIntegerBJ=0,integer,integer,integer,hashtable\n_SaveIntegerBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveIntegerBJ_Category=TC_HASHTABLE\n\nSaveInteger=0,hashtable,integer,integer,integer\n_SaveInteger_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveInteger_Category=TC_HASHTABLE\n\nSaveBooleanBJ=0,boolean,integer,integer,hashtable\n_SaveBooleanBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveBooleanBJ_Category=TC_HASHTABLE\n\nSaveBoolean=0,hashtable,integer,integer,boolean\n_SaveBoolean_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveBoolean_Category=TC_HASHTABLE\n\nSaveStringBJ=1,string,integer,integer,hashtable\n_SaveStringBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveStringBJ_Category=TC_HASHTABLE\n\nSaveStr=1,hashtable,integer,integer,string\n_SaveStr_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveStr_Category=TC_HASHTABLE\n\nSaveAgentHandle=0,hashtable,integer,integer,agent\n_SaveAgentHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveAgentHandle_Category=TC_HASHTABLE\n\nSavePlayerHandleBJ=0,player,integer,integer,hashtable\n_SavePlayerHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SavePlayerHandleBJ_Category=TC_HASHTABLE\n\nSavePlayerHandle=0,hashtable,integer,integer,player\n_SavePlayerHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SavePlayerHandle_Category=TC_HASHTABLE\n\nSaveWidgetHandleBJ=0,widget,integer,integer,hashtable\n_SaveWidgetHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveWidgetHandleBJ_Category=TC_HASHTABLE\n\nSaveWidgetHandle=0,hashtable,integer,integer,wigdet\n_SaveWidgetHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveWidgetHandle_Category=TC_HASHTABLE\n\nSaveDestructableHandleBJ=0,destructable,integer,integer,hashtable\n_SaveDestructableHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveDestructableHandleBJ_Category=TC_HASHTABLE\n\nSaveDestructableHandle=0,hashtable,integer,integer,destructable\n_SaveDestructableHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveDestructableHandle_Category=TC_HASHTABLE\n\nSaveItemHandleBJ=0,item,integer,integer,hashtable\n_SaveItemHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveItemHandleBJ_Category=TC_HASHTABLE\n\nSaveItemHandle=0,hashtable,integer,integer,item\n_SaveItemHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveItemHandle_Category=TC_HASHTABLE\n\nSaveUnitHandleBJ=0,unit,integer,integer,hashtable\n_SaveUnitHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveUnitHandleBJ_Category=TC_HASHTABLE\n\nSaveUnitHandle=0,hashtable,integer,integer,unit\n_SaveUnitHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveUnitHandle_Category=TC_HASHTABLE\n\n//SaveAbilityHandleBJ=0,ability,integer,integer,hashtable\n//_SaveAbilityHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveAbilityHandleBJ_Category=TC_HASHTABLE\n\n//SaveAbilityHandle=0,hashtable,integer,integer,ability\n//_SaveAbilityHandle_Defaults=GetLastCreatedHashtableBJ,1,1,bj_getSpellAbility\n//_SaveAbilityHandle_Category=TC_HASHTABLE\n\nYDWESaveAbilityHandleBJ=0,abilcode,integer,integer,hashtable\n_YDWESaveAbilityHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_YDWESaveAbilityHandleBJ_Category=TC_HASHTABLE\n\nYDWESaveAbilityHandle=0,hashtable,integer,integer,abilcode\n_YDWESaveAbilityHandle_Defaults=GetLastCreatedHashtableBJ,1,1,_\n_YDWESaveAbilityHandle_Category=TC_HASHTABLE\n\nSaveTimerHandleBJ=0,timer,integer,integer,hashtable\n_SaveTimerHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTimerHandleBJ_Category=TC_HASHTABLE\n\nSaveTimerHandle=0,hashtable,integer,integer,timer\n_SaveTimerHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTimerHandle_Category=TC_HASHTABLE\n\n//SaveTriggerRegionHandleBJ=0,region,integer,integer,hashtable\n//_SaveTriggerRegionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveTriggerRegionHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerHandleBJ=0,trigger,integer,integer,hashtable\n_SaveTriggerHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerHandle=0,hashtable,integer,integer,trigger\n_SaveTriggerHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTriggerHandle_Category=TC_HASHTABLE\n\nSaveTriggerConditionHandleBJ=0,triggercondition,integer,integer,hashtable\n_SaveTriggerConditionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerConditionHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerConditionHandle=0,hashtable,integer,integer,triggercondition\n_SaveTriggerConditionHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTriggerConditionHandle_Category=TC_HASHTABLE\n\nSaveTriggerActionHandleBJ=0,triggeraction,integer,integer,hashtable\n_SaveTriggerActionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerActionHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerActionHandle=0,hashtable,integer,integer,triggeraction\n_SaveTriggerActionHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTriggerActionHandle_Category=TC_HASHTABLE\n\nSaveTriggerEventHandleBJ=0,event,integer,integer,hashtable\n_SaveTriggerEventHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTriggerEventHandleBJ_Category=TC_HASHTABLE\n\nSaveTriggerEventHandle=0,hashtable,integer,integer,event\n_SaveTriggerEventHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTriggerEventHandle_Category=TC_HASHTABLE\n\nSaveForceHandleBJ=0,force,integer,integer,hashtable\n_SaveForceHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveForceHandleBJ_Category=TC_HASHTABLE\n\nSaveForceHandle=0,hashtable,integer,integer,force\n_SaveForceHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveForceHandle_Category=TC_HASHTABLE\n\nSaveGroupHandleBJ=0,group,integer,integer,hashtable\n_SaveGroupHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveGroupHandleBJ_Category=TC_HASHTABLE\n\nSaveGroupHandle=0,hashtable,integer,integer,group\n_SaveGroupHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveGroupHandle_Category=TC_HASHTABLE\n\nSaveLocationHandleBJ=0,location,integer,integer,hashtable\n_SaveLocationHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveLocationHandleBJ_Category=TC_HASHTABLE\n\nSaveLocationHandle=0,hashtable,integer,integer,location\n_SaveLocationHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveLocationHandle_Category=TC_HASHTABLE\n\nSaveRegionHandleBJ=0,region,integer,integer,hashtable\n_SaveRegionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveRegionHandleBJ_Category=TC_HASHTABLE\n\nSaveRegionHandle=0,hashtable,integer,integer,region\n_SaveRegionHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveRegionHandle_Category=TC_HASHTABLE\n\nSaveRectHandleBJ=0,rect,integer,integer,hashtable\n_SaveRectHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveRectHandleBJ_Category=TC_HASHTABLE\n\nSaveRectHandle=0,hashtable,integer,integer,rect\n_SaveRectHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveRectHandle_Category=TC_HASHTABLE\n\nSaveBooleanExprHandleBJ=0,boolexpr,integer,integer,hashtable\n_SaveBooleanExprHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveBooleanExprHandleBJ_Category=TC_HASHTABLE\n\nSaveBooleanExprHandle=0,hashtable,integer,integer,boolexpr\n_SaveBooleanExprHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveBooleanExprHandle_Category=TC_HASHTABLE\n\n//SaveConditionFuncHandleBJ=0,conditionfunc,integer,integer,hashtable\n//_SaveConditionFuncHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveConditionFuncHandleBJ_Category=TC_HASHTABLE\n\n//SaveFilterFuncHandleBJ=0,filterfunc,integer,integer,hashtable\n//_SaveFilterFuncHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveFilterFuncHandleBJ_Category=TC_HASHTABLE\n\nSaveSoundHandleBJ=0,sound,integer,integer,hashtable\n_SaveSoundHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveSoundHandleBJ_Category=TC_HASHTABLE\n\nSaveSoundHandle=0,hashtable,integer,integer,sound\n_SaveSoundHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveSoundHandle_Category=TC_HASHTABLE\n\n//SaveRaceHandleBJ=0,race,integer,integer,hashtable\n//_SaveRaceHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveRaceHandleBJ_Category=TC_HASHTABLE\n\nSaveEffectHandleBJ=0,effect,integer,integer,hashtable\n_SaveEffectHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveEffectHandleBJ_Category=TC_HASHTABLE\n\nSaveEffectHandle=0,hashtable,integer,integer,effect\n_SaveEffectHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveEffectHandle_Category=TC_HASHTABLE\n\nSaveUnitPoolHandleBJ=0,unitpool,integer,integer,hashtable\n_SaveUnitPoolHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveUnitPoolHandleBJ_Category=TC_HASHTABLE\n\nSaveUnitPoolHandle=0,hashtable,integer,integer,unitpool\n_SaveUnitPoolHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveUnitPoolHandle_Category=TC_HASHTABLE\n\nSaveItemPoolHandleBJ=0,itempool,integer,integer,hashtable\n_SaveItemPoolHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveItemPoolHandleBJ_Category=TC_HASHTABLE\n\nSaveItemPoolHandle=0,hashtable,integer,integer,itempool\n_SaveItemPoolHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveItemPoolHandle_Category=TC_HASHTABLE\n\nSaveQuestHandleBJ=0,quest,integer,integer,hashtable\n_SaveQuestHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveQuestHandleBJ_Category=TC_HASHTABLE\n\nSaveQuestHandle=0,hashtable,integer,integer,quest\n_SaveQuestHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveQuestHandle_Category=TC_HASHTABLE\n\nSaveQuestItemHandleBJ=0,questitem,integer,integer,hashtable\n_SaveQuestItemHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveQuestItemHandleBJ_Category=TC_HASHTABLE\n\nSaveQuestItemHandle=0,hashtable,integer,integer,questitem\n_SaveQuestItemHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveQuestItemHandle_Category=TC_HASHTABLE\n\nSaveDefeatConditionHandleBJ=0,defeatcondition,integer,integer,hashtable\n_SaveDefeatConditionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveDefeatConditionHandleBJ_Category=TC_HASHTABLE\n\nSaveDefeatConditionHandle=0,hashtable,integer,integer,defeatcondition\n_SaveDefeatConditionHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveDefeatConditionHandle_Category=TC_HASHTABLE\n\nSaveTimerDialogHandleBJ=0,timerdialog,integer,integer,hashtable\n_SaveTimerDialogHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTimerDialogHandleBJ_Category=TC_HASHTABLE\n\nSaveTimerDialogHandle=0,hashtable,integer,integer,timerdialog\n_SaveTimerDialogHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTimerDialogHandle_Category=TC_HASHTABLE\n\nSaveLeaderboardHandleBJ=0,leaderboard,integer,integer,hashtable\n_SaveLeaderboardHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveLeaderboardHandleBJ_Category=TC_HASHTABLE\n\nSaveLeaderboardHandle=0,hashtable,integer,integer,leaderboard\n_SaveLeaderboardHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveLeaderboardHandle_Category=TC_HASHTABLE\n\nSaveMultiboardHandleBJ=0,multiboard,integer,integer,hashtable\n_SaveMultiboardHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveMultiboardHandleBJ_Category=TC_HASHTABLE\n\nSaveMultiboardHandle=0,hashtable,integer,integer,multiboard\n_SaveMultiboardHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveMultiboardHandle_Category=TC_HASHTABLE\n\nSaveMultiboardItemHandleBJ=0,multiboarditem,integer,integer,hashtable\n_SaveMultiboardItemHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveMultiboardItemHandleBJ_Category=TC_HASHTABLE\n\nSaveMultiboardItemHandle=0,hashtable,integer,integer,multiboarditem\n_SaveMultiboardItemHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveMultiboardItemHandle_Category=TC_HASHTABLE\n\nSaveTrackableHandleBJ=0,trackable,integer,integer,hashtable\n_SaveTrackableHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTrackableHandleBJ_Category=TC_HASHTABLE\n\nSaveTrackableHandle=0,hashtable,integer,integer,trackable\n_SaveTrackableHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTrackableHandle_Category=TC_HASHTABLE\n\n//SaveGameCacheHandleBJ=0,gamecache,integer,integer,hashtable\n//_SaveGameCacheHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveGameCacheHandleBJ_Category=TC_HASHTABLE\n\nSaveDialogHandleBJ=0,dialog,integer,integer,hashtable\n_SaveDialogHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveDialogHandleBJ_Category=TC_HASHTABLE\n\nSaveDialogHandle=0,hashtable,integer,integer,dialog\n_SaveDialogHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveDialogHandle_Category=TC_HASHTABLE\n\nSaveButtonHandleBJ=0,button,integer,integer,hashtable\n_SaveButtonHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveButtonHandleBJ_Category=TC_HASHTABLE\n\nSaveButtonHandle=0,hashtable,integer,integer,button\n_SaveButtonHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveButtonHandle_Category=TC_HASHTABLE\n\n//SaveVersionHandleBJ=0,version,integer,integer,hashtable\n//_SaveVersionHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveVersionHandleBJ_Category=TC_HASHTABLE\n\n//SaveItemTypeHandleBJ=0,itemtype,integer,integer,hashtable\n//_SaveItemTypeHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n//_SaveItemTypeHandleBJ_Category=TC_HASHTABLE\n\nSaveTextTagHandleBJ=0,texttag,integer,integer,hashtable\n_SaveTextTagHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveTextTagHandleBJ_Category=TC_HASHTABLE\n\nSaveTextTagHandle=0,hashtable,integer,integer,texttag\n_SaveTextTagHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveTextTagHandle_Category=TC_HASHTABLE\n\nSaveLightningHandleBJ=0,lightning,integer,integer,hashtable\n_SaveLightningHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveLightningHandleBJ_Category=TC_HASHTABLE\n\nSaveLightningHandle=0,hashtable,integer,integer,lightning\n_SaveLightningHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveLightningHandle_Category=TC_HASHTABLE\n\nSaveImageHandleBJ=0,image,integer,integer,hashtable\n_SaveImageHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveImageHandleBJ_Category=TC_HASHTABLE\n\nSaveImageHandle=0,hashtable,integer,integer,image\n_SaveImageHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveImageHandle_Category=TC_HASHTABLE\n\nSaveUbersplatHandleBJ=0,ubersplat,integer,integer,hashtable\n_SaveUbersplatHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveUbersplatHandleBJ_Category=TC_HASHTABLE\n\nSaveUbersplatHandle=0,hashtable,integer,integer,ubersplat\n_SaveUbersplatHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveUbersplatHandle_Category=TC_HASHTABLE\n\nSaveFogStateHandleBJ=0,fogstate,integer,integer,hashtable\n_SaveFogStateHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveFogStateHandleBJ_Category=TC_HASHTABLE\n\nSaveFogStateHandle=0,hashtable,integer,integer,fogstate\n_SaveFogStateHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveFogStateHandle_Category=TC_HASHTABLE\n\nSaveFogModifierHandleBJ=0,fogmodifier,integer,integer,hashtable\n_SaveFogModifierHandleBJ_Defaults=_,_,_,GetLastCreatedHashtableBJ\n_SaveFogModifierHandleBJ_Category=TC_HASHTABLE\n\nSaveFogModifierHandle=0,hashtable,integer,integer,fogmodifier\n_SaveFogModifierHandle_Defaults=GetLastCreatedHashtableBJ,_,_,_\n_SaveFogModifierHandle_Category=TC_HASHTABLE\n\nSaveHashtableHandle=0,hashtable,integer,integer,hashtable\n_SaveHashtableHandle_Defaults=GetLastCreatedHashtableBJ,_,_,bj_lastCreatedHashtable\n_SaveHashtableHandle_Category=TC_HASHTABLE\n\nFlushParentHashtableBJ=1,hashtable\n_FlushParentHashtableBJ_Defaults=GetLastCreatedHashtableBJ\n_FlushParentHashtableBJ_Category=TC_HASHTABLE\n_FlushParentHashtableBJ_ScriptName=FlushParentHashtable\n\nFlushParentHashtable=1,hashtable\n_FlushParentHashtable_Defaults=GetLastCreatedHashtableBJ\n_FlushParentHashtable_Category=TC_HASHTABLE\n\nFlushChildHashtableBJ=1,integer,hashtable\n_FlushChildHashtableBJ_Defaults=_,GetLastCreatedHashtableBJ\n_FlushChildHashtableBJ_Category=TC_HASHTABLE\n\nFlushChildHashtable=1,hashtable,integer\n_FlushChildHashtable_Defaults=GetLastCreatedHashtableBJ,_\n_FlushChildHashtable_Category=TC_HASHTABLE\n\n// Neutral Building actions\nAddResourceAmountBJ=0,integer,unit\n_AddResourceAmountBJ_Defaults=5000,_\n_AddResourceAmountBJ_Category=TC_NEUTRALBUILDING\n\nSetResourceAmount=0,unit,integer\n_SetResourceAmount_Defaults=_,12500\n_SetResourceAmount_Limits=_,_,0,_\n_SetResourceAmount_Category=TC_NEUTRALBUILDING\n\nBlightGoldMineForPlayer=0,unit,player\n_BlightGoldMineForPlayer_Defaults=_,Player00\n_BlightGoldMineForPlayer_Category=TC_NEUTRALBUILDING\n\nWaygateActivateBJ=0,enabledisableoption,unit\n_WaygateActivateBJ_Defaults=EnableDisableEnable,_\n_WaygateActivateBJ_Category=TC_NEUTRALBUILDING\n\nWaygateSetDestination=0,unit,real,real\n_WaygateSetDestination_Defaults=_,0,0\n_WaygateSetDestination_Category=TC_NEUTRALBUILDING\n\nWaygateSetDestinationLocBJ=0,unit,location\n_WaygateSetDestinationLocBJ_Defaults=_,_\n_WaygateSetDestinationLocBJ_Category=TC_NEUTRALBUILDING\n\nSetAltMinimapIcon=1,imagefile\n_SetAltMinimapIcon_Defaults=\"UI\\Minimap\\Minimap-Tower\"\n_SetAltMinimapIcon_Category=TC_NEUTRALBUILDING\n\nUnitSetUsesAltIconBJ=1,onoffoption,unit\n_UnitSetUsesAltIconBJ_Defaults=OnOffOn,_\n_UnitSetUsesAltIconBJ_Category=TC_NEUTRALBUILDING\n\nAddItemToStockBJ=1,itemcode,unit,integer,integer\n_AddItemToStockBJ_Defaults=texp,GetTriggerUnit,0,1\n_AddItemToStockBJ_Category=TC_NEUTRALBUILDING\n\nAddItemToAllStock=1,itemcode,integer,integer\n_AddItemToAllStock_Defaults=texp,0,1\n_AddItemToAllStock_Category=TC_NEUTRALBUILDING\n\nAddUnitToStockBJ=1,unitcode,unit,integer,integer\n_AddUnitToStockBJ_Defaults=hfoo,GetTriggerUnit,0,1\n_AddUnitToStockBJ_Category=TC_NEUTRALBUILDING\n\nAddUnitToAllStock=1,unitcode,integer,integer\n_AddUnitToAllStock_Defaults=hfoo,0,1\n_AddUnitToAllStock_Category=TC_NEUTRALBUILDING\n\nRemoveItemFromStockBJ=1,itemcode,unit\n_RemoveItemFromStockBJ_Defaults=texp,GetTriggerUnit\n_RemoveItemFromStockBJ_Category=TC_NEUTRALBUILDING\n\nRemoveItemFromAllStock=1,itemcode\n_RemoveItemFromAllStock_Defaults=texp\n_RemoveItemFromAllStock_Category=TC_NEUTRALBUILDING\n\nRemoveUnitFromStockBJ=1,unitcode,unit\n_RemoveUnitFromStockBJ_Defaults=hfoo,GetTriggerUnit\n_RemoveUnitFromStockBJ_Category=TC_NEUTRALBUILDING\n\nRemoveUnitFromAllStock=1,unitcode\n_RemoveUnitFromAllStock_Defaults=hfoo\n_RemoveUnitFromAllStock_Category=TC_NEUTRALBUILDING\n\nSetItemTypeSlots=1,unit,integer\n_SetItemTypeSlots_Defaults=GetTriggerUnit,6\n_SetItemTypeSlots_Category=TC_NEUTRALBUILDING\n\nSetAllItemTypeSlots=1,integer\n_SetAllItemTypeSlots_Defaults=6\n_SetAllItemTypeSlots_Category=TC_NEUTRALBUILDING\n\nSetUnitTypeSlots=1,unit,integer\n_SetUnitTypeSlots_Defaults=GetTriggerUnit,6\n_SetUnitTypeSlots_Category=TC_NEUTRALBUILDING\n\nSetAllUnitTypeSlots=1,integer\n_SetAllUnitTypeSlots_Defaults=6\n_SetAllUnitTypeSlots_Category=TC_NEUTRALBUILDING\n\n\n// Obsolete actions\n//AddPerfLogLabel=0,string\n//_AddPerfLogLabel_Defaults=\"Triggered Debug Label\"\n//_AddPerfLogLabel_Category=TC_OBSOLETE\n\n//Cheat=0,string\n//_Cheat_Defaults=\"warnings\"\n//_Cheat_Category=TC_OBSOLETE\n\n//MemoryLeakHelper\nYDWEMemoryLeakHelperMapIsOpenMemoryLeakHelper=0,boolean\n_YDWEMemoryLeakHelperMapIsOpenMemoryLeakHelper_Defaults=false\n_YDWEMemoryLeakHelperMapIsOpenMemoryLeakHelper_Category=TC_YDHIDE\n\nYDWEMemoryLeakHelperDisplayLeaks=0,nothing\n_YDWEMemoryLeakHelperDisplayLeaks_Category=TC_YDHIDE\n\nYDWEMemoryLeakHelperProtectLastCaughtHandle=0,nothing\n_YDWEMemoryLeakHelperProtectLastCaughtHandle_Category=TC_YDHIDE\n\nYDWEMemoryLeakHelperProtectLocation=0,location\n_YDWEMemoryLeakHelperProtectLocation_Category=TC_YDHIDE\n\nYDWEMemoryLeakHelperProtectGroup=0,group\n_YDWEMemoryLeakHelperProtectGroup_Category=TC_YDHIDE\n\nYDWEMemoryLeakHelperProtectEffect=0,effect\n_YDWEMemoryLeakHelperProtectEffect_Defaults=GetLastCreatedEffectBJ\n_YDWEMemoryLeakHelperProtectEffect_Category=TC_YDHIDE\n\nStoreRealBJ=0,real,string,string,gamecache\n_StoreRealBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreRealBJ_Category=TC_YDHIDE\n\nStoreIntegerBJ=0,integer,string,string,gamecache\n_StoreIntegerBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreIntegerBJ_Category=TC_YDHIDE\n\nStoreBooleanBJ=0,boolean,string,string,gamecache\n_StoreBooleanBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreBooleanBJ_Category=TC_YDHIDE\n\nStoreStringBJ=1,string,string,string,gamecache\n_StoreStringBJ_Defaults=_,_,\"Category\",GetLastCreatedGameCacheBJ\n_StoreStringBJ_Category=TC_YDHIDE\n\nFlushGameCache=1,gamecache\n_FlushGameCache_Defaults=GetLastCreatedGameCacheBJ\n_FlushGameCache_Category=TC_YDHIDE\n_FlushGameCache_ScriptName=FlushGameCache\n\nFlushStoredMissionBJ=1,string,gamecache\n_FlushStoredMissionBJ_Defaults=\"Category\",GetLastCreatedGameCacheBJ\n_FlushStoredMissionBJ_Category=TC_YDHIDE\n\n\nYDWEWaitForLocalVariable=1,real\n_YDWEWaitForLocalVariable_Defaults=2\n_YDWEWaitForLocalVariable_Limits=0,_\n_YDWEWaitForLocalVariable_Category=TC_YDHIDE\n\n\n\n\n\n//***************************************************************************\n[TriggerCalls]\n\n// Defines function calls which may be used as parameter values\n// Key: Function name\n// Value 0: first game version in which this function is valid\n// Value 1: flag (0 or 1) indicating if the call can be used in events\n// Value 2: return type\n// Value 3+: argument types\n//\n// Note: Operators are specially handled by the editor\n\n// YD Beyond Fate\n\nYDWECustomScriptCode=0,1,AnyReturnType,scriptcode\n_YDWECustomScriptCode_Defaults=_\n_YDWECustomScriptCode_Category=TC_YDBF\n\nYDWEGetAnyTypeLocalVariable=0,1,AnyReturnType,scriptcode\n_YDWEGetAnyTypeLocalVariable_Defaults=_\n_YDWEGetAnyTypeLocalVariable_Category=TC_YDBF\n\nYDWEForLoopLocVarIndex=0,1,integer,scriptcode\n_YDWEForLoopLocVarIndex_Defaults=_\n_YDWEForLoopLocVarIndex_Category=TC_YDBF\n\nYDWELoadAnyTypeDataByUserData=0,1,AnyReturnType,typename,Null,scriptcode\n_YDWELoadAnyTypeDataByUserData_Defaults=_,_,_\n_YDWELoadAnyTypeDataByUserData_Category=TC_YDBF\n\nYDWEHaveSavedAnyTypeDataByUserData=0,1,boolean,typename,Null,typename,scriptcode\n_YDWEHaveSavedAnyTypeDataByUserData_Category=TC_YDBF\n\n\n//最萌小汐\nsys.isIn11=0,1,boolean\n_sys.isIn11_Category=TC_MU_BASE\n\nmath.isPointInRect=0,1,boolean,location,real,real,real,location,removeWhichLocation\n_math.isPointInRect_Defaults=_,0,1000,300,_,removeWhichLocationB\n_math.isPointInRect_Category=TC_MU_MATH\n\nmath.isInsidePolygon=0,1,boolean,integer,integer,location,boolean\n_math.isInsidePolygon_Defaults=1,3,_,true\n_math.isInsidePolygon_Category=TC_MU_MATH\n\nprocess.IsEnable=0,1,boolean,integer\n_process.IsEnable_Category=TC_MU_PROCESS\n\nprocess.HasName=0,1,boolean,unit,int,string,boolean,boolean\n_process.HasName_Defaults=GetTriggerUnit,0,_,true,false\n_process.HasName_Category=TC_MU_PROCESS\n\nUnit.IsHard=0,1,boolean,unit\n_Unit.IsHard_Category=TC_MU_UNIT\n\n// returns boolean\n\nYDWEGetLocalVariableBoolean=0,1,boolean,string\n_YDWEGetLocalVariableBoolean_Category=TC_YDLC\n\nYDWEGetLocalVariableBooleanArray=0,1,boolean,string,integer\n_YDWEGetLocalVariableBooleanArray_Defaults=_,1\n_YDWEGetLocalVariableBooleanArray_Limits=_,_,0,_\n_YDWEGetLocalVariableBooleanArray_Category=TC_YDLC\n\nYDWEGetBooleanByInteger=0,1,boolean,integer,integer\n_YDWEGetBooleanByInteger_Category=TC_YDLD\n\nYDWEGetBooleanByString=0,1,boolean,string,string\n_YDWEGetBooleanByString_Category=TC_YDLD\n\nYDWEPlatformIsInPlatform=0,1,boolean\n_YDWEPlatformIsInPlatform_Category=TC_YDFC\n\n//YDWEPlatformIsInRoom=0,1,boolean\n//_YDWEPlatformIsInRoom_Category=TC_YDFC\n\nYDWEIsItemSwitch=0,1,boolean,unit\n_YDWEIsItemSwitch_Defaults=GetTriggerUnit\n_YDWEIsItemSwitch_Category=TC_YDST\n\n  =0,1,boolean,scriptcode\n_  _Defaults=_\n_  _Category=TC_NOTHING\n\nYDWEIsTriggerEventId=0,1,boolean,eventid\n_YDWEIsTriggerEventId_Category=TC_NOTHING\n\n UnitAddAbility=0,1,boolean,unit,abilcode\n_ UnitAddAbility_Defaults=GetTriggerUnit,_\n_ UnitAddAbility_Category=TC_UNIT\n\n UnitRemoveAbility=0,1,boolean,unit,abilcode\n_ UnitRemoveAbility_Defaults=GetTriggerUnit,_\n_ UnitRemoveAbility_Category=TC_UNIT\n\nIsTriggerEnabled=0,1,boolean,trigger\n_IsTriggerEnabled_Defaults=GetTriggeringTrigger\n_IsTriggerEnabled_Category=TC_TRIGGER\n\nTriggerEvaluate=0,1,boolean,trigger\n_TriggerEvaluate_Defaults=_\n_TriggerEvaluate_Category=TC_TRIGGER\n\nIsTriggerQueuedBJ=0,1,boolean,trigger\n_IsTriggerQueuedBJ_Defaults=_\n_IsTriggerQueuedBJ_Category=TC_TRIGGER\n\nIsTriggerQueueEmptyBJ=0,1,boolean\n_IsTriggerQueueEmptyBJ_Defaults=\n_IsTriggerQueueEmptyBJ_Category=TC_TRIGGER\n\nIsUnit=0,1,boolean,unit,unit\n_IsUnit_Defaults=GetTriggerUnit,GetLastCreatedUnit\n_IsUnit_Category=TC_UNIT\n\nIsUnitDetected=0,1,boolean,unit,player\n_IsUnitDetected_Defaults=GetTriggerUnit,Player00\n_IsUnitDetected_Category=TC_UNIT\n\nIsUnitType=0,1,boolean,unit,unittype\n_IsUnitType_Defaults=GetTriggerUnit,UnitTypeStructure\n_IsUnitType_Category=TC_UNIT\n\nIsUnitRace=0,1,boolean,unit,race\n_IsUnitRace_Defaults=GetTriggerUnit,RaceHuman\n_IsUnitRace_Category=TC_UNIT\n\nIsUnitIdType=1,1,boolean,unitcode,unittype\n_IsUnitIdType_Defaults=GetUnitTypeId,UnitTypeStructure\n_IsUnitIdType_Category=TC_UNIT\n\nIsHeroUnitId=1,1,boolean,unitcode\n_IsHeroUnitId_Defaults=hfoo\n_IsHeroUnitId_Category=TC_UNIT\n\nIsUnitInGroup=0,1,boolean,unit,group\n_IsUnitInGroup_Defaults=GetTriggerUnit,_\n_IsUnitInGroup_Category=TC_UNIT\n\nIsUnitInRange=0,1,boolean,unit,unit,real\n_IsUnitInRange_Defaults=GetTriggerUnit,_,600\n_IsUnitInRange_Category=TC_UNIT\n\nIsUnitInRangeXY=0,1,boolean,unit,real,real,real\n_IsUnitInRangeXY_Defaults=GetTriggerUnit,0,0,600\n_IsUnitInRangeXY_Category=TC_UNIT\n\nIsUnitInRangeLoc=0,1,boolean,unit,location,real\n_IsUnitInRangeLoc_Defaults=GetTriggerUnit,_,600\n_IsUnitInRangeLoc_Category=TC_UNIT\n\nRectContainsUnit=0,1,boolean,rect,unit\n_RectContainsUnit_Defaults=GetPlayableMapRect,GetTriggerUnit\n_RectContainsUnit_Category=TC_UNIT\n\nIsUnitInRegion=0,1,boolean,region,unit\n_IsUnitInRegion_Defaults=_,GetTriggerUnit\n_IsUnitInRegion_Category=TC_UNIT\n\nIsUnitAliveBJ=0,1,boolean,unit\n_IsUnitAliveBJ_Defaults=GetTriggerUnit\n_IsUnitAliveBJ_Category=TC_UNIT\n\nIsUnitDeadBJ=0,1,boolean,unit\n_IsUnitDeadBJ_Defaults=GetTriggerUnit\n_IsUnitDeadBJ_Category=TC_UNIT\n\nIsUnitPausedBJ=0,1,boolean,unit\n_IsUnitPausedBJ_Defaults=GetTriggerUnit\n_IsUnitPausedBJ_Category=TC_UNIT\n_IsUnitPausedBJ_ScriptName=IsUnitPaused\n\nIsUnitHiddenBJ=0,1,boolean,unit\n_IsUnitHiddenBJ_Defaults=GetTriggerUnit\n_IsUnitHiddenBJ_Category=TC_UNIT\n_IsUnitHiddenBJ_ScriptName=IsUnitHidden\n\nIsUnitIllusionBJ=0,1,boolean,unit\n_IsUnitIllusionBJ_Defaults=GetTriggerUnit\n_IsUnitIllusionBJ_Category=TC_UNIT\n_IsUnitIllusionBJ_ScriptName=IsUnitIllusion\n\nUnitCanSleepPerm=0,1,boolean,unit\n_UnitCanSleepPerm_Defaults=GetTriggerUnit\n_UnitCanSleepPerm_Category=TC_UNIT\n_UnitCanSleepPerm_ScriptName=UnitCanSleepPerm\n\nUnitCanSleepBJ=0,1,boolean,unit\n_UnitCanSleepBJ_Defaults=GetTriggerUnit\n_UnitCanSleepBJ_Category=TC_UNIT\n_UnitCanSleepBJ_ScriptName=UnitCanSleep\n\nUnitIsSleepingBJ=0,1,boolean,unit\n_UnitIsSleepingBJ_Defaults=GetTriggerUnit\n_UnitIsSleepingBJ_Category=TC_UNIT\n_UnitIsSleepingBJ_ScriptName=UnitIsSleeping\n\nDoesUnitGenerateAlarms=1,0,boolean,unit\n_DoesUnitGenerateAlarms_Defaults=GetTriggerUnit\n_DoesUnitGenerateAlarms_Category=TC_UNIT\n\nIsUnitLoadedBJ=0,1,boolean,unit\n_IsUnitLoadedBJ_Defaults=GetTriggerUnit\n_IsUnitLoadedBJ_Category=TC_UNIT\n_IsUnitLoadedBJ_ScriptName=IsUnitLoaded\n\nIsUnitInTransportBJ=0,1,boolean,unit,unit\n_IsUnitInTransportBJ_Defaults=GetTriggerUnit,_\n_IsUnitInTransportBJ_Category=TC_UNIT\n_IsUnitInTransportBJ_ScriptName=IsUnitInTransport\n\nIsUnitSelected=0,1,boolean,unit,player\n_IsUnitSelected_Defaults=GetTriggerUnit,Player00\n_IsUnitSelected_Category=TC_UNIT\n\nIsUnitAlly=0,1,boolean,unit,player\n_IsUnitAlly_Defaults=GetTriggerUnit,Player00\n_IsUnitAlly_Category=TC_UNIT\n\nIsUnitEnemy=0,1,boolean,unit,player\n_IsUnitEnemy_Defaults=GetTriggerUnit,Player00\n_IsUnitEnemy_Category=TC_UNIT\n\nIsUnitOwnedByPlayer=0,1,boolean,unit,player\n_IsUnitOwnedByPlayer_Defaults=GetTriggerUnit,Player00\n_IsUnitOwnedByPlayer_Category=TC_UNIT\n\nIsUnitInForce=0,1,boolean,unit,force\n_IsUnitInForce_Defaults=GetTriggerUnit,GetPlayersAll\n_IsUnitInForce_Category=TC_UNIT\n\nUnitHasBuffBJ=1,1,boolean,unit,buffcode\n_UnitHasBuffBJ_Defaults=GetTriggerUnit,_\n_UnitHasBuffBJ_Category=TC_UNIT\n\nIsUnitGroupEmptyBJ=0,1,boolean,group\n_IsUnitGroupEmptyBJ_Defaults=_\n_IsUnitGroupEmptyBJ_Category=TC_UNITGROUP\n\nIsUnitGroupInRectBJ=0,1,boolean,group,rect\n_IsUnitGroupInRectBJ_Defaults=_\n_IsUnitGroupInRectBJ_Category=TC_UNITGROUP\n\nIsUnitGroupDeadBJ=0,1,boolean,group\n_IsUnitGroupDeadBJ_Defaults=_\n_IsUnitGroupDeadBJ_Category=TC_UNITGROUP\n\nIsMultiboardDisplayed=1,0,boolean,multiboard\n_IsMultiboardDisplayed_Defaults=GetLastCreatedMultiboard\n_IsMultiboardDisplayed_Category=TC_MULTIBOARD\n\nIsMultiboardMinimized=1,0,boolean,multiboard\n_IsMultiboardMinimized_Defaults=GetLastCreatedMultiboard\n_IsMultiboardMinimized_Category=TC_MULTIBOARD\n\nIsPointBlighted=1,1,boolean,real,real\n_IsPointBlighted_Defaults=0,0\n_IsPointBlighted_Category=TC_ENVIRONMENT\n\nIsPointBlightedBJ=1,1,boolean,location\n_IsPointBlightedBJ_Defaults=_\n_IsPointBlightedBJ_Category=TC_ENVIRONMENT\n\nIsTerrainPathable=1,1,boolean,real,real,pathingtype\n_IsTerrainPathable_Defaults=0,0,PathingTypeWalkability\n_IsTerrainPathable_Category=TC_ENVIRONMENT\n\nIsTerrainPathableBJ=1,1,boolean,location,pathingtype\n_IsTerrainPathableBJ_Defaults=_,PathingTypeWalkability\n_IsTerrainPathableBJ_Category=TC_ENVIRONMENT\n\nIsFogEnabled=0,1,boolean\n_IsFogEnabled_Defaults=\n_IsFogEnabled_Category=TC_VISIBILITY\n\nIsFogMaskEnabled=0,1,boolean\n_IsFogMaskEnabled_Defaults=\n_IsFogMaskEnabled_Category=TC_VISIBILITY\n\nIsUnitVisible=0,1,boolean,unit,player\n_IsUnitVisible_Defaults=GetTriggerUnit,Player00\n_IsUnitVisible_Category=TC_VISIBILITY\n\nIsUnitInvisible=0,1,boolean,unit,player\n_IsUnitInvisible_Defaults=GetTriggerUnit,Player00\n_IsUnitInvisible_Category=TC_VISIBILITY\n\nIsUnitFogged=0,1,boolean,unit,player\n_IsUnitFogged_Defaults=GetTriggerUnit,Player00\n_IsUnitFogged_Category=TC_VISIBILITY\n\nIsUnitMasked=0,1,boolean,unit,player\n_IsUnitMasked_Defaults=GetTriggerUnit,Player00\n_IsUnitMasked_Category=TC_VISIBILITY\n\nIsLocationVisibleToPlayer=0,1,boolean,location,player\n_IsLocationVisibleToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationVisibleToPlayer_Category=TC_VISIBILITY\n\nIsVisibleToPlayer=0,1,boolean,real,real,player\n_IsVisibleToPlayer_Defaults=_,_,Player00\n_IsVisibleToPlayer_Category=TC_VISIBILITY\n\nIsLocationFoggedToPlayer=0,1,boolean,location,player\n_IsLocationFoggedToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationFoggedToPlayer_Category=TC_VISIBILITY\n\nIsFoggedToPlayer=0,1,boolean,real,real,player\n_IsFoggedToPlayer_Defaults=_,_,Player00\n_IsFoggedToPlayer_Category=TC_VISIBILITY\n\nIsLocationMaskedToPlayer=0,1,boolean,location,player\n_IsLocationMaskedToPlayer_Defaults=GetRectCenter,Player00\n_IsLocationMaskedToPlayer_Category=TC_VISIBILITY\n\nIsMaskedToPlayer=0,1,boolean,real,real,player\n_IsMaskedToPlayer_Defaults=_,_,Player00\n_IsMaskedToPlayer_Category=TC_VISIBILITY\n\nIsDestructableAliveBJ=0,1,boolean,destructable\n_IsDestructableAliveBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableAliveBJ_Category=TC_DESTRUCT\n\nIsDestructableDeadBJ=0,1,boolean,destructable\n_IsDestructableDeadBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableDeadBJ_Category=TC_DESTRUCT\n\nIsDestructableInvulnerableBJ=0,1,boolean,destructable\n_IsDestructableInvulnerableBJ_Defaults=GetLastCreatedDestructable\n_IsDestructableInvulnerableBJ_Category=TC_DESTRUCT\n_IsDestructableInvulnerableBJ_ScriptName=IsDestructableInvulnerable\n\nLeaderboardHasPlayerItemBJ=0,1,boolean,leaderboard,player\n_LeaderboardHasPlayerItemBJ_Defaults=GetLastCreatedLeaderboard,Player00\n_LeaderboardHasPlayerItemBJ_Category=TC_LEADERBOARD\n_LeaderboardHasPlayerItemBJ_ScriptName=LeaderboardHasPlayerItem\n\nIsPointInRegion=0,1,boolean,region,real,real\n_IsPointInRegion_Defaults=_,0,0\n_IsPointInRegion_Category=TC_REGION\n\nIsLocationInRegion=0,1,boolean,region,location\n_IsLocationInRegion_Defaults=_,_\n_IsLocationInRegion_Category=TC_REGION\n\nRectContainsLoc=0,1,boolean,rect,location\n_RectContainsLoc_Defaults=GetPlayableMapRect,_\n_RectContainsLoc_Category=TC_RECT\n\nIsQuestItemCompleted=0,1,boolean,questitem\n_IsQuestItemCompleted_Defaults=GetLastCreatedQuestItemBJ\n_IsQuestItemCompleted_Category=TC_QUEST\n\nIsQuestEnabled=0,1,boolean,quest\n_IsQuestEnabled_Defaults=GetLastCreatedQuestBJ\n_IsQuestEnabled_Category=TC_QUEST\n\nIsQuestCompleted=0,1,boolean,quest\n_IsQuestCompleted_Defaults=GetLastCreatedQuestBJ\n_IsQuestCompleted_Category=TC_QUEST\n\nIsQuestFailed=0,1,boolean,quest\n_IsQuestFailed_Defaults=GetLastCreatedQuestBJ\n_IsQuestFailed_Category=TC_QUEST\n\nIsQuestDiscovered=0,1,boolean,quest\n_IsQuestDiscovered_Defaults=GetLastCreatedQuestBJ\n_IsQuestDiscovered_Category=TC_QUEST\n\nIsQuestRequired=0,1,boolean,quest\n_IsQuestRequired_Defaults=GetLastCreatedQuestBJ\n_IsQuestRequired_Category=TC_QUEST\n\nIsPlayerFlagSetBJ=0,1,boolean,playerflag,player\n_IsPlayerFlagSetBJ_Defaults=PlayerFlagGivesBounty,PlayerNA\n_IsPlayerFlagSetBJ_Category=TC_PLAYER\n\nIsPlayerAlly=0,1,boolean,player,player\n_IsPlayerAlly_Defaults=GetTriggerPlayer,Player00\n_IsPlayerAlly_Category=TC_PLAYER\n\nIsPlayerEnemy=0,1,boolean,player,player\n_IsPlayerEnemy_Defaults=GetTriggerPlayer,Player00\n_IsPlayerEnemy_Category=TC_PLAYER\n\nIsPlayerObserver=0,1,boolean,player\n_IsPlayerObserver_Defaults=GetTriggerPlayer\n_IsPlayerObserver_Category=TC_PLAYER\n\nIsPlayerRacePrefSet=0,1,boolean,player,racepreference\n_IsPlayerRacePrefSet_Defaults=GetTriggerPlayer,RacePrefRandom\n_IsPlayerRacePrefSet_Category=TC_PLAYER\n\nGetPlayerAlliance=0,1,boolean,player,player,alliancetype\n_GetPlayerAlliance_Defaults=GetTriggerPlayer,Player00,AllianceTypePassive\n_GetPlayerAlliance_Category=TC_PLAYER\n\nIsPlayerInForce=0,1,boolean,player,force\n_IsPlayerInForce_Defaults=Player00,GetPlayersAll\n_IsPlayerInForce_Category=TC_PLAYER\n\nCheckItemStatus=1,0,boolean,item,itemstatus\n_CheckItemStatus_Defaults=GetLastCreatedItem,ItemStatusHidden\n_CheckItemStatus_Category=TC_ITEM\n\nCheckItemcodeStatus=1,0,boolean,itemcode,itemcodestatus\n_CheckItemcodeStatus_Defaults=GetItemTypeId,ItemcodeStatusPowerup\n_CheckItemcodeStatus_Category=TC_ITEM\n\nIsItemVisible=1,0,boolean,item\n_IsItemVisible_Defaults=bj_lastCreatedItem\n_IsItemVisible_Category=TC_ITEM\n\nIsItemHiddenBJ=1,0,boolean,item\n_IsItemHiddenBJ_Defaults=GetLastCreatedItem\n_IsItemHiddenBJ_Category=TC_ITEM\n\nIsItemOwned=1,0,boolean,item\n_IsItemOwned_Defaults=_\n_IsItemOwned_Category=TC_ITEM\n\nIsItemPowerup=1,0,boolean,item\n_IsItemPowerup_Defaults=bj_lastCreatedItem\n_IsItemPowerup_Category=TC_ITEM\n\nIsItemSellable=1,0,boolean,item\n_IsItemSellable_Defaults=bj_lastCreatedItem\n_IsItemSellable_Category=TC_ITEM\n\nIsItemPawnable=1,0,boolean,item\n_IsItemPawnable_Defaults=bj_lastCreatedItem\n_IsItemPawnable_Category=TC_ITEM\n\nRectContainsItem=1,1,boolean,item,rect\n_RectContainsItem_Defaults=GetLastCreatedItem,_\n_RectContainsItem_Category=TC_ITEM\n\nIsItemInvulnerable=0,1,boolean,item\n_IsItemInvulnerable_Defaults=GetLastCreatedItem\n_IsItemInvulnerable_Category=TC_ITEM\n\nUnitHasItem=0,1,boolean,unit,item\n_UnitHasItem_Defaults=GetTriggerUnit,GetLastCreatedItem\n_UnitHasItem_Category=TC_HERO\n\nUnitHasItemOfTypeBJ=0,1,boolean,unit,itemcode\n_UnitHasItemOfTypeBJ_Defaults=GetTriggerUnit,texp\n_UnitHasItemOfTypeBJ_Category=TC_HERO\n\nIsSuspendedXP=0,1,boolean,unit\n_IsSuspendedXP_Defaults=GetTriggerUnit\n_IsSuspendedXP_Category=TC_HERO\n\nIsMapFlagSet=0,1,boolean,mapflag\n_IsMapFlagSet_Defaults=MapFlagUseHandicaps\n_IsMapFlagSet_Category=TC_GAME\n\nIsCustomCampaignButtonVisibile=1,0,boolean,integer\n_IsCustomCampaignButtonVisibile_Defaults=1\n_IsCustomCampaignButtonVisibile_Limits=1,_\n_IsCustomCampaignButtonVisibile_Category=TC_GAME\n\nGetCreepCampFilterState=1,1,boolean\n_GetCreepCampFilterState_Category=TC_GAME\n\nSaveGameExists=1,0,boolean,anyfile\n_SaveGameExists_Defaults=_\n_SaveGameExists_Category=TC_GAME\n\nIsNoVictoryCheat=1,0,boolean\n_IsNoVictoryCheat_Category=TC_GAME\n\nIsNoDefeatCheat=1,0,boolean\n_IsNoDefeatCheat_Category=TC_GAME\n\nGetStoredBoolean=0,1,boolean,gamecache,string,string\n_GetStoredBoolean_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_\n_GetStoredBoolean_Category=TC_GAMECACHE\n\nHaveStoredValue=1,0,boolean,string,cachevaluetype,string,gamecache\n_HaveStoredValue_Defaults=_,CacheValueTypeUnit,\"Category\",GetLastCreatedGameCacheBJ\n_HaveStoredValue_Category=TC_GAMECACHE\n\nWaygateIsActiveBJ=0,1,boolean,unit\n_WaygateIsActiveBJ_Defaults=_\n_WaygateIsActiveBJ_Category=TC_NEUTRALBUILDING\n_WaygateIsActiveBJ_ScriptName=WaygateIsActive\n\nLoadBooleanBJ=0,1,boolean,integer,integer,hashtable\n_LoadBooleanBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadBooleanBJ_Category=TC_HASHTABLE\n\nLoadBoolean=0,1,boolean,hashtable,integer,integer\n_LoadBoolean_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadBoolean_Category=TC_HASHTABLE\n\nHaveSavedValue=1,0,boolean,integer,hashtablevaluetype,integer,hashtable\n_HaveSavedValue_Defaults=_,HashtableValueTypeHandle,_,GetLastCreatedHashtableBJ\n_HaveSavedValue_Category=TC_HASHTABLE\n\n\n// returns integer\nOperatorInt=0,1,integer,integer,ArithmeticOperator,integer\n_OperatorInt_Defaults=_,OperatorAdd,1\n_OperatorInt_Category=TC_ARITHMETIC\n_OperatorInt_UseWithAI=1\n\nYDWEGetLocalVariableInteger=0,1,integer,string\n_YDWEGetLocalVariableInteger_Category=TC_YDLC\n\nYDWEGetLocalVariableIntegerArray=0,1,integer,string,integer\n_YDWEGetLocalVariableIntegerArray_Defaults=_,1\n_YDWEGetLocalVariableIntegerArray_Limits=_,_,0,_\n_YDWEGetLocalVariableIntegerArray_Category=TC_YDLC\n\nYDWERecordGetI=0,1,integer,player,string\n_YDWERecordGetI_Defaults=Player00,EverguoIsHandsome\n_YDWERecordGetI_Category=TC_YDSL\n\nYDWE_PreloadSL_Get=0,1,integer,player,string,integer\n_YDWE_PreloadSL_Get_Defaults=Player00,_,_\n_YDWE_PreloadSL_Get_Limits=_,_,_,_,1,500\n_YDWE_PreloadSL_Get_Category=TC_YDSL\n\nGetForLoopIndexA=0,1,integer\n_GetForLoopIndexA_Defaults=\n_GetForLoopIndexA_Category=TC_FORLOOP\n\nGetForLoopIndexB=0,1,integer\n_GetForLoopIndexB_Defaults=\n_GetForLoopIndexB_Category=TC_FORLOOP\n\nStringLength=1,1,integer,string\n_StringLength_Defaults=GetEventPlayerChatString\n_StringLength_Category=TC_NOTHING\n\n =1,1,integer,scriptcode\n_ _Category=TC_NOTHING\n\nR2I=0,1,integer,real\n_R2I_Defaults=GetUnitStateSwap\n_R2I_Category=TC_CONVERSION\n\nS2I=0,1,integer,string\n_S2I_Defaults=GetEventPlayerChatString\n_S2I_Category=TC_CONVERSION\n\n//最萌小汐\nprocess.Create=0,1,integer,unit,string,integer,boolean\n_process.Create_Defaults=GetTriggerUnit,\"移动\",100,true\n_process.Create_Category=TC_MU_PROCESS\n\nYDWE_TP_GetExpiredTimerIndex=0,1,integer\n_YDWE_TP_GetExpiredTimerIndex_Category=TC_YDST\n\nYDWE_TP_NewTimerPeriodic=0,1,integer,real,boolean,trigger\n_YDWE_TP_NewTimerPeriodic_Defaults=0.03,true,GetTriggeringTrigger\n_YDWE_TP_NewTimerPeriodic_Limits=0.01,_,_,_,_,_\n_YDWE_TP_NewTimerPeriodic_Category=TC_YDST\n\nYDWEGeneralBounsSystemUnitGetBonus=0,1,integer,unit,bonusType\n_YDWEGeneralBounsSystemUnitGetBonus_Defaults=GetTriggerUnit,bonusTypeA\n_YDWEGeneralBounsSystemUnitGetBonus_Category=TC_YDST\n\nYDWEGetGameCurrentTime=0,1,integer\n_YDWEGetGameCurrentTime_Category=TC_YDFC\n\nYDWETimerSystemGetRunIndex=0,1,integer\n_YDWETimerSystemGetRunIndex_Category=TC_YDFC\n\nYDWEGetUnitItemSoftId=0,1,integer,unit,item\n_YDWEGetUnitItemSoftId_Defaults=GetTriggerUnit,GetManipulatedItem\n_YDWEGetUnitItemSoftId_Category=TC_YDFC\n\nYDWEConverUnitcodeToInt=0,1,integer,unitcode\n_YDWEConverUnitcodeToInt_Category=TC_YDFC\n\nYDWEConverItemcodeToInt=0,1,integer,itemcode\n_YDWEConverItemcodeToInt_Category=TC_YDFC\n\nYDWEConverAbilcodeToInt=0,1,integer,abilcode\n_YDWEConverAbilcodeToInt_Category=TC_YDFC\n\nYDWEConverOrdercodeToInt=0,1,integer,ordercode\n_YDWEConverOrdercodeToInt_Category=TC_YDFC\n\nYDWEI2UnitId=0,1,unitcode,integer\n_YDWEI2UnitId_Defaults=_\n_YDWEI2UnitId_Category=TC_YDFC\n\nYDWEI2ItemId=0,1,itemcode,integer\n_YDWEI2ItemId_Defaults=_\n_YDWEI2ItemId_Category=TC_YDFC\n\nYDWES2Id=0,1,integer,string\n_YDWES2Id_Defaults=spsh\n_YDWES2Id_Category=TC_YDFC\n\nYDWES2UnitId=0,1,unitcode,string\n_YDWES2UnitId_Defaults=hfoo\n_YDWES2UnitId_Category=TC_YDFC\n\nYDWES2ItemId=0,1,itemcode,string\n_YDWES2ItemId_Defaults=spsh\n_YDWES2ItemId_Category=TC_YDFC\n\nYDWEGetUnitGoldCost=0,1,integer,unitcode\n_YDWEGetUnitGoldCost_Defaults=hfoo\n_YDWEGetUnitGoldCost_Category=TC_YDFC\n\nYDWEGetUnitWoodCost=0,1,integer,unitcode\n_YDWEGetUnitWoodCost_Defaults=hfoo\n_YDWEGetUnitWoodCost_Category=TC_YDFC\n\nYDWEGetUnitBuildTime=0,1,integer,unitcode\n_YDWEGetUnitBuildTime_Defaults=hfoo\n_YDWEGetUnitBuildTime_Category=TC_YDFC\n\nYDWEGetUnitFoodUsed=0,1,integer,unit\n_YDWEGetUnitFoodUsed_Defaults=GetTriggerUnit\n_YDWEGetUnitFoodUsed_Category=TC_YDFC\n\nYDWEGetUnitFoodMade=0,1,integer,unit\n_YDWEGetUnitFoodMade_Defaults=GetTriggerUnit\n_YDWEGetUnitFoodMade_Category=TC_YDFC\n\nYDWEGetIntegerByInteger=0,1,integer,integer,integer\n_YDWEGetIntegerByInteger_Category=TC_YDLD\n\nYDWEGetIntegerByString=0,1,integer,string,string\n_YDWEGetIntegerByString_Category=TC_YDLD\n\nGetTriggerEvalCount=0,1,integer,trigger\n_GetTriggerEvalCount_Defaults=GetTriggeringTrigger\n_GetTriggerEvalCount_Category=TC_TRIGGER\n\nGetTriggerExecCount=0,1,integer,trigger\n_GetTriggerExecCount_Defaults=GetTriggeringTrigger\n_GetTriggerExecCount_Category=TC_TRIGGER\n\nQueuedTriggerCountBJ=0,1,integer\n_QueuedTriggerCountBJ_Defaults=\n_QueuedTriggerCountBJ_Category=TC_TRIGGER\n\nCountUnitsInGroup=0,1,integer,group\n_CountUnitsInGroup_Defaults=GetUnitsInRectAll\n_CountUnitsInGroup_Category=TC_UNIT\n\nCountLivingPlayerUnitsOfTypeId=1,1,integer,unitcode,player\n_CountLivingPlayerUnitsOfTypeId_Defaults=hfoo,Player00\n_CountLivingPlayerUnitsOfTypeId_Category=TC_UNIT\n\nGetUnitFoodUsed=0,1,integer,unit\n_GetUnitFoodUsed_Defaults=GetTriggerUnit\n_GetUnitFoodUsed_Category=TC_UNIT\n\nGetUnitFoodMade=0,1,integer,unit\n_GetUnitFoodMade_Defaults=GetTriggerUnit\n_GetUnitFoodMade_Category=TC_UNIT\n\nGetFoodUsed=1,1,integer,unitcode\n_GetFoodUsed_Defaults=hfoo\n_GetFoodUsed_Category=TC_UNIT\n\nGetFoodMade=0,1,integer,unitcode\n_GetFoodMade_Defaults=hfoo\n_GetFoodMade_Category=TC_UNIT\n\nGetUnitPointValue=0,1,integer,unit\n_GetUnitPointValue_Defaults=GetTriggerUnit\n_GetUnitPointValue_Category=TC_UNIT\n\nGetUnitPointValueByType=0,1,integer,unitcode\n_GetUnitPointValueByType_Defaults=hfoo\n_GetUnitPointValueByType_Category=TC_UNIT\n\nGetUnitUserData=1,1,integer,unit\n_GetUnitUserData_Defaults=_\n_GetUnitUserData_Category=TC_UNIT\n\nGetUnitLevel=1,1,integer,unit\n_GetUnitLevel_Defaults=GetTriggerUnit\n_GetUnitLevel_Category=TC_UNIT\n\nGetUnitAbilityLevel=1,1,integer,unit,abilcode\n_GetUnitAbilityLevel_Defaults=GetTriggerUnit,GetSpellAbilityId\n_GetUnitAbilityLevel_Category=TC_UNIT\n\nGetUnitAbilityLevelSwapped=1,1,integer,abilcode,unit\n_GetUnitAbilityLevelSwapped_Defaults=GetSpellAbilityId,GetTriggerUnit\n_GetUnitAbilityLevelSwapped_Category=TC_UNIT\n\nItem.GetUnitItemCountByType=1,1,integer,unit,itemcode\n_Item.GetUnitItemCountByType_Defaults=GetTriggerUnit,ches\n_Item.GetUnitItemCountByType_Category=TC_UNIT\n\nUnitInventoryCount=1,1,integer,unit\n_UnitInventoryCount_Defaults=GetTriggerUnit\n_UnitInventoryCount_Category=TC_UNIT\n\nUnitInventorySizeBJ=1,1,integer,unit\n_UnitInventorySizeBJ_Defaults=GetTriggerUnit\n_UnitInventorySizeBJ_Category=TC_UNIT\n_UnitInventorySizeBJ_ScriptName=UnitInventorySize\n\nUnitCountBuffsEx=1,1,integer,unit,includeoption,includeoption,includeoptionnot,includeoptionnot,includeoption,includeoption,includeoptionnot\n_UnitCountBuffsEx_Defaults=GetTriggerUnit,InclusionInclude,InclusionInclude,InclusionIncludeNot,InclusionIncludeNot,InclusionInclude,InclusionInclude,InclusionIncludeNot\n_UnitCountBuffsEx_Category=TC_UNIT\n\nUnitCountBuffsExBJ=1,1,integer,buffpolarity,buffresist,unit,includeoption,includeoption\n_UnitCountBuffsExBJ_Defaults=BuffPolarityEither,BuffResistEither,GetTriggerUnit,InclusionInclude,InclusionInclude\n_UnitCountBuffsExBJ_Category=TC_UNIT\n\nMultiboardGetRowCount=1,1,integer,multiboard\n_MultiboardGetRowCount_Defaults=GetLastCreatedMultiboard\n_MultiboardGetRowCount_Category=TC_MULTIBOARD\n\nMultiboardGetColumnCount=1,1,integer,multiboard\n_MultiboardGetColumnCount_Defaults=GetLastCreatedMultiboard\n_MultiboardGetColumnCount_Category=TC_MULTIBOARD\n\nGetTerrainCliffLevel=1,1,integer,real,real\n_GetTerrainCliffLevel_Defaults=0,0\n_GetTerrainCliffLevel_Category=TC_ENVIRONMENT\n\nGetTerrainCliffLevelBJ=1,1,integer,location\n_GetTerrainCliffLevelBJ_Category=TC_ENVIRONMENT\n\nGetTerrainVariance=1,1,integer,real,real\n_GetTerrainVariance_Defaults=0,0\n_GetTerrainVariance_Category=TC_ENVIRONMENT\n\nGetTerrainVarianceBJ=1,1,integer,location\n_GetTerrainVarianceBJ_Defaults=GetRectCenter\n_GetTerrainVarianceBJ_Category=TC_ENVIRONMENT\n\nGetElevatorHeight=1,1,integer,destructable\n_GetElevatorHeight_Defaults=_\n_GetElevatorHeight_Category=TC_DESTRUCT\n\nLeaderboardGetPlayerIndexBJ=0,1,integer,player,leaderboard\n_LeaderboardGetPlayerIndexBJ_Defaults=Player00,GetLastCreatedLeaderboard\n_LeaderboardGetPlayerIndexBJ_Category=TC_LEADERBOARD\n\nLeaderboardGetItemCount=0,1,integer,leaderboard\n_LeaderboardGetItemCount_Defaults=GetLastCreatedLeaderboard\n_LeaderboardGetItemCount_Category=TC_LEADERBOARD\n\nGetLearnedSkillLevel=0,1,integer\n_GetLearnedSkillLevel_Defaults=\n_GetLearnedSkillLevel_Category=TC_EVENTRESPONSE\n\nGetRandomInt=0,1,integer,integer,integer\n_GetRandomInt_Defaults=1,10\n_GetRandomInt_Category=TC_MATH\n\nIMinBJ=0,1,integer,integer,integer\n_IMinBJ_Defaults=_,_\n_IMinBJ_Category=TC_MATH\n\nIMaxBJ=0,1,integer,integer,integer\n_IMaxBJ_Defaults=_,_\n_IMaxBJ_Category=TC_MATH\n\nIAbsBJ=0,1,integer,integer\n_IAbsBJ_Defaults=_\n_IAbsBJ_Category=TC_MATH\n\nISignBJ=0,1,integer,integer\n_ISignBJ_Defaults=_\n_ISignBJ_Category=TC_MATH\n\nStringHash=1,1,integer,string\n_StringHash_Defaults=\n_StringHash_Category=TC_MATH\n\nModuloInteger=0,1,integer,integer,integer\n_ModuloInteger_Defaults=_,_\n_ModuloInteger_Category=TC_MATH\n\nGetPlayerState=0,1,integer,player,playerstate\n_GetPlayerState_Defaults=Player00,PlayerStateGold\n_GetPlayerState_Category=TC_PLAYER\n\nGetPlayerTaxRate=1,1,integer,player,player,playerresource\n_GetPlayerTaxRate_Defaults=Player00,Player01,PlayerResourceGold\n_GetPlayerTaxRate_Category=TC_PLAYER\n\nGetPlayerTaxRateBJ=1,1,integer,playerresource,player,player\n_GetPlayerTaxRateBJ_Defaults=PlayerResourceGold,Player00,Player01\n_GetPlayerTaxRateBJ_Category=TC_PLAYER\n\nGetPlayerScore=1,1,integer,player,playerscore\n_GetPlayerScore_Defaults=Player00,PlayerScoreTotal\n_GetPlayerScore_Category=TC_PLAYER\n\nGetConvertedPlayerId=0,1,integer,player\n_GetConvertedPlayerId_Defaults=GetTriggerPlayer\n_GetConvertedPlayerId_Category=TC_PLAYER\n\nGetPlayerId=0,1,integer,player\n_GetPlayerId_Defaults=GetTriggerPlayer\n_GetPlayerId_Category=TC_PLAYER\n\nGetPlayerStructureCount=0,1,integer,player,includeoption\n_GetPlayerStructureCount_Defaults=Player00,InclusionExclude\n_GetPlayerStructureCount_Category=TC_PLAYER\n\nGetPlayerUnitCount=0,1,integer,player,includeoption\n_GetPlayerUnitCount_Defaults=Player00,InclusionExclude\n_GetPlayerUnitCount_Category=TC_PLAYER\n\nGetPlayerTechCountSimple=0,1,integer,techcode,player\n_GetPlayerTechCountSimple_Defaults=_,Player00\n_GetPlayerTechCountSimple_Category=TC_PLAYER\n\nGetPlayerTechMaxAllowedSwap=0,1,integer,techcode,player\n_GetPlayerTechMaxAllowedSwap_Defaults=_,Player00\n_GetPlayerTechMaxAllowedSwap_Category=TC_PLAYER\n\nGetPlayerTeam=0,1,integer,player\n_GetPlayerTeam_Defaults=Player00\n_GetPlayerTeam_Category=TC_PLAYER\n\nCountPlayersInForceBJ=0,1,integer,force\n_CountPlayersInForceBJ_Defaults=GetPlayersByMapControl\n_CountPlayersInForceBJ_Category=TC_PLAYER\n\nGetInventoryIndexOfItemTypeBJ=0,1,integer,unit,itemcode\n_GetInventoryIndexOfItemTypeBJ_Defaults=GetTriggerUnit,texp\n_GetInventoryIndexOfItemTypeBJ_Category=TC_ITEM\n\nGetItemLevel=1,1,integer,item\n_GetItemLevel_Defaults=GetLastCreatedItem\n_GetItemLevel_Category=TC_ITEM\n\nGetItemCharges=1,1,integer,item\n_GetItemCharges_Defaults=GetLastCreatedItem\n_GetItemCharges_Category=TC_ITEM\n\nGetItemUserData=1,1,integer,item\n_GetItemUserData_Defaults=_\n_GetItemUserData_Category=TC_ITEM\n\nGetHeroLevel=0,1,integer,unit\n_GetHeroLevel_Defaults=GetTriggerUnit\n_GetHeroLevel_Category=TC_HERO\n\nGetHeroXP=0,1,integer,unit\n_GetHeroXP_Defaults=GetTriggerUnit\n_GetHeroXP_Category=TC_HERO\n\nGetHeroStr=1,1,integer,unit,includeoption\n_GetHeroStr_Defaults=GetTriggerUnit,InclusionInclude\n_GetHeroStr_Category=TC_HERO\n\nGetHeroAgi=1,1,integer,unit,includeoption\n_GetHeroAgi_Defaults=GetTriggerUnit,InclusionInclude\n_GetHeroAgi_Category=TC_HERO\n\nGetHeroInt=1,1,integer,unit,includeoption\n_GetHeroInt_Defaults=GetTriggerUnit,InclusionInclude\n_GetHeroInt_Category=TC_HERO\n\nGetHeroStatBJ=1,1,integer,herostat,unit,includeoption\n_GetHeroStatBJ_Defaults=HeroStatStr,GetTriggerUnit,InclusionInclude\n_GetHeroStatBJ_Category=TC_HERO\n\nGetHeroSkillPoints=1,1,integer,unit\n_GetHeroSkillPoints_Defaults=_\n_GetHeroSkillPoints_Category=TC_HERO\n\nGetPlayers=0,1,integer\n_GetPlayers_Defaults=\n_GetPlayers_Category=TC_GAME\n\nGetTeams=0,1,integer\n_GetTeams_Defaults=\n_GetTeams_Category=TC_GAME\n\nGetAllyColorFilterState=1,1,integer\n_GetAllyColorFilterState_Defaults=\n_GetAllyColorFilterState_Category=TC_GAME\n\nGetTournamentFinishNowRule=1,0,integer\n_GetTournamentFinishNowRule_Defaults=\n_GetTournamentFinishNowRule_Category=TC_GAME\n\nGetTournamentScore=1,0,integer,player\n_GetTournamentScore_Defaults=Player00\n_GetTournamentScore_Category=TC_GAME\n\nGetStoredInteger=0,1,integer,gamecache,string,string\n_GetStoredInteger_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_,\n_GetStoredInteger_Category=TC_GAMECACHE\n\nGetResourceAmount=0,1,integer,unit\n_GetResourceAmount_Defaults=_\n_GetResourceAmount_Category=TC_NEUTRALBUILDING\n\nGetHandleIdBJ=1,1,integer,handle\n_GetHandleIdBJ_Defaults=\n_GetHandleIdBJ_Category=TC_HASHTABLE\n\nGetHandleId=1,1,integer,handle\n_GetHandleId_Defaults=_\n_GetHandleId_Category=TC_HASHTABLE\n\nStringHashBJ=1,1,integer,string\n_StringHashBJ_Defaults=\n_StringHashBJ_Category=TC_HASHTABLE\n\nLoadIntegerBJ=0,1,integer,integer,integer,hashtable\n_LoadIntegerBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadIntegerBJ_Category=TC_HASHTABLE\n\nLoadInteger=0,1,integer,hashtable,integer,integer\n_LoadInteger_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadInteger_Category=TC_HASHTABLE\n\n// returns real\nOperatorReal=0,1,real,real,ArithmeticOperator,real\n_OperatorReal_Defaults=1,OperatorAdd,1\n_OperatorReal_Category=TC_ARITHMETIC\n\n   =0,1,real,scriptcode\n_   _Defaults=_\n_   _Category=TC_NOTHING\n\n\n//最萌小汐\nmath.L2L=0,1,real,location,location,DisOrAng,removeWhichLocation\n_math.L2L_Defaults=_,_,DisOrAngA,removeWhichLocationB\n_math.L2L_Category=TC_MU_MATH\n\nmath.U2L=0,1,real,unit,location,DisOrAng,boolean\n_math.U2L_Defaults=GetTriggerUnit,GetSpellTargetLoc,DisOrAngA,true\n_math.U2L_Category=TC_MU_MATH\n\nmath.Angle=0,1,real,real,real\n_math.Angle_Defaults=0,180\n_math.Angle_Category=TC_MU_MATH\n\nsys.getTime=0,1,real\n_sys.getTime_Category=TC_MU_BASE\n\nGetLocationX=0,1,real,location\n_GetLocationX_Category=TC_NOTHING\n\nGetLocationY=0,1,real,location\n_GetLocationY_Category=TC_NOTHING\n\nGetLocationZ=0,1,real,location\n_GetLocationZ_Category=TC_NOTHING\n\nI2R=0,1,real,integer\n_I2R_Defaults=GetUnitPointValueByType\n_I2R_Category=TC_CONVERSION\n\nS2R=0,1,real,string\n_S2R_Defaults=GetEventPlayerChatString\n_S2R_Category=TC_CONVERSION\n\nDeg2Rad=0,1,real,real\n_Deg2Rad_Defaults=0\n_Deg2Rad_Category=TC_CONVERSION\n\nRad2Deg=0,1,real,real\n_Rad2Deg_Defaults=0\n_Rad2Deg_Category=TC_CONVERSION\n\nYDWEDeg2R=0,1,real,real\n_YDWEDeg2R_Category=TC_CONVERSION\n\nYDWERad2R=0,1,real,real\n_YDWERad2R_Category=TC_CONVERSION\n\nYDWER2Deg=0,1,real,real\n_YDWER2Deg_Category=TC_CONVERSION\n\nYDWER2Rad=0,1,real,real\n_YDWER2Rad_Category=TC_CONVERSION\n\nYDWEGetLocalVariableReal=0,1,real,string\n_YDWEGetLocalVariableReal_Category=TC_YDLC\n\nYDWEGetLocalVariableRealArray=0,1,real,string,integer\n_YDWEGetLocalVariableRealArray_Defaults=_,1\n_YDWEGetLocalVariableRealArray_Limits=_,_,0,_\n_YDWEGetLocalVariableRealArray_Category=TC_YDLC\n\nYDWEGetRealByInteger=0,1,real,integer,integer\n_YDWEGetRealByInteger_Limits=0,_,0,_\n_YDWEGetRealByInteger_Category=TC_YDLD\n\nYDWEGetRealByString=0,1,real,string,string\n_YDWEGetRealByString_Category=TC_YDLD\n\nYDWECoordinateX=0,1,real,real\n_YDWECoordinateX_Defaults=_\n_YDWECoordinateX_Category=TC_YDFC\n\nYDWECoordinateY=0,1,real,real\n_YDWECoordinateY_Defaults=_\n_YDWECoordinateY_Category=TC_YDFC\n\nYDWEDistanceBetweenUnits=0,1,real,unit,unit\n_YDWEDistanceBetweenUnits_Defaults=GetTriggerUnit,GetLastCreatedUnit\n_YDWEDistanceBetweenUnits_Category=TC_YDFC\n\nYDWEAngleBetweenUnits=0,1,real,unit,unit\n_YDWEAngleBetweenUnits_Defaults=GetTriggerUnit,GetLastCreatedUnit\n_YDWEAngleBetweenUnits_Category=TC_YDFC\n\nYDWEGetUnitArmor=0,1,real,unit,abilcode\n_YDWEGetUnitArmor_Defaults=GetTriggerUnit,_\n_YDWEGetUnitArmor_Category=TC_YDFC\n\nYDWE_TP_GetElapsedTime=0,1,real,integer\n_YDWE_TP_GetElapsedTime_Defaults=_\n_YDWE_TP_GetElapsedTime_Category=TC_YDST\n\nYDWE_TP_GetRemainingTime=0,1,real,integer\n_YDWE_TP_GetRemainingTime_Defaults=_\n_YDWE_TP_GetRemainingTime_Category=TC_YDST\n\nYDWE_TP_GetTimeout=0,1,real,integer\n_YDWE_TP_GetTimeout_Defaults=_\n_YDWE_TP_GetTimeout_Category=TC_YDST\n\nWaygateGetDestinationX=0,1,real,unit\n_WaygateGetDestinationX_Defaults=GetTriggerUnit\n_WaygateGetDestinationX_Category=TC_NEUTRALBUILDING\n\nWaygateGetDestinationY=0,1,real,unit\n_WaygateGetDestinationY_Defaults=GetTriggerUnit\n_WaygateGetDestinationY_Category=TC_NEUTRALBUILDING\n\nGetUnitState=0,1,real,unit,unitstate\n_GetUnitState_Defaults=GetTriggerUnit,UnitStateLife\n_GetUnitState_Category=TC_UNIT\n\nGetUnitStateSwap=0,1,real,unitstate,unit\n_GetUnitStateSwap_Defaults=UnitStateLife,GetTriggerUnit\n_GetUnitStateSwap_Category=TC_UNIT\n\nUnit.GetMaxLife=0,1,real,unit\n_Unit.GetMaxLife_Defaults=GetTriggerUnit\n_Unit.GetMaxLife_Category=TC_UNIT\n\nGetUnitLifePercent=1,1,real,unit\n_GetUnitLifePercent_Defaults=GetTriggerUnit\n_GetUnitLifePercent_Category=TC_UNIT\n\nGetUnitManaPercent=1,1,real,unit\n_GetUnitManaPercent_Defaults=GetTriggerUnit\n_GetUnitManaPercent_Category=TC_UNIT\n\nGetUnitX=0,1,real,unit\n_GetUnitX_Defaults=GetTriggerUnit\n_GetUnitX_Category=TC_UNIT\n\nGetUnitY=0,1,real,unit\n_GetUnitY_Defaults=GetTriggerUnit\n_GetUnitY_Category=TC_UNIT\n\nUnit.GetUnitZ=0,1,real,unit\n_Unit.GetUnitZ_Defaults=GetTriggerUnit\n_Unit.GetUnitZ_Category=TC_UNIT\n\nGetUnitFacing=0,1,real,unit\n_GetUnitFacing_Defaults=GetTriggerUnit\n_GetUnitFacing_Category=TC_UNIT\n\nGetUnitMoveSpeed=0,1,real,unit\n_GetUnitMoveSpeed_Defaults=GetTriggerUnit\n_GetUnitMoveSpeed_Category=TC_UNIT\n\nGetUnitDefaultMoveSpeed=0,1,real,unit\n_GetUnitDefaultMoveSpeed_Defaults=GetTriggerUnit\n_GetUnitDefaultMoveSpeed_Category=TC_UNIT\n\nGetUnitAcquireRange=0,1,real,unit\n_GetUnitAcquireRange_Defaults=GetTriggerUnit\n_GetUnitAcquireRange_Category=TC_UNIT\n\nGetUnitDefaultAcquireRange=0,1,real,unit\n_GetUnitDefaultAcquireRange_Defaults=GetTriggerUnit\n_GetUnitDefaultAcquireRange_Category=TC_UNIT\n\nGetUnitTurnSpeed=0,1,real,unit\n_GetUnitTurnSpeed_Defaults=GetTriggerUnit\n_GetUnitTurnSpeed_Category=TC_UNIT\n\nGetUnitDefaultTurnSpeed=0,1,real,unit\n_GetUnitDefaultTurnSpeed_Defaults=GetTriggerUnit\n_GetUnitDefaultTurnSpeed_Category=TC_UNIT\n\nUnit.GetUnitDefence=0,1,real,unit\n_Unit.GetUnitDefence_Defaults=GetTriggerUnit\n_Unit.GetUnitDefence_Category=TC_UNIT\n\nGetUnitPropWindow=0,1,real,unit\n_GetUnitPropWindow_Defaults=GetTriggerUnit\n_GetUnitPropWindow_Category=TC_UNIT\n\nGetUnitPropWindowBJ=0,1,real,unit\n_GetUnitPropWindowBJ_Defaults=GetTriggerUnit\n_GetUnitPropWindowBJ_Category=TC_UNIT\n\nGetUnitDefaultPropWindowBJ=0,1,real,unit\n_GetUnitDefaultPropWindowBJ_Defaults=GetTriggerUnit\n_GetUnitDefaultPropWindowBJ_Category=TC_UNIT\n_GetUnitDefaultPropWindowBJ_ScriptName=GetUnitDefaultPropWindow\n\nGetUnitFlyHeight=0,1,real,unit\n_GetUnitFlyHeight_Defaults=GetTriggerUnit\n_GetUnitFlyHeight_Category=TC_UNIT\n\nGetUnitDefaultFlyHeight=0,1,real,unit\n_GetUnitDefaultFlyHeight_Defaults=GetTriggerUnit\n_GetUnitDefaultFlyHeight_Category=TC_UNIT\n\nYDWEGetUnitAbilityState=0,0,real,unit,abilcode,AbilityState\n_YDWEGetUnitAbilityState_Defaults=GetTriggerUnit,_,ABILITY_STATE_COOLDOWN\n_YDWEGetUnitAbilityState_Category=TC_UNIT\n\nYDWEGetUnitAbilityDataInteger=0,0,integer,unit,abilcode,integer,AbilityDataInteger\n_YDWEGetUnitAbilityDataInteger_Defaults=GetTriggerUnit,_,1,ABILITY_DATA_COST\n_YDWEGetUnitAbilityDataInteger_Limits=_,_,_,_,1,_,_,_,\n_YDWEGetUnitAbilityDataInteger_Category=TC_UNIT\n\nYDWEGetUnitAbilityDataReal=0,0,real,unit,abilcode,integer,AbilityDataReal\n_YDWEGetUnitAbilityDataReal_Defaults=GetTriggerUnit,_,1,ABILITY_DATA_COOL\n_YDWEGetUnitAbilityDataReal_Limits=_,_,_,_,1,_,_,_,\n_YDWEGetUnitAbilityDataReal_Category=TC_UNIT\n\nYDWEGetUnitAbilityDataString=0,0,string,unit,abilcode,integer,AbilityDataString\n_YDWEGetUnitAbilityDataString_Defaults=GetTriggerUnit,_,1,ABILITY_DATA_TIP\n_YDWEGetUnitAbilityDataString_Limits=_,_,_,_,1,_,_,_,\n_YDWEGetUnitAbilityDataString_Category=TC_UNIT\n\n\n\nYDWEGetObjectPropertyInteger=0,0,integer,objecttype,Null,string\n_YDWEGetObjectPropertyInteger_Defaults=objecttype00_abilcode,AHhb,\"levels\"\n_YDWEGetObjectPropertyInteger_Category=TC_YDBF\n\nYDWEGetObjectPropertyReal=0,0,real,objecttype,Null,string\n_YDWEGetObjectPropertyReal_Defaults=objecttype00_abilcode,AHhb,\"Rng1\"\n_YDWEGetObjectPropertyReal_Category=TC_YDBF\n\nYDWEGetObjectPropertyString=0,0,string,objecttype,Null,string\n_YDWEGetObjectPropertyString_Defaults=objecttype00_abilcode,AHhb,\"Name\"\n_YDWEGetObjectPropertyString_Category=TC_YDBF\n\n\n\nGetLastTransmissionDurationBJ=0,1,real\n_GetLastTransmissionDurationBJ_Defaults=\n_GetLastTransmissionDurationBJ_Category=TC_CINEMATIC\n\nTimerGetElapsed=0,1,real,timer\n_TimerGetElapsed_Defaults=_\n_TimerGetElapsed_Category=TC_TIMER\n\nTimerGetRemaining=0,1,real,timer\n_TimerGetRemaining_Defaults=_\n_TimerGetRemaining_Category=TC_TIMER\n\nTimerGetTimeout=0,1,real,timer\n_TimerGetTimeout_Defaults=_\n_TimerGetTimeout_Category=TC_TIMER\n\nCameraSetupGetField=0,1,real,camerasetup,camerafield\n_CameraSetupGetField_Defaults=_,CameraFieldTargetDistance\n_CameraSetupGetField_Category=TC_CAMERA\n\nCameraSetupGetFieldSwap=0,1,real,camerafield,camerasetup\n_CameraSetupGetFieldSwap_Defaults=CameraFieldTargetDistance,_\n_CameraSetupGetFieldSwap_Category=TC_CAMERA\n\nGetCameraField=0,1,real,camerafield\n_GetCameraField_Defaults=CameraFieldTargetDistance\n_GetCameraField_Category=TC_CAMERA\n\nGetCameraTargetPositionX=0,1,real\n_GetCameraTargetPositionX_Defaults=\n_GetCameraTargetPositionX_Category=TC_CAMERA\n\nGetCameraTargetPositionY=0,1,real\n_GetCameraTargetPositionY_Defaults=\n_GetCameraTargetPositionY_Category=TC_CAMERA\n\nGetCameraTargetPositionZ=0,1,real\n_GetCameraTargetPositionZ_Defaults=\n_GetCameraTargetPositionZ_Category=TC_CAMERA\n\nGetCameraEyePositionX=0,1,real\n_GetCameraEyePositionX_Defaults=\n_GetCameraEyePositionX_Category=TC_CAMERA\n\nGetCameraEyePositionY=0,1,real\n_GetCameraEyePositionY_Defaults=\n_GetCameraEyePositionY_Category=TC_CAMERA\n\nGetCameraEyePositionZ=0,1,real\n_GetCameraEyePositionZ_Defaults=\n_GetCameraEyePositionZ_Category=TC_CAMERA\n\nGetDestructableLife=0,1,real,destructable\n_GetDestructableLife_Defaults=GetLastCreatedDestructable\n_GetDestructableLife_Category=TC_DESTRUCT\n\nGetDestructableMaxLife=0,1,real,destructable\n_GetDestructableMaxLife_Defaults=GetLastCreatedDestructable\n_GetDestructableMaxLife_Category=TC_DESTRUCT\n\nGetDestructableOccluderHeight=1,1,real,destructable\n_GetDestructableOccluderHeight_Defaults=GetLastCreatedDestructable\n_GetDestructableOccluderHeight_Category=TC_DESTRUCT\n\nGetDestructableX=1,1,real,destructable\n_GetDestructableX_Defaults=GetLastCreatedDestructable\n_GetDestructableX_Category=TC_DESTRUCT\n\nGetDestructableY=1,1,real,destructable\n_GetDestructableY_Defaults=GetLastCreatedDestructable\n_GetDestructableY_Category=TC_DESTRUCT\n\nGetWidgetLife=0,1,real,widget\n_GetWidgetLife_Defaults=GetTriggerWidget\n_GetWidgetLife_Category=TC_WIDGET\n\nGetWidgetX=0,1,real,widget\n_GetWidgetX_Defaults=GetTriggerWidget\n_GetWidgetX_Category=TC_WIDGET\n\nGetWidgetY=0,1,real,widget\n_GetWidgetY_Defaults=GetTriggerWidget\n_GetWidgetY_Category=TC_WIDGET\n\nGetRectCenterX=0,1,real,rect\n_GetRectCenterX_Defaults=GetPlayableMapRect\n_GetRectCenterX_Category=TC_RECT\n\nGetRectCenterY=0,1,real,rect\n_GetRectCenterY_Defaults=GetPlayableMapRect\n_GetRectCenterY_Category=TC_RECT\n\nGetRectMinX=0,1,real,rect\n_GetRectMinX_Defaults=GetPlayableMapRect\n_GetRectMinX_Category=TC_RECT\n\nGetRectMinY=0,1,real,rect\n_GetRectMinY_Defaults=GetPlayableMapRect\n_GetRectMinY_Category=TC_RECT\n\nGetRectMaxX=0,1,real,rect\n_GetRectMaxX_Defaults=GetPlayableMapRect\n_GetRectMaxX_Category=TC_RECT\n\nGetRectMaxY=0,1,real,rect\n_GetRectMaxY_Defaults=GetPlayableMapRect\n_GetRectMaxY_Category=TC_RECT\n\nGetRectWidthBJ=0,1,real,rect\n_GetRectWidthBJ_Defaults=_\n_GetRectWidthBJ_Category=TC_RECT\n\nGetRectHeightBJ=0,1,real,rect\n_GetRectHeightBJ_Defaults=_\n_GetRectHeightBJ_Category=TC_RECT\n\nGetLightningColorRBJ=1,0,real,lightning\n_GetLightningColorRBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorRBJ_Category=TC_LIGHTNING\n_GetLightningColorRBJ_ScriptName=GetLightningColorR\n\nGetLightningColorGBJ=1,0,real,lightning\n_GetLightningColorGBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorGBJ_Category=TC_LIGHTNING\n_GetLightningColorGBJ_ScriptName=GetLightningColorG\n\nGetLightningColorBBJ=1,0,real,lightning\n_GetLightningColorBBJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorBBJ_Category=TC_LIGHTNING\n_GetLightningColorBBJ_ScriptName=GetLightningColorB\n\nGetLightningColorABJ=1,0,real,lightning\n_GetLightningColorABJ_Defaults=GetLastCreatedLightningBJ\n_GetLightningColorABJ_Category=TC_LIGHTNING\n_GetLightningColorABJ_ScriptName=GetLightningColorA\n\nGetSoundDurationBJ=0,1,real,sound\n_GetSoundDurationBJ_Defaults=GetLastPlayedSound\n_GetSoundDurationBJ_Category=TC_SOUND\n\nGetSoundFileDurationBJ=0,1,real,musicfile\n_GetSoundFileDurationBJ_Defaults=GetLastPlayedMusic\n_GetSoundFileDurationBJ_Category=TC_SOUND\n\nYDWEIsEventPhysicalDamage=0,1,boolean\n_YDWEIsEventPhysicalDamage_Defaults=\n_YDWEIsEventPhysicalDamage_Category=TC_EVENTRESPONSE\n\nYDWEIsEventAttackDamage=0,1,boolean\n_YDWEIsEventAttackDamage_Defaults=\n_YDWEIsEventAttackDamage_Category=TC_EVENTRESPONSE\n\nYDWEIsEventRangedDamage=0,1,boolean\n_YDWEIsEventRangedDamage_Defaults=\n_YDWEIsEventRangedDamage_Category=TC_EVENTRESPONSE\n\nYDWEIsEventDamageType=0,1,boolean,damagetype\n_YDWEIsEventDamageType_Defaults=DamageTypeNormal\n_YDWEIsEventDamageType_Category=TC_EVENTRESPONSE\n\nYDWEIsEventWeaponType=0,1,boolean,weapontype\n_YDWEIsEventWeaponType_Defaults=WEAPON_TYPE_WHOKNOWS\n_YDWEIsEventWeaponType_Category=TC_EVENTRESPONSE\n\nYDWEIsEventAttackType=0,1,boolean,attacktype\n_YDWEIsEventAttackType_Defaults=AttackTypeNormal\n_YDWEIsEventAttackType_Category=TC_EVENTRESPONSE\n\nGetEventDamage=0,1,real\n_GetEventDamage_Defaults=\n_GetEventDamage_Category=TC_EVENTRESPONSE\n\nEvent.GetCurrentDamage=0,1,real\n_Event.GetCurrentDamage_Category=TC_EVENTRESPONSE\n\nEvent.GetHeal=0,1,real\n_Event.GetHeal_Category=TC_EVENTRESPONSE\n\nEvent.GetCurrentHeal=0,1,real\n_Event.GetCurrentHeal_Category=TC_EVENTRESPONSE\n\nGetOrderPointX=0,1,real\n_GetOrderPointX_Category=TC_EVENTRESPONSE\n\nGetOrderPointY=0,1,real\n_GetOrderPointY_Category=TC_EVENTRESPONSE\n\nGetSpellTargetX=0,1,real\n_GetSpellTargetX_Defaults=\n_GetSpellTargetX_Category=TC_EVENTRESPONSE\n\nGetSpellTargetY=0,1,real\n_GetSpellTargetY_Defaults=\n_GetSpellTargetY_Category=TC_EVENTRESPONSE\n\nGetTournamentFinishSoonTimeRemaining=1,0,real\n_GetTournamentFinishSoonTimeRemaining_Defaults=\n_GetTournamentFinishSoonTimeRemaining_Category=TC_EVENTRESPONSE\n\nOperatorDegreeAdd=0,1,real,real,real\n_OperatorDegreeAdd_Defaults=_,_\n_OperatorDegreeAdd_Category=TC_MATH\n\nOperatorDegreeSubtract=0,1,real,real,real\n_OperatorDegreeSubtract_Defaults=_,_\n_OperatorDegreeSubtract_Category=TC_MATH\n\nOperatorDegreeMultiply=0,1,real,real,real\n_OperatorDegreeMultiply_Defaults=_,_\n_OperatorDegreeMultiply_Category=TC_MATH\n\nOperatorDegreeDivide=0,1,real,real,real\n_OperatorDegreeDivide_Defaults=_,_\n_OperatorDegreeDivide_Category=TC_MATH\n\nOperatorRadianAdd=0,1,real,real,real\n_OperatorRadianAdd_Defaults=_,_\n_OperatorRadianAdd_Category=TC_MATH\n\nOperatorRadianSubtract=0,1,real,real,real\n_OperatorRadianSubtract_Defaults=_,_\n_OperatorRadianSubtract_Category=TC_MATH\n\nOperatorRadianMultiply=0,1,real,real,real\n_OperatorRadianMultiply_Defaults=_,_\n_OperatorRadianMultiply_Category=TC_MATH\n\nOperatorRadianDivide=0,1,real,real,real\n_OperatorRadianDivide_Defaults=_,_\n_OperatorRadianDivide_Category=TC_MATH\n\nGetRandomReal=0,1,real,real,real\n_GetRandomReal_Defaults=0,1\n_GetRandomReal_Category=TC_MATH\n\nGetRandomDirectionDeg=0,1,real\n_GetRandomDirectionDeg_Defaults=\n_GetRandomDirectionDeg_Category=TC_MATH\n\nGetRandomPercentageBJ=0,1,real\n_GetRandomPercentageBJ_Defaults=\n_GetRandomPercentageBJ_Category=TC_MATH\n\nDistanceBetweenPoints=0,1,real,location,location\n_DistanceBetweenPoints_Defaults=_,_\n_DistanceBetweenPoints_Category=TC_MATH\n\nAngleBetweenPoints=0,1,real,location,location\n_AngleBetweenPoints_Defaults=_,_\n_AngleBetweenPoints_Category=TC_MATH\n\nRMinBJ=0,1,real,real,real\n_RMinBJ_Defaults=_,_\n_RMinBJ_Category=TC_MATH\n\nRMaxBJ=0,1,real,real,real\n_RMaxBJ_Defaults=_,_\n_RMaxBJ_Category=TC_MATH\n\nRAbsBJ=0,1,real,real\n_RAbsBJ_Defaults=_\n_RAbsBJ_Category=TC_MATH\n\nRSignBJ=0,1,real,real\n_RSignBJ_Defaults=_\n_RSignBJ_Category=TC_MATH\n\nModuloReal=0,1,real,real,real\n_ModuloReal_Defaults=_,_\n_ModuloReal_Category=TC_MATH\n\nPow=0,1,real,real,real\n_Pow_Defaults=_,_\n_Pow_Category=TC_MATH\n\nSquareRoot=0,1,real,real\n_SquareRoot_Defaults=_\n_SquareRoot_Limits=0,_\n_SquareRoot_Category=TC_MATH\n\nSinBJ=0,1,real,real\n_SinBJ_Defaults=GetUnitFacing\n_SinBJ_Category=TC_MATH\n\nCosBJ=0,1,real,real\n_CosBJ_Defaults=GetUnitFacing\n_CosBJ_Category=TC_MATH\n\nTanBJ=0,1,real,real\n_TanBJ_Defaults=GetUnitFacing\n_TanBJ_Category=TC_MATH\n\nAsinBJ=0,1,real,real\n_AsinBJ_Defaults=_\n_AsinBJ_Limits=-1,1\n_AsinBJ_Category=TC_MATH\n\nAcosBJ=0,1,real,real\n_AcosBJ_Defaults=_\n_AcosBJ_Limits=-1,1\n_AcosBJ_Category=TC_MATH\n\nAtanBJ=0,1,real,real\n_AtanBJ_Defaults=_\n_AtanBJ_Category=TC_MATH\n\nAtan2BJ=0,1,real,real,real\n_Atan2BJ_Defaults=_,_\n_Atan2BJ_Category=TC_MATH\n\nSin=0,1,real,real\n_Sin_Defaults=bj_PI\n_Sin_Category=TC_MATH\n\nCos=0,1,real,real\n_Cos_Defaults=bj_PI\n_Cos_Category=TC_MATH\n\nTan=0,1,real,real\n_Tan_Defaults=bj_PI\n_Tan_Category=TC_MATH\n\nAsin=0,1,real,real\n_Asin_Defaults=0\n_Asin_Limits=-1,1\n_Asin_Category=TC_MATH\n\nAcos=0,1,real,real\n_Acos_Defaults=0\n_Acos_Limits=-1,1\n_Acos_Category=TC_MATH\n\nAtan=0,1,real,real\n_Atan_Defaults=0\n_Atan_Category=TC_MATH\n\nAtan2=0,1,real,real,real\n_Atan2_Defaults=_,_\n_Atan2_Category=TC_MATH\n\nYDWELogarithmLg=0,1,real,real\n_YDWELogarithmLg_Defaults=_\n_YDWELogarithmLg_Limits=0.01,_\n_YDWELogarithmLg_Category=TC_MATH\n\nYDWELogarithmLn=0,1,real,real\n_YDWELogarithmLn_Defaults=_\n_YDWELogarithmLn_Limits=0.01,_\n_YDWELogarithmLn_Category=TC_MATH\n\nYDWELogarithmLog=0,1,real,real,real\n_YDWELogarithmLog_Defaults=_,_\n_YDWELogarithmLog_Limits=0.01,_,0.01,_\n_YDWELogarithmLog_Category=TC_MATH\n\nGetPlayerHandicapXPBJ=0,1,real,player\n_GetPlayerHandicapXPBJ_Defaults=Player00\n_GetPlayerHandicapXPBJ_Category=TC_PLAYER\n\nGetPlayerHandicapBJ=0,1,real,player\n_GetPlayerHandicapBJ_Defaults=Player00\n_GetPlayerHandicapBJ_Category=TC_PLAYER\n\nGetItemLifeBJ=0,1,real,item\n_GetItemLifeBJ_Defaults=GetLastCreatedItem\n_GetItemLifeBJ_Category=TC_ITEM\n\nGetItemX=0,1,real,item\n_GetItemX_Defaults=GetLastCreatedItem\n_GetItemX_Category=TC_ITEM\n\nGetItemY=0,1,real,item\n_GetItemY_Defaults=GetLastCreatedItem\n_GetItemY_Category=TC_ITEM\n\nGetTimeOfDay=0,1,real\n_GetTimeOfDay_Defaults=\n_GetTimeOfDay_Category=TC_GAME\n\nGetTimeOfDayScalePercentBJ=0,1,real\n_GetTimeOfDayScalePercentBJ_Defaults=\n_GetTimeOfDayScalePercentBJ_Category=TC_GAME\n\nGetStoredReal=0,1,real,gamecache,string,string\n_GetStoredReal_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_,\n_GetStoredReal_Category=TC_GAMECACHE\n\nLoadRealBJ=0,1,real,integer,integer,hashtable\n_LoadRealBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadRealBJ_Category=TC_HASHTABLE\n\nLoadReal=0,1,real,hashtable,integer,integer\n_LoadReal_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadReal_Category=TC_HASHTABLE\n\n\n// returns string\n\nOperatorString=0,1,string,string,string\n_OperatorString_Defaults=_,_\n_OperatorString_Category=TC_NOTHING\n\n    =0,1,string,scriptcode\n_    _Defaults=_\n_    _Category=TC_NOTHING\n\nString.ConvertStringExt=0,1,string,StringExt\n_String.ConvertStringExt_Category=TC_MU_STRING\n\nGetObjectName=0,1,string,scriptcode\n_GetObjectName_Defaults=_\n_GetObjectName_Category=TC_NOTHING\n\nYDWEId2S=0,1,string,integer\n_YDWEId2S_Defaults=spsh\n_YDWEId2S_Category=TC_YDFC\n\nYDWEGetPlayerColorString=0,1,string,player,string\n_YDWEGetPlayerColorString_Defaults=Player00,_\n_YDWEGetPlayerColorString_Category=TC_YDFC\n\nSubStringBJ=0,1,string,string,integer,integer\n_SubStringBJ_Defaults=_,1,5\n_SubStringBJ_Category=TC_NOTHING\n\nSubString=0,1,string,string,integer,integer\n_SubString_Defaults=_,1,5\n_SubString_Category=TC_NOTHING\n\nI2S=0,1,string,integer\n_I2S_Defaults=GetConvertedPlayerId\n_I2S_Category=TC_CONVERSION\n\nR2S=0,1,string,real\n_R2S_Defaults=GetUnitStateSwap\n_R2S_Category=TC_CONVERSION\n\nYDWE_PreloadSL_GetFile=0,1,string,player,string,integer\n_YDWE_PreloadSL_GetFile_Defaults=Player00,_,_\n_YDWE_PreloadSL_GetFile_Limits=_,_,_,_,1,16\n_YDWE_PreloadSL_GetFile_Category=TC_YDSL\n\nYDWEGetLocalVariableString=0,1,string,string\n_YDWEGetLocalVariableString_Category=TC_YDLC\n\nYDWEGetLocalVariableStringArray=0,1,string,string,integer\n_YDWEGetLocalVariableStringArray_Defaults=_,1\n_YDWEGetLocalVariableStringArray_Limits=_,_,0,_\n_YDWEGetLocalVariableStringArray_Category=TC_YDLC\n\nYDWEGetStringByInteger=0,1,string,integer,integer\n_YDWEGetStringByInteger_Category=TC_YDLD\n\nYDWEGetStringByString=0,1,string,string,string\n_YDWEGetStringByString_Category=TC_YDLD\n\nR2SW=0,1,string,real,integer,integer\n_R2SW_Defaults=GetUnitStateSwap,1,2\n_R2SW_Limits=_,_,0,_,0,_\n_R2SW_Category=TC_CONVERSION\n\nOrderId2StringBJ=0,1,string,ordercode\n_OrderId2StringBJ_Defaults=GetIssuedOrderIdBJ\n_OrderId2StringBJ_Category=TC_CONVERSION\n\nUnitId2StringBJ=0,1,string,unitcode\n_UnitId2StringBJ_Defaults=GetUnitTypeId\n_UnitId2StringBJ_Category=TC_CONVERSION\n\nGetLocalizedString=1,0,string,string\n_GetLocalizedString_Defaults=_\n_GetLocalizedString_Category=TC_CONVERSION\n\nStringIdentity=1,0,string,string\n_StringIdentity_Defaults=_\n_StringIdentity_Category=TC_CONVERSION\n_StringIdentity_ScriptName=GetLocalizedString\n\nGetLocalizedHotkey=1,0,integer,string\n_GetLocalizedHotkey_Defaults=_\n_GetLocalizedHotkey_Category=TC_CONVERSION\n\nStringCase=1,1,string,StringExt,stringcaseoption\n_StringCase_Defaults=_,StringCaseLower\n_StringCase_Category=TC_CONVERSION\n\nGetTriggerName=1,1,string\n_GetTriggerName_Defaults=\n_GetTriggerName_Category=TC_TRIGGER\n\nGetUnitName=0,1,string,unit\n_GetUnitName_Defaults=GetTriggerUnit\n_GetUnitName_Category=TC_UNIT\n\nGetItemName=0,1,string,item\n_GetItemName_Defaults=GetManipulatedItem\n_GetItemName_Category=TC_ITEM\n\nMultiboardGetTitleText=1,1,string,multiboard\n_MultiboardGetTitleText_Defaults=GetLastCreatedMultiboard\n_MultiboardGetTitleText_Category=TC_MULTIBOARD\n\nGetDestructableName=1,1,string,destructable\n_GetDestructableName_Defaults=GetLastCreatedDestructable\n_GetDestructableName_Category=TC_DESTRUCT\n\nGetEventPlayerChatString=0,1,string\n_GetEventPlayerChatString_Defaults=\n_GetEventPlayerChatString_Category=TC_EVENTRESPONSE\n\nGetEventPlayerChatStringMatched=0,1,string\n_GetEventPlayerChatStringMatched_Defaults=\n_GetEventPlayerChatStringMatched_Category=TC_EVENTRESPONSE\n\nGetSaveBasicFilename=1,0,string\n_GetSaveBasicFilename_Defaults=\n_GetSaveBasicFilename_Category=TC_EVENTRESPONSE\n\nGetPlayerName=0,1,string,player\n_GetPlayerName_Defaults=GetTriggerPlayer\n_GetPlayerName_Category=TC_PLAYER\n\nGetHeroProperName=1,1,string,unit\n_GetHeroProperName_Defaults=GetTriggerUnit\n_GetHeroProperName_Category=TC_HERO\n\nGetAbilityName=1,1,string,abilcode\n_GetAbilityName_Defaults=_\n_GetAbilityName_Category=TC_GAME\n_GetAbilityName_ScriptName=GetObjectName\n\nGetAbilityEffectBJ=1,1,string,abilcode,effecttype,integer\n_GetAbilityEffectBJ_Defaults=_,EffectTypeEffect,0\n_GetAbilityEffectBJ_Category=TC_GAME\n_GetAbilityEffectBJ_ScriptName=GetAbilityEffectById\n\nGetAbilitySoundBJ=1,1,string,abilcode,soundtype\n_GetAbilitySoundBJ_Defaults=_,SoundTypeEffect\n_GetAbilitySoundBJ_Category=TC_GAME\n_GetAbilitySoundBJ_ScriptName=GetAbilitySoundById\n\nGetStoredString=0,1,string,gamecache,string,string\n_GetStoredString_Defaults=GetLastCreatedGameCacheBJ,\"Category\",_,\n_GetStoredString_Category=TC_GAMECACHE\n\nLoadStringBJ=1,0,string,integer,integer,hashtable\n_LoadStringBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadStringBJ_Category=TC_HASHTABLE\n\nLoadStr=1,0,string,hashtable,integer,integer\n_LoadStr_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadStr_Category=TC_HASHTABLE\n\n// returns location\n\nGetRectCenter=0,1,location,rect\n_GetRectCenter_Defaults=GetPlayableMapRect\n_GetRectCenter_Category=TC_NOTHING\n\nGetRandomLocInRect=0,1,location,rect\n_GetRandomLocInRect_Defaults=GetPlayableMapRect\n_GetRandomLocInRect_Category=TC_NOTHING\n\n     =0,1,location,scriptcode\n_     _Defaults=_\n_     _Category=TC_NOTHING\n\nOffsetLocation=0,1,location,location,real,real\n_OffsetLocation_Defaults=_,0,0\n_OffsetLocation_Category=TC_NOTHING\n\nPolarProjectionBJ=0,1,location,location,real,real\n_PolarProjectionBJ_Defaults=_,256,0\n_PolarProjectionBJ_Category=TC_NOTHING\n\n//最萌小汐\nmath.PolarProjectionMU=0,1,location,location,real,real\n_math.PolarProjectionMU_Defaults=_,256,0\n_math.PolarProjectionMU_Category=TC_MU_MATH\n\nLocation=0,1,location,real,real\n_Location_Defaults=0,0\n_Location_Category=TC_CONVERSION\n\nYDWEGetLocalVariableLocation=0,1,location,string\n_YDWEGetLocalVariableLocation_Category=TC_YDLC\n\nYDWEGetLocalVariableLocationArray=0,1,location,string,integer\n_YDWEGetLocalVariableLocationArray_Defaults=_,1\n_YDWEGetLocalVariableLocationArray_Limits=_,_,0,_\n_YDWEGetLocalVariableLocationArray_Category=TC_YDLC\n\nYDWEGetLocationByInteger=0,1,location,integer,integer\n_YDWEGetLocationByInteger_Limits=0,_,0,_\n_YDWEGetLocationByInteger_Category=TC_YDLD\n\nYDWEGetLocationByString=0,1,location,string,string\n_YDWEGetLocationByString_Category=TC_YDLD\n\nGetUnitLoc=0,1,location,unit\n_GetUnitLoc_Defaults=GetTriggerUnit\n_GetUnitLoc_Category=TC_UNIT\n\nGetUnitRallyPoint=1,1,location,unit\n_GetUnitRallyPoint_Defaults=GetTriggerUnit\n_GetUnitRallyPoint_Category=TC_UNIT\n\nCameraSetupGetDestPositionLoc=0,1,location,camerasetup\n_CameraSetupGetDestPositionLoc_Defaults=_\n_CameraSetupGetDestPositionLoc_Category=TC_CAMERA\n\nGetCameraTargetPositionLoc=0,1,location\n_GetCameraTargetPositionLoc_Defaults=\n_GetCameraTargetPositionLoc_Category=TC_CAMERA\n\nGetCameraEyePositionLoc=0,1,location\n_GetCameraEyePositionLoc_Defaults=\n_GetCameraEyePositionLoc_Category=TC_CAMERA\n\nGetDestructableLoc=0,1,location,destructable\n_GetDestructableLoc_Defaults=GetLastCreatedDestructable\n_GetDestructableLoc_Category=TC_DESTRUCT\n\nGetOrderPointLoc=0,1,location\n_GetOrderPointLoc_Defaults=\n_GetOrderPointLoc_Category=TC_EVENTRESPONSE\n\nGetSpellTargetLoc=1,0,location\n_GetSpellTargetLoc_Defaults=\n_GetSpellTargetLoc_Category=TC_EVENTRESPONSE\n\nGetPlayerStartLocationLoc=0,1,location,player\n_GetPlayerStartLocationLoc_Defaults=Player00\n_GetPlayerStartLocationLoc_Category=TC_PLAYER\n\nGetItemLoc=0,1,location,item\n_GetItemLoc_Defaults=GetLastCreatedItem\n_GetItemLoc_Category=TC_ITEM\n\nWaygateGetDestinationLocBJ=0,1,location,unit\n_WaygateGetDestinationLocBJ_Defaults=_\n_WaygateGetDestinationLocBJ_Category=TC_NEUTRALBUILDING\n\n// returns region\nCreateRegion=0,1,region\n_CreateRegion_Category=TC_REGION\n_CreateRegion_Defaults=\n\nGetTriggeringRegion=0,1,region\n_GetTriggeringRegion_Category=TC_EVENTRESPONSE\n\nYDWEGetRegionByInteger=0,1,region,integer,integer\n_YDWEGetRegionByInteger_Limits=0,_,0,_\n_YDWEGetRegionByInteger_Category=TC_YDLD\n\nYDWEGetRegionByString=0,1,region,string,string\n_YDWEGetRegionByString_Category=TC_YDLD\n\n// returns rect\nGetCurrentCameraBoundsMapRectBJ=0,1,rect\n_GetCurrentCameraBoundsMapRectBJ_Defaults=\n_GetCurrentCameraBoundsMapRectBJ_Category=TC_NOTHING\n\nGetCameraBoundsMapRect=0,1,rect\n_GetCameraBoundsMapRect_Defaults=\n_GetCameraBoundsMapRect_Category=TC_NOTHING\n\nGetPlayableMapRect=0,1,rect\n_GetPlayableMapRect_Defaults=\n_GetPlayableMapRect_Category=TC_NOTHING\n\nGetEntireMapRect=0,1,rect\n_GetEntireMapRect_Defaults=\n_GetEntireMapRect_Category=TC_NOTHING\n_GetEntireMapRect_ScriptName=GetWorldBounds\n\nYDWEGetLocalVariableRect=0,1,rect,string\n_YDWEGetLocalVariableRect_Category=TC_YDLC\n\nYDWEGetLocalVariableRectArray=0,1,rect,string,integer\n_YDWEGetLocalVariableRectArray_Defaults=_,1\n_YDWEGetLocalVariableRectArray_Limits=_,_,0,_\n_YDWEGetLocalVariableRectArray_Category=TC_YDLC\n\nYDWEGetRectByInteger=0,1,rect,integer,integer\n_YDWEGetRectByInteger_Limits=0,_,0,_\n_YDWEGetRectByInteger_Category=TC_YDLD\n\nYDWEGetRectByString=0,1,rect,string,string\n_YDWEGetRectByString_Category=TC_YDLD\n\nYDWEGetRect=0,1,rect,real,real,real,real\n_YDWEGetRect_Defaults=0,0,100,50\n_YDWEGetRect_Limits=_,_,_,_,0,_,0,_\n_YDWEGetRect_Category=TC_NOTHING\n\nOffsetRectBJ=0,1,rect,rect,real,real\n_OffsetRectBJ_Defaults=_,0,0\n_OffsetRectBJ_Category=TC_NOTHING\n\nRectFromCenterSizeBJ=0,1,rect,location,real,real\n_RectFromCenterSizeBJ_Defaults=_,_,_\n_RectFromCenterSizeBJ_Category=TC_NOTHING\n\nRect=0,1,rect,real,real,real,real\n_Rect_Defaults=0,0,0,0\n_Rect_Category=TC_NOTHING\n\nRectFromLoc=0,1,rect,location,location\n_RectFromLoc_Defaults=Location,Location\n_RectFromLoc_Category=TC_NOTHING\n\n// returns unit\nCreateUnit=0,1,unit,player,unitcode,real,real,real\n_CreateUnit_Defaults=Player00,hfoo,0,0,0\n_CreateUnit_Category=TC_NOTHING\n\nCreateUnitAtLoc=0,1,unit,player,unitcode,location,real\n_CreateUnitAtLoc_Defaults=Player00,hfoo,_,0\n_CreateUnitAtLoc_Category=TC_NOTHING\n\n//最萌小汐\nUnit.CreateUnitAtLocMU=0,1,unit,player,unitcode,location,real\n_Unit.CreateUnitAtLocMU_Defaults=Player00,hfoo,_,0\n_Unit.CreateUnitAtLocMU_Category=TC_NOTHING\n\nCreateCorpse=0,1,unit,player,unitcode,real,real,real\n_CreateCorpse_Defaults=Player00,hfoo,0,0,0\n_CreateCorpse_Category=TC_NOTHING\n\nCreateBlightedGoldmine=0,1,unit,player,real,real,real\n_CreateBlightedGoldmine_Defaults=Player00,0,0,0\n_CreateBlightedGoldmine_Category=TC_NOTHING\n\nGetLastCreatedUnit=0,1,unit\n_GetLastCreatedUnit_Defaults=\n_GetLastCreatedUnit_Category=TC_LAST\n\nGetLastRestoredUnitBJ=0,1,unit\n_GetLastRestoredUnitBJ_Defaults=\n_GetLastRestoredUnitBJ_Category=TC_LAST\n\nGetLastReplacedUnitBJ=0,1,unit\n_GetLastReplacedUnitBJ_Defaults=\n_GetLastReplacedUnitBJ_Category=TC_LAST\n\nGetLastHauntedGoldMine=0,1,unit\n_GetLastHauntedGoldMine_Defaults=\n_GetLastHauntedGoldMine_Category=TC_LAST\n\nGetEnumUnit=0,1,unit\n_GetEnumUnit_Defaults=\n_GetEnumUnit_Category=TC_NOTHING\n\nGetFilterUnit=0,1,unit\n_GetFilterUnit_Defaults=\n_GetFilterUnit_Category=TC_NOTHING\n\nFirstOfGroup=0,1,unit,group\n_FirstOfGroup_Defaults=\n_FirstOfGroup_Category=TC_NOTHING\n\n      =0,1,unit,scriptcode\n_      _Defaults=_\n_      _Category=TC_NOTHING\n\n\n//YDWEGetLocalVariable=0,1,unit,string\n//_YDWEGetLocalVariable_Category=TC_YDLC\n\n//YDWEGetLocalVariableUnit=0,1,unit,string\n//_YDWEGetLocalVariableUnit_Category=TC_YDLD\n\nYDWEGetLocalVariableUnit=0,1,unit,string\n_YDWEGetLocalVariableUnit_Category=TC_YDLC\n\nYDWEGetLocalVariableUnitArray=0,1,unit,string,integer\n_YDWEGetLocalVariableUnitArray_Defaults=_,1\n_YDWEGetLocalVariableUnitArray_Limits=_,_,0,_\n_YDWEGetLocalVariableUnitArray_Category=TC_YDLC\n\nYDWEGetUnitByInteger=0,1,unit,integer,integer\n_YDWEGetUnitByInteger_Limits=0,_,0,_\n_YDWEGetUnitByInteger_Category=TC_YDLD\n\nYDWEGetUnitByString=0,1,unit,string,string\n_YDWEGetUnitByString_Category=TC_YDLD\n\nGetLastAbilityCastingUnit=0,1,unit\n_GetLastAbilityCastingUnit_Category=TC_YDFC\n\nGetLastAbilityTargetUnit=0,1,unit\n_GetLastAbilityTargetUnit_Category=TC_YDFC\n\nGroupPickRandomUnit=0,1,unit,group\n_GroupPickRandomUnit_Defaults=_\n_GroupPickRandomUnit_Category=TC_NOTHING\n\nGetUnitRallyUnit=1,0,unit,unit\n_GetUnitRallyUnit_Defaults=GetTriggerUnit\n_GetUnitRallyUnit_Category=TC_UNIT\n\nGetAttackedUnitBJ=0,1,unit\n_GetAttackedUnitBJ_Defaults=\n_GetAttackedUnitBJ_Category=TC_EVENTRESPONSE\n_GetAttackedUnitBJ_ScriptName=GetTriggerUnit\n\nGetAttacker=0,1,unit\n_GetAttacker_Defaults=\n_GetAttacker_Category=TC_EVENTRESPONSE\n\nGetBuyingUnit=1,0,unit\n_GetBuyingUnit_Defaults=\n_GetBuyingUnit_Category=TC_EVENTRESPONSE\n\nGetCancelledStructure=0,1,unit\n_GetCancelledStructure_Defaults=\n_GetCancelledStructure_Category=TC_EVENTRESPONSE\n\nGetSpellAbilityUnit=1,0,unit\n_GetSpellAbilityUnit_Defaults=\n_GetSpellAbilityUnit_Category=TC_EVENTRESPONSE\n\nGetConstructingStructure=0,1,unit\n_GetConstructingStructure_Defaults=\n_GetConstructingStructure_Category=TC_EVENTRESPONSE\n\nGetConstructedStructure=0,1,unit\n_GetConstructedStructure_Defaults=\n_GetConstructedStructure_Category=TC_EVENTRESPONSE\n\nGetEventDamageSource=1,0,unit\n_GetEventDamageSource_Defaults=\n_GetEventDamageSource_Category=TC_EVENTRESPONSE\n\nEvent.GetOriginDamageFrom=1,0,unit\n_Event.GetOriginDamageFrom_Defaults=\n_Event.GetOriginDamageFrom_Category=TC_EVENTRESPONSE\n\nGetDecayingUnit=0,1,unit\n_GetDecayingUnit_Defaults=\n_GetDecayingUnit_Category=TC_EVENTRESPONSE\n\nGetDyingUnit=0,1,unit\n_GetDyingUnit_Defaults=\n_GetDyingUnit_Category=TC_EVENTRESPONSE\n\nGetEnteringUnit=0,1,unit\n_GetEnteringUnit_Defaults=\n_GetEnteringUnit_Category=TC_EVENTRESPONSE\n\nGetManipulatingUnit=0,1,unit\n_GetManipulatingUnit_Defaults=\n_GetManipulatingUnit_Category=TC_EVENTRESPONSE\n\nGetKillingUnitBJ=0,1,unit\n_GetKillingUnitBJ_Defaults=\n_GetKillingUnitBJ_Category=TC_EVENTRESPONSE\n_GetKillingUnitBJ_ScriptName=GetKillingUnit\n\nGetLearningUnit=0,1,unit\n_GetLearningUnit_Defaults=\n_GetLearningUnit_Category=TC_EVENTRESPONSE\n\nGetLeavingUnit=0,1,unit\n_GetLeavingUnit_Defaults=\n_GetLeavingUnit_Category=TC_EVENTRESPONSE\n\nGetLevelingUnit=0,1,unit\n_GetLevelingUnit_Defaults=\n_GetLevelingUnit_Category=TC_EVENTRESPONSE\n\nGetLoadedUnitBJ=0,1,unit\n_GetLoadedUnitBJ_Defaults=\n_GetLoadedUnitBJ_Category=TC_EVENTRESPONSE\n_GetLoadedUnitBJ_ScriptName=GetLoadedUnit\n\nGetOrderedUnit=0,1,unit\n_GetOrderedUnit_Defaults=\n_GetOrderedUnit_Category=TC_EVENTRESPONSE\n\nGetChangingUnit=1,0,unit\n_GetChangingUnit_Defaults=\n_GetChangingUnit_Category=TC_EVENTRESPONSE\n\nGetResearchingUnit=0,1,unit\n_GetResearchingUnit_Defaults=\n_GetResearchingUnit_Category=TC_EVENTRESPONSE\n\nGetRevivableUnit=0,1,unit\n_GetRevivableUnit_Defaults=\n_GetRevivableUnit_Category=TC_EVENTRESPONSE\n\nGetRevivingUnit=0,1,unit\n_GetRevivingUnit_Defaults=\n_GetRevivingUnit_Category=TC_EVENTRESPONSE\n\nGetSellingUnit=1,0,unit\n_GetSellingUnit_Defaults=\n_GetSellingUnit_Category=TC_EVENTRESPONSE\n\nGetSoldUnit=1,0,unit\n_GetSoldUnit_Defaults=\n_GetSoldUnit_Category=TC_EVENTRESPONSE\n\nGetSummonedUnit=0,1,unit\n_GetSummonedUnit_Defaults=\n_GetSummonedUnit_Category=TC_EVENTRESPONSE\n\nGetSummoningUnit=0,1,unit\n_GetSummoningUnit_Defaults=\n_GetSummoningUnit_Category=TC_EVENTRESPONSE\n\nGetOrderTargetUnit=0,1,unit\n_GetOrderTargetUnit_Defaults=\n_GetOrderTargetUnit_Category=TC_EVENTRESPONSE\n\nGetSpellTargetUnit=1,1,unit\n_GetSpellTargetUnit_Defaults=\n_GetSpellTargetUnit_Category=TC_EVENTRESPONSE\n\nGetEventTargetUnit=0,1,unit\n_GetEventTargetUnit_Defaults=\n_GetEventTargetUnit_Category=TC_EVENTRESPONSE\n\nGetTrainedUnit=0,1,unit\n_GetTrainedUnit_Defaults=\n_GetTrainedUnit_Category=TC_EVENTRESPONSE\n\nGetTransportUnitBJ=0,1,unit\n_GetTransportUnitBJ_Defaults=\n_GetTransportUnitBJ_Category=TC_EVENTRESPONSE\n_GetTransportUnitBJ_ScriptName=GetTransportUnit\n\nGetTriggerUnit=0,1,unit\n_GetTriggerUnit_Defaults=\n_GetTriggerUnit_Category=TC_EVENTRESPONSE\n\nYDWECinSActor=0,1,unit,integer\n_YDWECinSActor_Defaults=1\n_YDWECinSActor_Limits=1,_\n_YDWECinSActor_Category=TC_SCRIPTSET\n\nPlaceRandomUnit=0,1,unit,unitpool,player,real,real,real\n_PlaceRandomUnit_Defaults=_,Player00,0,0,0\n_PlaceRandomUnit_Category=TC_UNITPOOL\n\nYDWEGetLastPoolAbstractedUnit=0,1,unit\n_YDWEGetLastPoolAbstractedUnit_Defaults=\n_YDWEGetLastPoolAbstractedUnit_Category=TC_UNITPOOL\n\n//returns unitpool\nCreateUnitPool=1,0,unitpool\n_CreateUnitPool_Defaults=\n_CreateUnitPool_Category=TC_NOTHING\n\nYDWEGetLastUnitPool=1,0,unitpool\n_YDWEGetLastUnitPool_Defaults=\n_YDWEGetLastUnitPool_Category=TC_LAST\n\n// returns unitcode\n\nGetUnitTypeId=0,1,unitcode,unit\n_GetUnitTypeId_Defaults=GetTriggerUnit\n_GetUnitTypeId_Category=TC_NOTHING\n\n       =0,1,unitcode,scriptcode\n_       _Defaults=_\n_       _Category=TC_NOTHING\n\nYDWEGetLocalVariableUnitID=0,1,unitcode,string\n_YDWEGetLocalVariableUnitID_Category=TC_YDLC\n\nYDWEGetLocalVariableUnitIDArray=0,1,unitcode,string,integer\n_YDWEGetLocalVariableUnitIDArray_Defaults=_,1\n_YDWEGetLocalVariableUnitIDArray_Limits=_,_,0,_\n_YDWEGetLocalVariableUnitIDArray_Category=TC_YDLC\n\nYDWEGetUnitIDByInteger=0,1,unitcode,integer,integer\n_YDWEGetUnitIDByInteger_Limits=0,_,0,_\n_YDWEGetUnitIDByInteger_Category=TC_YDLD\n\nYDWEGetUnitIDByString=0,1,unitcode,string,string\n_YDWEGetUnitIDByString_Category=TC_YDLD\n\nChooseRandomCreepBJ=0,1,unitcode,integer\n_ChooseRandomCreepBJ_Defaults=1\n_ChooseRandomCreepBJ_Limits=-1,10\n_ChooseRandomCreepBJ_Category=TC_NOTHING\n_ChooseRandomCreepBJ_ScriptName=ChooseRandomCreep\n\nChooseRandomNPBuildingBJ=0,1,unitcode\n_ChooseRandomNPBuildingBJ_Defaults=\n_ChooseRandomNPBuildingBJ_Category=TC_NOTHING\n_ChooseRandomNPBuildingBJ_ScriptName=ChooseRandomNPBuilding\n\nString2UnitIdBJ=0,1,unitcode,string\n_String2UnitIdBJ_Defaults=footman\n_String2UnitIdBJ_Category=TC_CONVERSION\n_String2UnitIdBJ_ScriptName=UnitId\n\nGetTrainedUnitType=0,1,unitcode\n_GetTrainedUnitType_Defaults=\n_GetTrainedUnitType_Category=TC_EVENTRESPONSE\n\n\n// returns ordercode\nString2OrderIdBJ=0,1,ordercode,string\n_String2OrderIdBJ_Defaults=stop\n_String2OrderIdBJ_Category=TC_CONVERSION\n\nUnitId2OrderIdBJ=0,1,ordercode,unitcode\n_UnitId2OrderIdBJ_Defaults=hfoo\n_UnitId2OrderIdBJ_Category=TC_CONVERSION\n\nGetUnitCurrentOrder=1,0,ordercode,unit\n_GetUnitCurrentOrder_Defaults=GetTriggerUnit\n_GetUnitCurrentOrder_Category=TC_UNIT\n\nGetIssuedOrderIdBJ=0,1,ordercode\n_GetIssuedOrderIdBJ_Defaults=\n_GetIssuedOrderIdBJ_Category=TC_EVENTRESPONSE\n_GetIssuedOrderIdBJ_ScriptName=GetIssuedOrderId\n\n// returns destructable\n\nCreateDestructableZ=0,1,destructable,destructablecode,real,real,real,real,real,integer\n_CreateDestructableZ_Defaults=LTlt,0,0,0,GetRandomDirectionDeg,1,0\n_CreateDestructableZ_Category=TC_NOTHING\n\nCreateDeadDestructableZ=0,1,destructable,destructablecode,real,real,real,real,real,integer\n_CreateDeadDestructableZ_Defaults=LTlt,0,0,0,GetRandomDirectionDeg,1,0\n_CreateDeadDestructableZ_Category=TC_NOTHING\n\nGetLastCreatedDestructable=0,1,destructable\n_GetLastCreatedDestructable_Defaults=\n_GetLastCreatedDestructable_Category=TC_LAST\n\nYDWEGetDestructableByInteger=0,1,destructable,integer,integer\n_YDWEGetDestructableByInteger_Limits=0,1,0,1\n_YDWEGetDestructableByInteger_Category=TC_YDLD\n\nYDWEGetDestructableByString=0,1,destructable,string,string\n_YDWEGetDestructableByString_Category=TC_YDLD\n\nRandomDestructableInRectSimpleBJ=0,1,destructable,rect\n_RandomDestructableInRectSimpleBJ_Defaults=_\n_RandomDestructableInRectSimpleBJ_Category=TC_NOTHING\n\nRandomDestructableInRectBJ=0,1,destructable,rect,boolexpr\n_RandomDestructableInRectBJ_Defaults=_,_\n_RandomDestructableInRectBJ_Category=TC_NOTHING\n\nGetEnumDestructable=0,1,destructable\n_GetEnumDestructable_Defaults=\n_GetEnumDestructable_Category=TC_NOTHING\n\nGetFilterDestructable=0,1,destructable\n_GetFilterDestructable_Defaults=\n_GetFilterDestructable_Category=TC_NOTHING\n\nGetUnitRallyDestructable=1,0,destructable,unit\n_GetUnitRallyDestructable_Defaults=GetTriggerUnit\n_GetUnitRallyDestructable_Category=TC_UNIT\n\nGetDyingDestructable=0,1,destructable\n_GetDyingDestructable_Defaults=\n_GetDyingDestructable_Category=TC_EVENTRESPONSE\n\nGetOrderTargetDestructable=0,1,destructable\n_GetOrderTargetDestructable_Defaults=\n_GetOrderTargetDestructable_Category=TC_EVENTRESPONSE\n\nGetSpellTargetDestructable=1,0,destructable\n_GetSpellTargetDestructable_Defaults=\n_GetSpellTargetDestructable_Category=TC_EVENTRESPONSE\n\n// returns destructablecode\nGetDestructableTypeId=0,1,destructablecode,destructable\n_GetDestructableTypeId_Defaults=GetLastCreatedDestructable\n_GetDestructableTypeId_Category=TC_NOTHING\n\n\n// returns item\nCreateItem=0,1,item,itemcode,real,real\n_CreateItem_Defaults=texp,0,0\n_CreateItem_Category=TC_NOTHING\n\nGetLastCreatedItem=0,1,item\n_GetLastCreatedItem_Defaults=\n_GetLastCreatedItem_Category=TC_LAST\n\nGetLastRemovedItem=0,1,item\n_GetLastRemovedItem_Defaults=\n_GetLastRemovedItem_Category=TC_LAST\n\nGetLastMovedItemInItemSlot=0,1,item\n_GetLastMovedItemInItemSlot_Category=TC_LAST\n\nGetLastCombinedItem=0,1,item\n_GetLastCombinedItem_Category=TC_LAST\n\nUnitDropItem=0,1,item,unit,itemcode\n_UnitDropItem_Defaults=GetTriggerUnit,texp\n_UnitDropItem_Limits=_,_,_,_\n_UnitDropItem_Category=TC_NOTHING\n\nYDWEGetLocalVariableItem=0,1,item,string\n_YDWEGetLocalVariableItem_Category=TC_YDLC\n\nYDWEGetLocalVariableItemArray=0,1,item,string,integer\n_YDWEGetLocalVariableItemArray_Defaults=_,1\n_YDWEGetLocalVariableItemArray_Limits=_,_,0,_\n_YDWEGetLocalVariableItemArray_Category=TC_YDLC\n\nYDWEGetItemByInteger=0,1,item,integer,integer\n_YDWEGetItemByInteger_Limits=0,_,0,_\n_YDWEGetItemByInteger_Category=TC_YDLD\n\nYDWEGetItemByString=0,1,item,string,string\n_YDWEGetItemByString_Category=TC_YDLD\n\nRandomItemInRectSimpleBJ=1,0,item,rect\n_RandomItemInRectSimpleBJ_Defaults=_\n_RandomItemInRectSimpleBJ_Category=TC_NOTHING\n\nRandomItemInRectBJ=1,0,item,rect,boolexpr\n_RandomItemInRectBJ_Defaults=_,_\n_RandomItemInRectBJ_Category=TC_NOTHING\n\nGetEnumItem=1,0,item\n_GetEnumItem_Defaults=\n_GetEnumItem_Category=TC_NOTHING\n\nGetFilterItem=1,0,item\n_GetFilterItem_Defaults=\n_GetFilterItem_Category=TC_NOTHING\n\nUnitItemInSlot=0,1,item,unit,integer\n_UnitItemInSlot_Defaults=_,0\n_UnitItemInSlot_Limits=_,_,0,5\n_UnitItemInSlot_Category=TC_NOTHING\n\nUnitItemInSlotBJ=0,1,item,unit,integer\n_UnitItemInSlotBJ_Defaults=_,1\n_UnitItemInSlotBJ_Limits=_,_,1,6\n_UnitItemInSlotBJ_Category=TC_NOTHING\n\nGetItemOfTypeFromUnitBJ=0,1,item,unit,itemcode\n_GetItemOfTypeFromUnitBJ_Defaults=_,texp\n_GetItemOfTypeFromUnitBJ_Category=TC_NOTHING\n\nGetManipulatedItem=0,1,item\n_GetManipulatedItem_Defaults=\n_GetManipulatedItem_Category=TC_EVENTRESPONSE\n\nGetSoldItem=1,0,item\n_GetSoldItem_Defaults=\n_GetSoldItem_Category=TC_EVENTRESPONSE\n\nGetOrderTargetItem=0,1,item\n_GetOrderTargetItem_Defaults=\n_GetOrderTargetItem_Category=TC_EVENTRESPONSE\n\nGetSpellTargetItem=1,0,item\n_GetSpellTargetItem_Defaults=\n_GetSpellTargetItem_Category=TC_EVENTRESPONSE\n\nPlaceRandomItem=0,1,item,itempool,real,real\n_PlaceRandomItem_Defaults=_,0,0\n_PlaceRandomItem_Category=TC_ITEMPOOL\n\n//returns itempool\nCreateItemPool=1,0,itempool\n_CreateItemPool_Defaults=\n_CreateItemPool_Category=TC_NOTHING\n\nYDWEGetLastItemPool=1,0,itempool\n_YDWEGetLastItemPool_Defaults=\n_YDWEGetLastItemPool_Category=TC_NOTHING\n\n// returns itemtype\nGetItemType=1,1,itemtype,item\n_GetItemType_Defaults=GetLastCreatedItem\n_GetItemType_Category=TC_NOTHING\n\n\n// returns itemcode\n\nGetItemTypeId=0,1,itemcode,item\n_GetItemTypeId_Defaults=GetLastCreatedItem\n_GetItemTypeId_Category=TC_NOTHING\n\n        =0,1,itemcode,scriptcode\n_        _Defaults=_\n_        _Category=TC_NOTHING\n\nYDWEGetLocalVariableItemID=0,1,itemcode,string\n_YDWEGetLocalVariableItemID_Category=TC_YDLC\n\nYDWEGetLocalVariableItemIDArray=0,1,itemcode,string,integer\n_YDWEGetLocalVariableItemIDArray_Defaults=_,1\n_YDWEGetLocalVariableItemIDArray_Limits=_,_,0,_\n_YDWEGetLocalVariableItemIDArray_Category=TC_YDLC\n\nYDWEGetItemIDByInteger=0,1,itemcode,integer,integer\n_YDWEGetItemIDByInteger_Limits=0,_,0,_\n_YDWEGetItemIDByInteger_Category=TC_YDLD\n\nYDWEGetItemIDByString=0,1,itemcode,string,string\n_YDWEGetItemIDByString_Category=TC_YDLD\n\nChooseRandomItemExBJ=1,1,itemcode,integer,itemtype\n_ChooseRandomItemExBJ_Defaults=1,ItemTypeAny\n_ChooseRandomItemExBJ_Limits=-1,_,_,_\n_ChooseRandomItemExBJ_Category=TC_NOTHING\n\nChooseRandomItemBJ=0,1,itemcode,integer\n_ChooseRandomItemBJ_Defaults=1\n_ChooseRandomItemBJ_Limits=-1,_\n_ChooseRandomItemBJ_Category=TC_NOTHING\n_ChooseRandomItemBJ_ScriptName=ChooseRandomItem\n\n// returns widget\nGetTriggerWidget=0,1,widget\n_GetTriggerWidget_Category=TC_WIDGET\n\nGetOrderTarget=0,1,widget\n_GetOrderTarget_Category=TC_WIDGET\n\n// returns techcode\nGetResearched=0,1,techcode\n_GetResearched_Defaults=\n_GetResearched_Category=TC_EVENTRESPONSE\n\n\n// returns abilcode\n\nGetSpellAbilityId=1,0,abilcode\n_GetSpellAbilityId_Defaults=\n_GetSpellAbilityId_Category=TC_EVENTRESPONSE\n\nGetLearnedSkill=0,1,abilcode\n_GetLearnedSkill_Defaults=\n_GetLearnedSkill_Category=TC_EVENTRESPONSE\n\nYDWEGetLocalVariableAbilityID=0,1,abilcode,string\n_YDWEGetLocalVariableAbilityID_Category=TC_YDLC\n\nYDWEGetLocalVariableAbilityIDArray=0,1,abilcode,string,integer\n_YDWEGetLocalVariableAbilityIDArray_Defaults=_,1\n_YDWEGetLocalVariableAbilityIDArray_Limits=_,_,0,_\n_YDWEGetLocalVariableAbilityIDArray_Category=TC_YDLC\n\nYDWEGetAbilityIDByInteger=0,1,abilcode,integer,integer\n_YDWEGetAbilityIDByInteger_Limits=0,_,0,_\n_YDWEGetAbilityIDByInteger_Category=TC_YDLD\n\nYDWEGetAbilityIDByString=0,1,abilcode,string,string\n_YDWEGetAbilityIDByString_Category=TC_YDLD\n\n         =0,1,abilcode,scriptcode\n_         _Defaults=_\n_         _Category=TC_NOTHING\n\n\n// returns heroskillcode\nGetLearnedSkillBJ=0,1,heroskillcode\n_GetLearnedSkillBJ_Defaults=\n_GetLearnedSkillBJ_Category=TC_EVENTRESPONSE\n_GetLearnedSkillBJ_ScriptName=GetLearnedSkill\n\n// returns player\nGetEnumPlayer=0,1,player\n_GetEnumPlayer_Defaults=\n_GetEnumPlayer_Category=TC_NOTHING\n\nGetFilterPlayer=0,1,player\n_GetFilterPlayer_Defaults=\n_GetFilterPlayer_Category=TC_NOTHING\n\nGetOwningPlayer=0,1,player,unit\n_GetOwningPlayer_Defaults=GetTriggerUnit\n_GetOwningPlayer_Category=TC_NOTHING\n\nYDWEGetPlayerByInteger=0,1,player,integer,integer\n_YDWEGetPlayerByInteger_Limits=0,_,0,_\n_YDWEGetPlayerByInteger_Category=TC_YDLD\n\nYDWEGetPlayerByString=0,1,player,string,string\n_YDWEGetPlayerByString_Category=TC_YDLD\n\nGetItemPlayer=0,1,player,item\n_GetItemPlayer_Defaults=GetLastCreatedItem\n_GetItemPlayer_Category=TC_NOTHING\n\nForcePickRandomPlayer=0,1,player,force\n_ForcePickRandomPlayer_Defaults=_\n_ForcePickRandomPlayer_Category=TC_NOTHING\n\nGetLocalPlayer=0,1,player\n_GetLocalPlayer_Defaults=\n_GetLocalPlayer_Category=TC_NOTHING\n\nConvertedPlayer=0,1,player,integer\n_ConvertedPlayer_Defaults=1\n_ConvertedPlayer_Limits=1,16\n_ConvertedPlayer_Category=TC_CONVERSION\n\nPlayer=0,1,player,integer\n_Player_Defaults=1\n_Player_Limits=0,15\n_Player_Category=TC_CONVERSION\n\nLeaderboardGetIndexedPlayerBJ=1,0,player,integer,leaderboard\n_LeaderboardGetIndexedPlayerBJ_Defaults=1,GetLastCreatedLeaderboard\n_LeaderboardGetIndexedPlayerBJ_Limits=1,16\n_LeaderboardGetIndexedPlayerBJ_Category=TC_LEADERBOARD\n\nGetChangingUnitPrevOwner=1,0,player\n_GetChangingUnitPrevOwner_Defaults=\n_GetChangingUnitPrevOwner_Category=TC_EVENTRESPONSE\n\nGetTriggerPlayer=0,1,player\n_GetTriggerPlayer_Defaults=\n_GetTriggerPlayer_Category=TC_EVENTRESPONSE\n\n          =0,1,player,scriptcode\n_          _Defaults=_\n_          _Category=TC_NOTHING\n\n// returns group\nCreateGroup=0,1,group\n_CreateGroup_Defaults=\n_CreateGroup_Category=TC_NOTHING\n\nGetLastCreatedGroup=0,1,group\n_GetLastCreatedGroup_Defaults=\n_GetLastCreatedGroup_Category=TC_LAST\n\n           =0,1,group,scriptcode\n_           _Defaults=_\n_           _Category=TC_NOTHING\n\n CreateNUnitsAtLoc=0,1,group,integer,unitcode,player,location,real\n_ CreateNUnitsAtLoc_Defaults=1,hfoo,Player00,_,RealUnitFacing\n_ CreateNUnitsAtLoc_Limits=1,_,_,_,_,_,_,_,0,360\n_ CreateNUnitsAtLoc_Category=TC_UNIT\n\nGetRandomSubGroup=1,0,group,integer,group\n_GetRandomSubGroup_Defaults=4,GetUnitsInRectAll\n_GetRandomSubGroup_Category=TC_NOTHING\n\nGetUnitsInRectAll=0,1,group,rect\n_GetUnitsInRectAll_Defaults=GetPlayableMapRect\n_GetUnitsInRectAll_Category=TC_NOTHING\n\nYDWEGetLocalVariableGroup=0,1,group,string\n_YDWEGetLocalVariableGroup_Category=TC_YDLC\n\nYDWEGetLocalVariableGroupArray=0,1,group,string,integer\n_YDWEGetLocalVariableGroupArray_Defaults=_,1\n_YDWEGetLocalVariableGroupArray_Limits=_,_,0,_\n_YDWEGetLocalVariableGroupArray_Category=TC_YDLC\n\nYDWEGetGroupByInteger=0,1,group,integer,integer\n_YDWEGetGroupByInteger_Limits=0,_,0,_\n_YDWEGetGroupByInteger_Category=TC_YDLD\n\nYDWEGetGroupByString=0,1,group,string,string\n_YDWEGetGroupByString_Category=TC_YDLD\n\nGetUnitsInRectOfPlayer=0,1,group,rect,player\n_GetUnitsInRectOfPlayer_Defaults=GetPlayableMapRect,Player00\n_GetUnitsInRectOfPlayer_Category=TC_NOTHING\n\nGetUnitsInRectMatching=0,1,group,rect,boolexpr\n_GetUnitsInRectMatching_Defaults=GetPlayableMapRect,_\n_GetUnitsInRectMatching_Category=TC_NOTHING\n\n//最萌小汐\nUnit.GetUnitInLineAll=0,1,group,location,boolean,real,real,real\n_Unit.GetUnitInLineAll_Defaults=GetUnitLoc,true,0,1000,200\n_Unit.GetUnitInLineAll_Category=TC_MU_UNIT\n\nGetUnitsInRangeOfLocAll=0,1,group,real,location\n_GetUnitsInRangeOfLocAll_Defaults=512,GetRectCenter\n_GetUnitsInRangeOfLocAll_Limits=0,_,_,_\n_GetUnitsInRangeOfLocAll_Category=TC_NOTHING\n\n//最萌小汐\nUnit.GetUnitsInRangeOfLocAllMU=0,1,group,real,location\n_Unit.GetUnitsInRangeOfLocAllMU_Defaults=512,GetRectCenter\n_Unit.GetUnitsInRangeOfLocAllMU_Limits=0,_,_,_\n_Unit.GetUnitsInRangeOfLocAllMU_Category=TC_MU_UNIT\n\nGetUnitsInRangeOfLocMatching=0,1,group,real,location,boolexpr\n_GetUnitsInRangeOfLocMatching_Defaults=512,GetRectCenter,_\n_GetUnitsInRangeOfLocMatching_Limits=0,_,_,_,_,_\n_GetUnitsInRangeOfLocMatching_Category=TC_NOTHING\n\n//最萌小汐\nUnit.GetUnitsInRangeOfLocMatchingMU=0,1,group,real,location,boolexpr\n_Unit.GetUnitsInRangeOfLocMatchingMU_Defaults=512,GetRectCenter,_\n_Unit.GetUnitsInRangeOfLocMatchingMU_Limits=0,_,_,_,_\n_Unit.GetUnitsInRangeOfLocMatchingMU_Category=TC_MU_UNIT\n\nGetUnitsOfPlayerAll=0,1,group,player\n_GetUnitsOfPlayerAll_Defaults=Player00\n_GetUnitsOfPlayerAll_Category=TC_NOTHING\n\nGetUnitsOfPlayerAndTypeId=0,1,group,player,unitcode\n_GetUnitsOfPlayerAndTypeId_Defaults=Player00,hfoo\n_GetUnitsOfPlayerAndTypeId_Category=TC_NOTHING\n\nGetUnitsOfPlayerMatching=0,1,group,player,boolexpr\n_GetUnitsOfPlayerMatching_Defaults=Player00,_\n_GetUnitsOfPlayerMatching_Category=TC_NOTHING\n\nGetUnitsOfTypeIdAll=0,1,group,unitcode\n_GetUnitsOfTypeIdAll_Defaults=hfoo\n_GetUnitsOfTypeIdAll_Category=TC_NOTHING\n\nGetUnitsSelectedAll=0,1,group,player\n_GetUnitsSelectedAll_Defaults=Player00\n_GetUnitsSelectedAll_Category=TC_NOTHING\n\n// returns force\n\nCreateForce=0,1,force\n_CreateForce_Defaults=\n_CreateForce_Category=TC_NOTHING\n\nGetPlayersAll=0,1,force\n_GetPlayersAll_Defaults=\n_GetPlayersAll_Category=TC_NOTHING\n\nGetPlayersByMapControl=0,1,force,mapcontrol\n_GetPlayersByMapControl_Defaults=MapControlComputer\n_GetPlayersByMapControl_Category=TC_NOTHING\n\nGetPlayersMatching=0,1,force,boolexpr\n_GetPlayersMatching_Defaults=_\n_GetPlayersMatching_Category=TC_NOTHING\n\nGetPlayersAllies=0,1,force,player\n_GetPlayersAllies_Defaults=Player00\n_GetPlayersAllies_Category=TC_NOTHING\n\nGetPlayersEnemies=0,1,force,player\n_GetPlayersEnemies_Defaults=Player00\n_GetPlayersEnemies_Category=TC_NOTHING\n\nGetForceOfPlayer=0,1,force,player\n_GetForceOfPlayer_Defaults=Player00\n_GetForceOfPlayer_Category=TC_NOTHING\n\nYDWEGetForceByInteger=0,1,force,integer,integer\n_YDWEGetForceByInteger_Limits=0,_,0,_\n_YDWEGetForceByInteger_Category=TC_YDLD\n\nYDWEGetForceByString=0,1,force,string,string\n_YDWEGetForceByString_Category=TC_YDLD\n\n// returns race\nGetPlayerRace=0,1,race,player\n_GetPlayerRace_Defaults=Player00\n_GetPlayerRace_Category=TC_NOTHING\n\nGetUnitRace=0,1,race,unit\n_GetUnitRace_Defaults=GetTriggerUnit\n_GetUnitRace_Category=TC_NOTHING\n\n\n// returns camerasetup\nGetCurrentCameraSetup=0,1,camerasetup\n_GetCurrentCameraSetup_Defaults=\n_GetCurrentCameraSetup_Category=TC_NOTHING\n\n\n// returns fogmodifier\nCreateFogModifierRect=0,1,fogmodifier,player,fogstate,rect,sharevisionoption,converunitoption\n_CreateFogModifierRect_Defaults=Player00,FogStateVisible,_,ShareVisionShare,ConverUnitNot\n_CreateFogModifierRect_Category=TC_NOTHING\n\nCreateFogModifierRadius=0,1,fogmodifier,player,fogstate,real,real,real,sharevisionoption,converunitoption\n_CreateFogModifierRadius_Defaults=Player00,FogStateVisible,0,0,512,ShareVisionShare,ConverUnitNot\n_CreateFogModifierRadius_Category=TC_NOTHING\n\nGetLastCreatedFogModifier=0,1,fogmodifier\n_GetLastCreatedFogModifier_Defaults=\n_GetLastCreatedFogModifier_Category=TC_LAST\n\n\n// returns triggercondition\nYDWEGetTriggerConditionByInteger=0,1,triggercondition,integer,integer\n_YDWEGetTriggerConditionByInteger_Limits=0,_,0,_\n_YDWEGetTriggerConditionByInteger_Category=TC_YDLD\n\nYDWEGetTriggerConditionByString=0,1,triggercondition,string,string\n_YDWEGetTriggerConditionByString_Category=TC_YDLD\n\n// returns triggeraction\nYDWEGetTriggerActionByInteger=0,1,triggeraction,integer,integer\n_YDWEGetTriggerActionByInteger_Limits=0,_,0,_\n_YDWEGetTriggerActionByInteger_Category=TC_YDLD\n\nYDWEGetTriggerActionByString=0,1,triggeraction,string,string\n_YDWEGetTriggerActionByString_Category=TC_YDLD\n\n// returns event\nYDWEGetTriggerEventByInteger=0,1,event,integer,integer\n_YDWEGetTriggerEventByInteger_Limits=0,_,0,_\n_YDWEGetTriggerEventByInteger_Category=TC_YDLD\n\nYDWEGetTriggerEventByString=0,1,event,string,string\n_YDWEGetTriggerEventByString_Category=TC_YDLD\n\n// returns boolexpr\nYDWEGetBoolexprByInteger=0,1,boolexpr,integer,integer\n_YDWEGetBoolexprByInteger_Limits=0,_,0,_\n_YDWEGetBoolexprByInteger_Category=TC_YDLD\n\nYDWEGetBoolexprByString=0,1,boolexpr,string,string\n_YDWEGetBoolexprByString_Category=TC_YDLD\n\n// returns trigger\nCreateTrigger=0,1,trigger\n_CreateTrigger_Category=TC_TRIGGER\n\nGetTriggeringTrigger=0,1,trigger\n_GetTriggeringTrigger_Defaults=\n_GetTriggeringTrigger_Category=TC_NOTHING\n\nYDWEGetTriggerByInteger=0,1,trigger,integer,integer\n_YDWEGetTriggerByInteger_Limits=0,_,0,_\n_YDWEGetTriggerByInteger_Category=TC_YDLD\n\nYDWEGetTriggerByString=0,1,trigger,string,string\n_YDWEGetTriggerByString_Category=TC_YDLD\n\n// returns gamedifficulty\nGetGameDifficulty=0,1,gamedifficulty\n_GetGameDifficulty_Defaults=\n_GetGameDifficulty_Category=TC_NOTHING\n\n\n// returns aidifficulty\nGetAIDifficulty=1,1,aidifficulty,player\n_GetAIDifficulty_Defaults=Player00\n_GetAIDifficulty_Category=TC_NOTHING\n\n\n// returns gamespeed\nGetGameSpeed=0,1,gamespeed\n_GetGameSpeed_Defaults=\n_GetGameSpeed_Category=TC_NOTHING\n\n\n// returns mapcontrol\nGetPlayerController=0,1,mapcontrol,player\n_GetPlayerController_Defaults=Player00\n_GetPlayerController_Category=TC_NOTHING\n\n\n// returns playercolor\nGetPlayerColor=0,1,playercolor,player\n_GetPlayerColor_Defaults=Player00\n_GetPlayerColor_Category=TC_NOTHING\n\n\n// returns playerslotstate\nGetPlayerSlotState=0,1,playerslotstate,player\n_GetPlayerSlotState_Defaults=Player00\n_GetPlayerSlotState_Category=TC_NOTHING\n\n\n// returns effect\nAddSpecialEffect=0,1,effect,modelfile,real,real\n_AddSpecialEffect_Defaults=\"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl\",0,0\n_AddSpecialEffect_Category=TC_NOTHING\n\nAddSpecialEffectLoc=0,1,effect,modelfile,location\n_AddSpecialEffectLoc_Defaults=\"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl\",_\n_AddSpecialEffectLoc_Category=TC_NOTHING\n\nEffect.AddSpecialEffectLoc2=0,1,effect,modelfile,location\n_Effect.AddSpecialEffectLoc2_Defaults=\"Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl\",_\n_Effect.AddSpecialEffectLoc2_Category=TC_MU_EFFECT\n\nAddSpecialEffectTarget=0,1,effect,modelfile,unit,string\n_AddSpecialEffectTarget_Defaults=\"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl\",GetTriggerUnit,\"overhead\"\n_AddSpecialEffectTarget_Category=TC_NOTHING\n\n//AddSpellEffect\n//AddSpellEffectLoc\n//AddSpellEffectTarget\n\nAddSpellEffectById=0,1,effect,abilcode,effecttype,real,real\n_AddSpellEffectById_Defaults=_,EffectTypeEffect,0,0\n_AddSpellEffectById_Category=TC_NOTHING\n\nAddSpellEffectByIdLoc=0,1,effect,abilcode,effecttype,location\n_AddSpellEffectByIdLoc_Defaults=_,EffectTypeEffect,_\n_AddSpellEffectByIdLoc_Category=TC_NOTHING\n\nAddSpellEffectTargetById=0,1,effect,abilcode,effecttype,unit,string\n_AddSpellEffectTargetById_Defaults=_,EffectTypeEffect,GetTriggerUnit,\"overhead\"\n_AddSpellEffectTargetById_Category=TC_NOTHING\n\nGetLastCreatedEffectBJ=0,1,effect\n_GetLastCreatedEffectBJ_Defaults=\n_GetLastCreatedEffectBJ_Category=TC_LAST\n\nYDWEGetLocalVariableEffect=0,1,effect,string\n_YDWEGetLocalVariableEffect_Category=TC_YDLC\n\nYDWEGetLocalVariableEffectArray=0,1,effect,string,integer\n_YDWEGetLocalVariableEffectArray_Defaults=_,1\n_YDWEGetLocalVariableEffectArray_Limits=_,_,0,_\n_YDWEGetLocalVariableEffectArray_Category=TC_YDLC\n\nYDWEGetEffectByInteger=0,1,effect,integer,integer\n_YDWEGetEffectByInteger_Category=TC_YDLD\n\nYDWEGetEffectByString=0,1,effect,string,string\n_YDWEGetEffectByString_Category=TC_YDLD\n\n// returns lightning\n//AddLightning\n\nAddLightning=0,1,lightning,lightningtype,allowdontoption,real,real,real,real\n_AddLightning_Defaults=LightningTypeCLPB,AllowDontDont,0,0,0,0\n_AddLightning_Category=TC_LIGHTNING\n\nAddLightningEx=0,1,lightning,lightningtype,allowdontoption,real,real,real,real,real,real\n_AddLightningEx_Defaults=LightningTypeCLPB,AllowDontDont,0,0,0,0,0,0\n_AddLightningEx_Category=TC_LIGHTNING\n\nbaka.AddLightningEx2=0,1,lightning,string,allowdontoption,real,real,real,real,real,real\n_baka.AddLightningEx2_Defaults=LightningTypeCLPB,AllowDontDont,0,0,0,0,0,0\n_baka.AddLightningEx2_Category=TC_LIGHTNING\n\nYDWEGetLightningByInteger=0,1,lightning,integer,integer\n_YDWEGetLightningByInteger_Limits=0,_,0,_\n_YDWEGetLightningByInteger_Category=TC_YDLD\n\nYDWEGetLightningByString=0,1,lightning,string,string\n_YDWEGetLightningByString_Category=TC_YDLD\n\nGetLastCreatedLightningBJ=1,0,lightning\n_GetLastCreatedLightningBJ_Defaults=\n_GetLastCreatedLightningBJ_Category=TC_LAST\n\n// returns image\nCreateImage=1,0,image,string,real,real,real,real,real,real,real,real,real,imagetype\n_CreateImage_Defaults=\"ReplaceableTextures\\Splats\\AuraRune9b.blp\",256,256,256,0,0,0,0,0,0,ImageTypeIndicator\n_CreateImage_Category=TC_NOTHING\n\nGetLastCreatedImage=1,0,image\n_GetLastCreatedImage_Defaults=\n_GetLastCreatedImage_Category=TC_LAST\n\n// returns ubersplat\nCreateUbersplat=1,0,ubersplat,real,real,ubersplattype,integer,integer,integer,integer,enabledisableoption,enabledisableoption\n_CreateUbersplat_Defaults=0,0,UbersplatTypeNGOL,255,255,255,255,EnableDisableDisable,EnableDisableDisable\n_CreateUbersplat_Category=TC_NOTHING\n\nGetLastCreatedUbersplat=1,0,ubersplat\n_GetLastCreatedUbersplat_Defaults=\n_GetLastCreatedUbersplat_Category=TC_LAST\n\n// returns weathereffect\nAddWeatherEffect=0,1,weathereffect,rect,weathereffectcode\n_AddWeatherEffect_Defaults=\n_AddWeatherEffect_Category=TC_NOTHING\n\nGetLastCreatedWeatherEffect=0,1,weathereffect\n_GetLastCreatedWeatherEffect_Defaults=\n_GetLastCreatedWeatherEffect_Category=TC_LAST\n\n// returns terraindeformation\nTerrainDeformCrater=1,1,terraindeformation,real,real,real,real,integer,cratertype\n_TerrainDeformCrater_Defaults=0,0,512,96,4000,CraterTypeTemporary\n_TerrainDeformCrater_Limits=_,_,_,_,0.01,_,_,_,1,_,_,_\n_TerrainDeformCrater_Category=TC_NOTHING\n\nTerrainDeformRipple=1,1,terraindeformation,real,real,real,real,integer,integer,real,real,real,rippletype\n_TerrainDeformRipple_Defaults=0,0,1024,96,1,4000,4,16,1,RippleTypeNormal\n_TerrainDeformRipple_Limits=_,_,_,_,0.01,_,_,_,1,_,1,_,0.01,_,0.01,_,0.01,_,_,_\n_TerrainDeformRipple_Category=TC_NOTHING\n\nTerrainDeformWave=1,1,terraindeformation,real,real,real,real,real,real,real,real,integer,integer\n_TerrainDeformWave_Defaults=0,0,1,0,1024,1024,256,96,1000,1\n_TerrainDeformWave_Limits=_,_,_,_,_,_,_,_,0.01,_,0.01,_,0.01,_,0.01,_,1,_,1,_\n_TerrainDeformWave_Category=TC_NOTHING\n\nTerrainDeformRandom=1,1,terraindeformation,real,real,real,real,real,integer,integer\n_TerrainDeformRandom_Defaults=0,0,0,0,1024,-96,96,4000,100\n_TerrainDeformRandom_Limits=_,_,_,_,0.01,_,_,_,_,_,1,_,1,_\n_TerrainDeformRandom_Category=TC_NOTHING\n\nGetLastCreatedTerrainDeformation=1,0,terraindeformation\n_GetLastCreatedTerrainDeformation_Defaults=\n_GetLastCreatedTerrainDeformation_Category=TC_LAST\n\n\n// returns terraintype\nGetTerrainType=1,1,terraintype,real,real\n_GetTerrainType_Defaults=0,0\n_GetTerrainType_Category=TC_ENVIRONMENT\n\nGetTerrainTypeBJ=1,1,terraintype,location\n_GetTerrainTypeBJ_Defaults=_\n_GetTerrainTypeBJ_Category=TC_ENVIRONMENT\n\n\n// returns sound\nGetLastPlayedSound=0,1,sound\n_GetLastPlayedSound_Defaults=\n_GetLastPlayedSound_Category=TC_LAST\n\nYDWEGetSoundByInteger=0,1,sound,integer,integer\n_YDWEGetSoundByInteger_Limits=0,_,0,_\n_YDWEGetSoundByInteger_Category=TC_YDLD\n\nYDWEGetSoundByString=0,1,sound,string,string\n_YDWEGetSoundByString_Category=TC_YDLD\n\n// returns musicfile\nGetLastPlayedMusic=0,1,musicfile\n_GetLastPlayedMusic_Defaults=\n_GetLastPlayedMusic_Category=TC_LAST\n\n\n// returns quest\nCreateQuest=0,1,quest\n_CreateQuest_Category=TC_QUEST\n\nYDWECreateQuest=0,1,quest,questtypeoption,StringExt,StringExt,imagefile\n_YDWECreateQuest_Defaults=QuestTypeReqDiscovered,_,_,\"ReplaceableTextures\\CommandButtons\\BTNAmbush.blp\"\n_YDWECreateQuest_Limits=_,_,_,24,_,_,_,_\n_YDWECreateQuest_Category=TC_QUEST\n_YDWECreateQuest_ScriptName=CreateQuestBJ\n\nGetLastCreatedQuestBJ=0,1,quest\n_GetLastCreatedQuestBJ_Defaults=\n_GetLastCreatedQuestBJ_Category=TC_LAST\n\nYDWEGetQuestByInteger=0,1,quest,integer,integer\n_YDWEGetQuestByInteger_Limits=0,_,0,_\n_YDWEGetQuestByInteger_Category=TC_YDLD\n\nYDWEGetQuestByString=0,1,quest,string,string\n_YDWEGetQuestByString_Category=TC_YDLD\n\n// returns questitem\nYDWECreateQuestItem=0,1,questitem,quest,StringExt\n_YDWECreateQuestItem_Defaults=GetLastCreatedQuestBJ,_\n_YDWECreateQuestItem_Category=TC_QUEST\n_YDWECreateQuestItem_ScriptName=CreateQuestItemBJ\n\nGetLastCreatedQuestItemBJ=0,1,questitem\n_GetLastCreatedQuestItemBJ_Defaults=\n_GetLastCreatedQuestItemBJ_Category=TC_LAST\n\n// returns defeatcondition\n\nGetLastCreatedDefeatConditionBJ=0,1,defeatcondition\n_GetLastCreatedDefeatConditionBJ_Defaults=\n_GetLastCreatedDefeatConditionBJ_Category=TC_LAST\n\nYDWEGetQuestItemByInteger=0,1,questitem,integer,integer\n_YDWEGetQuestItemByInteger_Limits=0,_,0,_\n_YDWEGetQuestItemByInteger_Category=TC_YDLD\n\nYDWEGetQuestItemByString=0,1,questitem,string,string\n_YDWEGetQuestItemByString_Category=TC_YDLD\n\n// returns dialog\nDialogCreate=0,1,dialog\n_DialogCreate_Category=TC_DIALOG\n\nGetClickedDialogBJ=0,1,dialog\n_GetClickedDialogBJ_Defaults=\n_GetClickedDialogBJ_Category=TC_EVENTRESPONSE\n_GetClickedDialogBJ_ScriptName=GetClickedDialog\n\nYDWEGetDialogByInteger=0,1,dialog,integer,integer\n_YDWEGetDialogByInteger_Limits=0,_,0,_\n_YDWEGetDialogByInteger_Category=TC_YDLD\n\nYDWEGetDialogByString=0,1,dialog,string,string\n_YDWEGetDialogByString_Category=TC_YDLD\n\n// returns button\nDialogAddButton=0,1,button,dialog,StringExt,hotkeyint\n_DialogAddButton_Defaults=_Defaults=GetClickedDialogBJ,_,HotKeyNull\n_DialogAddButton_Category=TC_NOTHING\n\nGetLastCreatedButtonBJ=0,1,button\n_GetLastCreatedButtonBJ_Defaults=\n_GetLastCreatedButtonBJ_Category=TC_LAST\n\nGetClickedButtonBJ=0,1,button\n_GetClickedButtonBJ_Defaults=\n_GetClickedButtonBJ_Category=TC_EVENTRESPONSE\n_GetClickedButtonBJ_ScriptName=GetClickedButton\n\nYDWEGetButtonByInteger=0,1,button,integer,integer\n_YDWEGetButtonByInteger_Limits=0,_,0,_\n_YDWEGetButtonByInteger_Category=TC_YDLD\n\nYDWEGetButtonByString=0,1,button,string,string\n_YDWEGetButtonByString_Category=TC_YDLD\n\n// returns leaderboard\nCreateLeaderboard=0,1,leaderboard\n_CreateLeaderboard_Category=TC_NOTHING\n\nGetLastCreatedLeaderboard=0,1,leaderboard\n_GetLastCreatedLeaderboard_Defaults=\n_GetLastCreatedLeaderboard_Category=TC_LAST\n\nYDWEGetLeaderboardByInteger=0,1,leaderboard,integer,integer\n_YDWEGetLeaderboardByInteger_Limits=0,_,0,_\n_YDWEGetLeaderboardByInteger_Category=TC_YDLD\n\nYDWEGetLeaderboardByString=0,1,leaderboard,string,string\n_YDWEGetLeaderboardByString_Category=TC_YDLD\n\nPlayerGetLeaderboardBJ=0,1,leaderboard,player\n_PlayerGetLeaderboardBJ_Defaults=Player00\n_PlayerGetLeaderboardBJ_Category=TC_NOTHING\n_PlayerGetLeaderboardBJ_ScriptName=PlayerGetLeaderboard\n\n\n// returns multiboard\nCreateMultiboard=1,0,multiboard\n_CreateMultiboard_Defaults=\n_CreateMultiboard_Category=TC_NOTHING\n\nGetLastCreatedMultiboard=1,0,multiboard\n_GetLastCreatedMultiboard_Defaults=\n_GetLastCreatedMultiboard_Category=TC_LAST\n\nYDWEGetMultiboardByInteger=0,1,multiboard,integer,integer\n_YDWEGetMultiboardByInteger_Category=TC_YDLD\n\nYDWEGetMultiboardByString=0,1,multiboard,string,string\n_YDWEGetMultiboardByString_Category=TC_YDLD\n\n// returns multiboarditem\nMultiboardGetItem=1,0,multiboarditem,multiboard,integer,integer\n_MultiboardGetItem_Defaults=bj_lastCreatedMultiboard,0,0\n_MultiboardGetItem_Category=TC_NOTHING\n\nYDWEGetMultiboardItemByInteger=0,1,multiboarditem,integer,integer\n_YDWEGetMultiboardItemByInteger_Category=TC_YDLD\n\nYDWEGetMultiboardItemByString=0,1,multiboarditem,string,string\n_YDWEGetMultiboardItemByString_Category=TC_YDLD\n\n// returns timer\nCreateTimer=0,1,timer\n_CreateTimer_Category=TC_NOTHING\n\nGetLastCreatedTimerBJ=0,1,timer\n_GetLastCreatedTimerBJ_Defaults=\n_GetLastCreatedTimerBJ_Category=TC_LAST\n\nYDWEGetTimerByInteger=0,1,timer,integer,integer\n_YDWEGetTimerByInteger_Limits=0,_,0,_\n_YDWEGetTimerByInteger_Category=TC_YDLD\n\nYDWEGetTimerByString=0,1,timer,string,string\n_YDWEGetTimerByString_Category=TC_YDLD\n\nGetExpiredTimer=0,1,timer\n_GetExpiredTimer_Defaults=\n_GetExpiredTimer_Category=TC_EVENTRESPONSE\n\nYDWERemoveAttackWaveReturnTimer=0,1,timer\n_YDWERemoveAttackWaveReturnTimer_Defaults=\n_YDWERemoveAttackWaveReturnTimer_Category=TC_NOTHING\n\n            =0,1,timer,scriptcode\n_            _Defaults=_\n_            _Category=TC_NOTHING\n\n// returns timerdialog\nGetLastCreatedTimerDialogBJ=0,1,timerdialog\n_GetLastCreatedTimerDialogBJ_Defaults=\n_GetLastCreatedTimerDialogBJ_Category=TC_LAST\n\nYDWEGetTimerDialogByInteger=0,1,timerdialog,integer,integer\n_YDWEGetTimerDialogByInteger_Limits=0,_,0,_\n_YDWEGetTimerDialogByInteger_Category=TC_YDLD\n\nYDWEGetTimerDialogByString=0,1,timerdialog,string,string\n_YDWEGetTimerDialogByString_Category=TC_YDLD\n\n// returns gamecache\nInitGameCache=0,1,gamecache,string\n_InitGameCache_Defaults=\"MapName.w3v\"\n_InitGameCache_Category=TC_GAMECACHE\n\nGetLastCreatedGameCacheBJ=0,1,gamecache\n_GetLastCreatedGameCacheBJ_Defaults=\n_GetLastCreatedGameCacheBJ_Category=TC_LAST\n\n\n// returns trackable\nCreateTrackable=0,1,trackable,modelfile,real,real,real\n_CreateTrackable_Defaults=\"Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl\",0,0,0\n_CreateTrackable_Category=TC_NOTHING\n\nGetTriggeringTrackable=0,1,trackable\n_GetTriggeringTrackable_Defaults=\n_GetTriggeringTrackable_Category=TC_EVENTRESPONSE\n\nYDWEGetTrackableByInteger=0,1,trackable,integer,integer\n_YDWEGetTrackableByInteger_Limits=0,_,0,_\n_YDWEGetTrackableByInteger_Category=TC_YDLD\n\nYDWEGetTrackableByString=0,1,trackable,string,string\n_YDWEGetTrackableByString_Category=TC_YDLD\n\n// returns hashtable\n\n              =0,1,hashtable,scriptcode\n_              _Defaults=_\n_              _Category=TC_NOTHING\n\nYDWEInitHashtable=1,0,hashtable\n_YDWEInitHashtable_Defaults=\n_YDWEInitHashtable_Category=TC_YDFC\n\nGetLastCreatedHashtableBJ=0,1,hashtable\n_GetLastCreatedHashtableBJ_Defaults=\n_GetLastCreatedHashtableBJ_Category=TC_LAST\n\nLoadHashtableHandle=0,1,hashtable,hashtable,integer,integer\n_LoadHashtableHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadHashtableHandle_Category=TC_LAST\n\n\n// returns texttag\nCreateTextTag=1,0,texttag\n_CreateTextTag_Category=TC_NOTHING\n\nGetLastCreatedTextTag=1,0,texttag\n_GetLastCreatedTextTag_Defaults=\n_GetLastCreatedTextTag_Category=TC_LAST\n\nYDWEGetTextTagByInteger=0,1,texttag,integer,integer\n_YDWEGetTextTagByInteger_Limits=0,_,0,_\n_YDWEGetTextTagByInteger_Category=TC_YDLD\n\nYDWEGetTextTagByString=0,1,texttag,string,string\n_YDWEGetTextTagByString_Category=TC_YDLD\n\n// Hashtable\n\nLoadPlayerHandleBJ=0,1,player,integer,integer,hashtable\n_LoadPlayerHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadPlayerHandleBJ_Category=TC_HASHTABLE\n\nLoadPlayerHandle=0,1,player,hashtable,integer,integer\n_LoadPlayerHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadPlayerHandle_Category=TC_HASHTABLE\n\nLoadWidgetHandleBJ=0,1,widget,integer,integer,hashtable\n_LoadWidgetHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadWidgetHandleBJ_Category=TC_HASHTABLE\n\nLoadWidgetHandle=0,1,widget,hashtable,integer,integer\n_LoadWidgetHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadWidgetHandle_Category=TC_HASHTABLE\n\nLoadDestructableHandleBJ=0,1,destructable,integer,integer,hashtable\n_LoadDestructableHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadDestructableHandleBJ_Category=TC_HASHTABLE\n\nLoadDestructableHandle=0,1,destructable,hashtable,integer,integer\n_LoadDestructableHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadDestructableHandle_Category=TC_HASHTABLE\n\nLoadItemHandleBJ=0,1,item,integer,integer,hashtable\n_LoadItemHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadItemHandleBJ_Category=TC_HASHTABLE\n\nLoadItemHandle=0,1,item,hashtable,integer,integer\n_LoadItemHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadItemHandle_Category=TC_HASHTABLE\n\nLoadUnitHandleBJ=0,1,unit,integer,integer,hashtable\n_LoadUnitHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadUnitHandleBJ_Category=TC_HASHTABLE\n\nLoadUnitHandle=0,1,unit,hashtable,integer,integer\n_LoadUnitHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadUnitHandle_Category=TC_HASHTABLE\n\nYDWELoadAbilityHandleBJ=0,1,abilcode,integer,integer,hashtable\n_YDWELoadAbilityHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_YDWELoadAbilityHandleBJ_Category=TC_HASHTABLE\n\nYDWELoadAbilityHandle=0,1,abilcode,hashtable,integer,integer\n_YDWELoadAbilityHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_YDWELoadAbilityHandle_Category=TC_HASHTABLE\n\nLoadTimerHandleBJ=0,1,timer,integer,integer,hashtable\n_LoadTimerHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTimerHandleBJ_Category=TC_HASHTABLE\n\nLoadTimerHandle=0,1,timer,hashtable,integer,integer\n_LoadTimerHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTimerHandle_Category=TC_HASHTABLE\n\n//LoadTriggerRegionHandleBJ=0,1,region,integer,integer,hashtable\n//_LoadTriggerRegionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadTriggerRegionHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerHandleBJ=0,1,trigger,integer,integer,hashtable\n_LoadTriggerHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerHandle=0,1,trigger,hashtable,integer,integer\n_LoadTriggerHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTriggerHandle_Category=TC_HASHTABLE\n\nLoadTriggerConditionHandleBJ=0,1,triggercondition,integer,integer,hashtable\n_LoadTriggerConditionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerConditionHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerConditionHandle=0,1,triggercondition,hashtable,integer,integer\n_LoadTriggerConditionHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTriggerConditionHandle_Category=TC_HASHTABLE\n\nLoadTriggerActionHandleBJ=0,1,triggeraction,integer,integer,hashtable\n_LoadTriggerActionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerActionHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerActionHandle=0,1,triggeraction,hashtable,integer,integer\n_LoadTriggerActionHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTriggerActionHandle_Category=TC_HASHTABLE\n\nLoadTriggerEventHandleBJ=0,1,event,integer,integer,hashtable\n_LoadTriggerEventHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTriggerEventHandleBJ_Category=TC_HASHTABLE\n\nLoadTriggerEventHandle=0,1,event,hashtable,integer,integer\n_LoadTriggerEventHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTriggerEventHandle_Category=TC_HASHTABLE\n\nLoadForceHandleBJ=0,1,force,integer,integer,hashtable\n_LoadForceHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadForceHandleBJ_Category=TC_HASHTABLE\n\nLoadForceHandle=0,1,force,hashtable,integer,integer\n_LoadForceHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadForceHandle_Category=TC_HASHTABLE\n\nLoadGroupHandleBJ=0,1,group,integer,integer,hashtable\n_LoadGroupHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadGroupHandleBJ_Category=TC_HASHTABLE\n\nLoadGroupHandle=0,1,group,hashtable,integer,integer\n_LoadGroupHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadGroupHandle_Category=TC_HASHTABLE\n\nLoadLocationHandleBJ=0,1,location,integer,integer,hashtable\n_LoadLocationHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadLocationHandleBJ_Category=TC_HASHTABLE\n\nLoadLocationHandle=0,1,location,hashtable,integer,integer\n_LoadLocationHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadLocationHandle_Category=TC_HASHTABLE\n\nLoadRegionHandleBJ=0,1,region,integer,integer,hashtable\n_LoadRegionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadRegionHandleBJ_Category=TC_HASHTABLE\n\nLoadRegionHandle=0,1,region,hashtable,integer,integer\n_LoadRegionHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadRegionHandle_Category=TC_HASHTABLE\n\nLoadRectHandleBJ=0,1,rect,integer,integer,hashtable\n_LoadRectHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadRectHandleBJ_Category=TC_HASHTABLE\n\nLoadRectHandle=0,1,rect,hashtable,integer,integer\n_LoadRectHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadRectHandle_Category=TC_HASHTABLE\n\nLoadBooleanExprHandleBJ=0,1,boolexpr,integer,integer,hashtable\n_LoadBooleanExprHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadBooleanExprHandleBJ_Category=TC_HASHTABLE\n\nLoadBooleanExprHandle=0,1,boolexpr,hashtable,integer,integer\n_LoadBooleanExprHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadBooleanExprHandle_Category=TC_HASHTABLE\n\n//LoadConditionFuncHandleBJ=0,1,conditionfunc,integer,integer,hashtable\n//_LoadConditionFuncHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadConditionFuncHandleBJ_Category=TC_HASHTABLE\n\n//LoadFilterFuncHandleBJ=0,1,filterfunc,integer,integer,hashtable\n//_LoadFilterFuncHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadFilterFuncHandleBJ_Category=TC_HASHTABLE\n\nLoadSoundHandleBJ=0,1,sound,integer,integer,hashtable\n_LoadSoundHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadSoundHandleBJ_Category=TC_HASHTABLE\n\nLoadSoundHandle=0,1,sound,hashtable,integer,integer\n_LoadSoundHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadSoundHandle_Category=TC_HASHTABLE\n\n//LoadRaceHandleBJ=0,1,race,integer,integer,hashtable\n//_LoadRaceHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadRaceHandleBJ_Category=TC_HASHTABLE\n\nLoadEffectHandleBJ=0,1,effect,integer,integer,hashtable\n_LoadEffectHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadEffectHandleBJ_Category=TC_HASHTABLE\n\nLoadEffectHandle=0,1,effect,hashtable,integer,integer\n_LoadEffectHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadEffectHandle_Category=TC_HASHTABLE\n\nLoadUnitPoolHandleBJ=0,1,unitpool,integer,integer,hashtable\n_LoadUnitPoolHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadUnitPoolHandleBJ_Category=TC_HASHTABLE\n\nLoadUnitPoolHandle=0,1,unitpool,hashtable,integer,integer\n_LoadUnitPoolHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadUnitPoolHandle_Category=TC_HASHTABLE\n\nLoadItemPoolHandleBJ=0,1,itempool,integer,integer,hashtable\n_LoadItemPoolHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadItemPoolHandleBJ_Category=TC_HASHTABLE\n\nLoadItemPoolHandle=0,1,itempool,hashtable,integer,integer\n_LoadItemPoolHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadItemPoolHandle_Category=TC_HASHTABLE\n\nLoadQuestHandleBJ=0,1,quest,integer,integer,hashtable\n_LoadQuestHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadQuestHandleBJ_Category=TC_HASHTABLE\n\nLoadQuestHandle=0,1,quest,hashtable,integer,integer\n_LoadQuestHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadQuestHandle_Category=TC_HASHTABLE\n\nLoadQuestItemHandleBJ=0,1,questitem,integer,integer,hashtable\n_LoadQuestItemHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadQuestItemHandleBJ_Category=TC_HASHTABLE\n\nLoadQuestItemHandle=0,1,questitem,hashtable,integer,integer\n_LoadQuestItemHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadQuestItemHandle_Category=TC_HASHTABLE\n\nLoadDefeatConditionHandleBJ=0,1,defeatcondition,integer,integer,hashtable\n_LoadDefeatConditionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadDefeatConditionHandleBJ_Category=TC_HASHTABLE\n\nLoadDefeatConditionHandle=0,1,defeatcondition,hashtable,integer,integer\n_LoadDefeatConditionHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadDefeatConditionHandle_Category=TC_HASHTABLE\n\nLoadTimerDialogHandleBJ=0,1,timerdialog,integer,integer,hashtable\n_LoadTimerDialogHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTimerDialogHandleBJ_Category=TC_HASHTABLE\n\nLoadTimerDialogHandle=0,1,timerdialog,hashtable,integer,integer\n_LoadTimerDialogHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTimerDialogHandle_Category=TC_HASHTABLE\n\nLoadLeaderboardHandleBJ=0,1,leaderboard,integer,integer,hashtable\n_LoadLeaderboardHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadLeaderboardHandleBJ_Category=TC_HASHTABLE\n\nLoadLeaderboardHandle=0,1,leaderboard,hashtable,integer,integer\n_LoadLeaderboardHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadLeaderboardHandle_Category=TC_HASHTABLE\n\nLoadMultiboardHandleBJ=0,1,multiboard,integer,integer,hashtable\n_LoadMultiboardHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadMultiboardHandleBJ_Category=TC_HASHTABLE\n\nLoadMultiboardHandle=0,1,multiboard,hashtable,integer,integer\n_LoadMultiboardHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadMultiboardHandle_Category=TC_HASHTABLE\n\nLoadMultiboardItemHandleBJ=0,1,multiboarditem,integer,integer,hashtable\n_LoadMultiboardItemHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadMultiboardItemHandleBJ_Category=TC_HASHTABLE\n\nLoadMultiboardItemHandle=0,1,multiboarditem,hashtable,integer,integer\n_LoadMultiboardItemHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadMultiboardItemHandle_Category=TC_HASHTABLE\n\nLoadTrackableHandleBJ=0,1,trackable,integer,integer,hashtable\n_LoadTrackableHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTrackableHandleBJ_Category=TC_HASHTABLE\n\nLoadTrackableHandle=0,1,trackable,hashtable,integer,integer\n_LoadTrackableHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTrackableHandle_Category=TC_HASHTABLE\n\nLoadDialogHandleBJ=0,1,dialog,integer,integer,hashtable\n_LoadDialogHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadDialogHandleBJ_Category=TC_HASHTABLE\n\nLoadDialogHandle=0,1,dialog,hashtable,integer,integer\n_LoadDialogHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadDialogHandle_Category=TC_HASHTABLE\n\nLoadButtonHandleBJ=0,1,button,integer,integer,hashtable\n_LoadButtonHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadButtonHandleBJ_Category=TC_HASHTABLE\n\nLoadButtonHandle=0,1,button,hashtable,integer,integer\n_LoadButtonHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadButtonHandle_Category=TC_HASHTABLE\n\n//LoadVersionHandleBJ=0,1,version,integer,integer,hashtable\n//_LoadVersionHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadVersionHandleBJ_Category=TC_HASHTABLE\n\n//LoadItemTypeHandleBJ=0,1,itemtype,integer,integer,hashtable\n//_LoadItemTypeHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n//_LoadItemTypeHandleBJ_Category=TC_HASHTABLE\n\nLoadTextTagHandleBJ=0,1,texttag,integer,integer,hashtable\n_LoadTextTagHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadTextTagHandleBJ_Category=TC_HASHTABLE\n\nLoadTextTagHandle=0,1,texttag,hashtable,integer,integer\n_LoadTextTagHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadTextTagHandle_Category=TC_HASHTABLE\n\nLoadLightningHandleBJ=0,1,lightning,integer,integer,hashtable\n_LoadLightningHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadLightningHandleBJ_Category=TC_HASHTABLE\n\nLoadLightningHandle=0,1,lightning,hashtable,integer,integer\n_LoadLightningHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadLightningHandle_Category=TC_HASHTABLE\n\nLoadImageHandleBJ=0,1,image,integer,integer,hashtable\n_LoadImageHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadImageHandleBJ_Category=TC_HASHTABLE\n\nLoadImageHandle=0,1,image,hashtable,integer,integer\n_LoadImageHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadImageHandle_Category=TC_HASHTABLE\n\nLoadUbersplatHandleBJ=0,1,ubersplat,integer,integer,hashtable\n_LoadUbersplatHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadUbersplatHandleBJ_Category=TC_HASHTABLE\n\nLoadUbersplatHandle=0,1,ubersplat,hashtable,integer,integer\n_LoadUbersplatHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadUbersplatHandle_Category=TC_HASHTABLE\n\nLoadFogStateHandleBJ=0,1,fogstate,integer,integer,hashtable\n_LoadFogStateHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadFogStateHandleBJ_Category=TC_HASHTABLE\n\nLoadFogStateHandle=0,1,fogstate,hashtable,integer,integer\n_LoadFogStateHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadFogStateHandle_Category=TC_HASHTABLE\n\nLoadFogModifierHandleBJ=0,1,fogmodifier,integer,integer,hashtable\n_LoadFogModifierHandleBJ_Defaults=_,_,GetLastCreatedHashtableBJ\n_LoadFogModifierHandleBJ_Category=TC_HASHTABLE\n\nLoadFogModifierHandle=0,1,fogmodifier,hashtable,integer,integer\n_LoadFogModifierHandle_Defaults=GetLastCreatedHashtableBJ,_,_\n_LoadFogModifierHandle_Category=TC_HASHTABLE\n\nYDWEGetUnitID=0,1,integer,unit\n_YDWEGetUnitID_Defaults=GetTriggerUnit\n_YDWEGetUnitID_Category=TC_YDID\n\nYDWEGetPlayerID=0,1,integer,player\n_YDWEGetPlayerID_Defaults=GetTriggerPlayer\n_YDWEGetPlayerID_Category=TC_YDID\n\nYDWEGetItemID=0,1,integer,item\n_YDWEGetItemID_Defaults=GetManipulatedItem\n_YDWEGetItemID_Category=TC_YDID\n\nYDWEGetTimerID=0,1,integer,timer\n_YDWEGetTimerID_Defaults=GetLastCreatedTimerBJ\n_YDWEGetTimerID_Category=TC_YDID\n\nYDWEGetTriggerID=0,1,integer,trigger\n_YDWEGetTriggerID_Defaults=GetTriggeringTrigger\n_YDWEGetTriggerID_Category=TC_YDID\n\nYDWEGetGroupID=0,1,integer,group\n_YDWEGetGroupID_Defaults=GetLastCreatedGroup\n_YDWEGetGroupID_Category=TC_YDID\n\nYDWEGetLocationID=0,1,integer,location\n_YDWEGetLocationID_Category=TC_YDID\n\nYDWEGetUnitTypeID=0,1,integer,unitcode\n_YDWEGetUnitTypeID_Defaults=hfoo\n_YDWEGetUnitTypeID_Category=TC_YDID\n\nYDWEGetAbilityTypeID=0,1,integer,abilcode\n_YDWEGetAbilityTypeID_Defaults=Aloc\n_YDWEGetAbilityTypeID_Category=TC_YDID\n\nYDWEGetItemTypeID=0,1,integer,itemcode\n_YDWEGetItemTypeID_Defaults=spsh\n_YDWEGetItemTypeID_Category=TC_YDID\n\nYDWEGetMultiboardID=0,1,integer,multiboard\n_YDWEGetMultiboardID_Defaults=GetLastCreatedMultiboard\n_YDWEGetMultiboardID_Category=TC_YDID\n\nYDWEGetMultiboardItemID=0,1,integer,multiboarditem\n_YDWEGetMultiboardItemID_Category=TC_YDID\n\nYDWEGetTextTagID=0,1,integer,texttag\n_YDWEGetTextTagID_Defaults=GetLastCreatedTextTag\n_YDWEGetTextTagID_Category=TC_YDID\n\nYDWEGetLightningID=0,1,integer,lightning\n_YDWEGetLightningID_Defaults=bj_lastCreatedLightning\n_YDWEGetLightningID_Category=TC_YDID\n\nYDWEGetRegionID=0,1,integer,region\n_YDWEGetRegionID_Defaults=GetTriggeringRegion\n_YDWEGetRegionID_Category=TC_YDID\n\nYDWEGetRectID=0,1,integer,rect\n_YDWEGetRectID_Defaults=GetPlayableMapRect\n_YDWEGetRectID_Category=TC_YDID\n\nYDWEGetLeaderboardID=0,1,integer,leaderboard\n_YDWEGetLeaderboardID_Defaults=DestroyLeaderboard\n_YDWEGetLeaderboardID_Category=TC_YDID\n\nYDWEGetEffectID=0,1,integer,effect\n_YDWEGetEffectID_Defaults=GetLastCreatedEffectBJ\n_YDWEGetEffectID_Category=TC_YDID\n\nYDWEGetDestructableID=0,1,integer,destructable\n_YDWEGetDestructableID_Defaults=GetLastCreatedDestructable\n_YDWEGetDestructableID_Category=TC_YDID\n\nYDWEGetTriggerConditionID=0,1,integer,triggercondition\n_YDWEGetTriggerConditionID_Defaults=_\n_YDWEGetTriggerConditionID_Category=TC_YDID\n\nYDWEGetTriggerActionID=0,1,integer,triggeraction\n_YDWEGetTriggerActionID_Defaults=_\n_YDWEGetTriggerActionID_Category=TC_YDID\n\nYDWEGetTriggerEventID=0,1,integer,event\n_YDWEGetTriggerEventID_Defaults=_\n_YDWEGetTriggerEventID_Category=TC_YDID\n\nYDWEGetForceID=0,1,integer,force\n_YDWEGetForceID_Defaults=_\n_YDWEGetForceID_Category=TC_YDID\n\nYDWEGetBoolexprID=0,1,integer,boolexpr\n_YDWEGetBoolexprID_Defaults=_\n_YDWEGetBoolexprID_Category=TC_YDID\n\nGetStoredBooleanBJ=0,1,boolean,string,string,gamecache\n_GetStoredBooleanBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredBooleanBJ_Category=TC_YDHIDE\n\nGetStoredIntegerBJ=0,1,integer,string,string,gamecache\n_GetStoredIntegerBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredIntegerBJ_Category=TC_YDHIDE\n\nGetStoredRealBJ=0,1,real,string,string,gamecache\n_GetStoredRealBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredRealBJ_Category=TC_YDHIDE\n\nGetStoredStringBJ=1,0,string,string,string,gamecache\n_GetStoredStringBJ_Defaults=_,\"Category\",GetLastCreatedGameCacheBJ\n_GetStoredStringBJ_Category=TC_YDHIDE\n\n\n\n//***************************************************************************\n[DefaultTriggerCategories]\n// Defines categories to be automatically added to new maps\nNumCategories=1\n\nCategory01=\"欢迎使用YDWE\"\n\n\n\n//***************************************************************************\n[DefaultTriggers]\n\nNumTriggers=1\n\nTrigger01Name=\"简介\"\nTrigger01Comment=\nTrigger01Category=1\nTrigger01Events=0\nTrigger01Conditions=0\nTrigger01Actions=5\nTrigger01Action01=CommentString,\"YDWE是《魔兽争霸III》地图编辑器的一个增强Mod。\"\nTrigger01Action02=CommentString,\"　　你可以从www.ydwe.net获取最新的YDWE。\"\nTrigger01Action03=CommentString,\"　　你可以由YDWE附带的演示地图开始，快速了解YDWE的功能。\"\nTrigger01Action04=CommentString,\"　　当你的地图意外损坏时，你可以在backups目录找到你最近26次保存的地图。\"\nTrigger01Action05=CommentString,\"　　当你的YDWE不能正常工作时，你可以前往www.ydwe.net联系我们。\"\nTrigger01Action06=CommentString,\"　　筒隐月子俺の嫁!!!(by 最萌小汐)。\"\n"
  },
  {
    "path": "clients/weu/components/weuchanges.js",
    "content": "import Component from '../../shared/component';\nimport { addTextToRow } from '../../shared/domutils';\n\nexport default class WeuChanges extends Component {\n  constructor(converter, changes) {\n    super({ tagName: 'table', className: 'hidden' });\n\n    let tbody = this.container.createTBody();\n    let thead = this.container.createTHead();\n\n    let header = thead.insertRow();\n\n    header.className = 'header';\n\n    addTextToRow(header, '#');\n    addTextToRow(header, 'Reason');\n    addTextToRow(header, 'Change');\n    addTextToRow(header, 'Stack');\n\n    for (let i = 0, l = changes.length; i < l; i++) {\n      let change = changes[i];\n\n      let row = tbody.insertRow();\n\n      row.className = change.type;\n\n      addTextToRow(row, `${i + 1}`);\n      addTextToRow(row, change.reason);\n      addTextToRow(row, change.data);\n      addTextToRow(row, change.stack);\n    }\n\n    converter.changesElement.appendChild(this.container);\n  }\n}\n"
  },
  {
    "path": "clients/weu/components/weuconverter.js",
    "content": "\nimport { extname } from '../../../src/common/path';\nimport MpqArchive from '../../../src/parsers/mpq/archive';\nimport { TriggerData } from '../../../src/parsers/w3x/wtg/triggerdata';\nimport War3Map from '../../../src/parsers/w3x/map';\nimport convertWeu from '../../../src/utils/w3x/weu/weu';\nimport Component from '../../shared/component';\nimport { createElement } from '../../shared/domutils';\nimport { aFrame } from '../../shared/utils';\nimport localOrHive from '../../shared/localorhive';\nimport WeuMeta from './weumeta';\n\nexport default class WeuConverter extends Component {\n  constructor(parentElement) {\n    super({ className: 'client' });\n\n    this.triggerData = new TriggerData();\n    this.weTriggerData = new TriggerData();\n    this.ready = false;\n\n    this.metaElement = createElement({ className: 'meta', container: this.container });\n    this.metaStack = [this.metaElement];\n    this.visibleMeta = null;\n\n    this.changesElement = createElement({ className: 'changes', container: this.container });\n    this.visibleChanges = null;\n\n    this.load();\n\n    parentElement.appendChild(this.container);\n  }\n\n  async load() {\n    this.text('Fetching files: \"UI\\\\TriggerData.txt\", \"TriggerDataWEU.txt\", \"TriggerDataYDWE.txt\", \"TriggerDataCustom.txt\", \"Scripts\\\\common.j\"');\n    this.text('Please wait...');\n\n    let [blzResponse, commonjResponse, weuResponse, ydweResponse, customResponse] = await Promise.all([\n      fetch(localOrHive('UI\\\\TriggerData.txt')),\n      fetch(localOrHive('Scripts\\\\common.j')),\n      fetch('TriggerDataWEU.txt'),\n      fetch('TriggerDataYDWE.txt'),\n      fetch('TriggerDataCustom.txt'),\n    ]);\n\n    let [blzText, commonjText, weuText, ydweText, customText] = await Promise.all([\n      blzResponse.text(),\n      commonjResponse.text(),\n      weuResponse.text(),\n      ydweResponse.text(),\n      customResponse.text(),\n    ]);\n\n    this.triggerData.addTriggerData(blzText); // WE trigger data\n    this.triggerData.addJassFunctions(commonjText); // natives from common.j\n    this.triggerData.addTriggerData(weuText, true); // WEU trigger data\n    this.triggerData.addTriggerData(ydweText, true); // YDWE trigger data\n    this.triggerData.addTriggerData(customText, true);\n\n    this.weTriggerData.addTriggerData(blzText); // WE trigger data\n\n    this.ready = true;\n\n    this.text('Ready, drag and drop a TFT map (*.w3x) or campaign (*.w3n) anywhere on the page');\n  }\n\n  clear() {\n    this.metaElement.innerHTML = '';\n    this.changesElement.innerHTML = '';\n  }\n\n  indent() {\n    this.metaStack.unshift(createElement({ className: 'indent', container: this.metaStack[0] }));\n  }\n\n  deindent() {\n    this.metaStack.shift();\n  }\n\n  text(text) {\n    createElement({ textContent: text, container: this.metaStack[0] });\n\n    this.metaElement.scrollTo(0, 10000000);\n  }\n\n  error(text) {\n    createElement({ className: 'error', textContent: text, container: this.metaStack[0] });\n\n    this.metaElement.scrollTo(0, 10000000);\n  }\n\n  results(results) {\n    this.metaStack[0].appendChild((new WeuMeta(this, results)).container);\n\n    this.metaElement.scrollTo(0, 10000000);\n  }\n\n  showChanges(meta) {\n    if (this.visibleMeta) {\n      this.visibleMeta.changesToggle.toggle();\n    }\n\n    this.visibleMeta = meta;\n\n    meta.changes.show();\n  }\n\n  hideChanges() {\n    if (this.visibleMeta) {\n      this.visibleMeta.changes.hide();\n\n      this.visibleMeta = null;\n    }\n  }\n\n  convertMap(name, buffer) {\n    this.text(`Parsing ${name}`);\n\n    let map = new War3Map();\n\n    try {\n      map.load(buffer);\n    } catch (e) {\n      this.error(`Failed to parse: ${e}`);\n      this.error('This map is most likely protected/optimized');\n\n      return;\n    }\n\n    let changesCount = 0;\n    let results = convertWeu(map, this.triggerData, this.weTriggerData);\n\n    this.indent();\n\n    if (results.ok) {\n      let changes = results.changes;\n\n      if (changes.length) {\n        changesCount = changes.length;\n\n        this.results(results);\n      } else {\n        this.text('Found nothing to convert');\n      }\n    } else {\n      this.error(results.error);\n    }\n\n    this.deindent();\n\n    return { parser: map, changes: changesCount };\n  }\n\n  async convertCampaign(name, buffer) {\n    this.text(`Parsing ${name}`);\n\n    let campaign = new MpqArchive();\n\n    try {\n      campaign.load(buffer);\n    } catch (e) {\n      this.error(`Failed to parse: ${e}`);\n      this.error('This campaign is most likely protected/optimized');\n\n      return;\n    }\n\n    this.text('Looking for maps');\n\n    let totalChanges = 0;\n    let changedMaps = 0;\n\n    for (let fileName of campaign.getFileNames()) {\n      if (extname(fileName) === '.w3x') {\n        this.indent();\n\n        let results = this.convertMap(fileName, campaign.get(fileName).arrayBuffer());\n\n        this.deindent();\n\n        if (results) {\n          totalChanges += results.changes;\n          changedMaps += 1;\n\n          campaign.set(fileName, results.parser.save());\n        }\n\n        await aFrame();\n      }\n    }\n\n    if (totalChanges) {\n      this.text(`Converted with ${totalChanges} changes in ${changedMaps} maps`);\n    } else {\n      this.text('Found nothing to convert');\n    }\n\n    return { parser: campaign, changes: totalChanges };\n  }\n\n  convertFile(file) {\n    if (this.ready && file) {\n      let name = file.name;\n      let ext = extname(name);\n      let isMap = ext === '.w3x';\n      let isCampaign = ext === '.w3n';\n\n      this.clear();\n\n      if (isMap || isCampaign) {\n        this.text(`Reading ${name}`);\n\n        let reader = new FileReader();\n\n        reader.addEventListener('loadend', async (e) => {\n          let buffer = e.target.result;\n          let results;\n\n          this.indent();\n\n          if (isMap) {\n            results = this.convertMap(name, buffer);\n          } else {\n            results = await this.convertCampaign(name, buffer);\n          }\n\n          this.deindent();\n\n          if (results && results.changes) {\n            name = `${name.slice(0, -4)}_no_weu${ext}`;\n\n            this.text(`Saving as ${name}`);\n\n            this.metaElement.scrollTo(0, 10000000);\n\n            saveAs(new Blob([results.parser.save().buffer], { type: 'application/octet-stream' }), name);\n          }\n        });\n\n        reader.readAsArrayBuffer(file);\n      } else {\n        this.error(`${name} is not a TFT map/campaign`);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/weu/components/weumeta.js",
    "content": "\nimport Component from '../../shared/component';\nimport Toggle from '../../shared/components/toggle';\nimport { createElement } from '../../shared/domutils';\nimport WeuChanges from './weuchanges';\n\nexport default class WeuMeta extends Component {\n  constructor(converter, results) {\n    super();\n\n    this.changes = null;\n    this.changesToggle = null;\n\n    if (results.ok) {\n      let changes = results.changes;\n\n      if (changes.length) {\n        createElement({ textContent: `Converted with ${changes.length} changes`, container: this.container });\n\n        this.changes = new WeuChanges(converter, changes);\n\n        this.changesToggle = new Toggle('Show the changes', 'Hide the changes', (e) => {\n          if (e.clicked) {\n            converter.showChanges(this);\n          } else {\n            converter.hideChanges();\n          }\n        }, { container: this.container });\n      } else {\n        createElement({ textContent: 'Found nothing to convert!', container: this.container });\n      }\n    } else {\n      createElement({ className: 'error', textContent: results.error, container: this.container });\n      createElement({ className: 'error', textContent: 'Did nothing due to errors', container: this.container });\n    }\n  }\n}\n"
  },
  {
    "path": "clients/weu/index.css",
    "content": "﻿html,\nbody {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n}\n\n.client {\n    display: grid;\n    width: 100%;\n    height: 100vh;\n    grid-auto-rows: auto;\n    grid-template-columns: auto 1fr;\n    grid-template-areas: \"meta changes\";\n    padding: 5px;\n    grid-gap: 5px;\n    box-sizing: border-box;\n}\n\n.meta {\n    grid-area: meta;\n\n    padding: 5px;\n\n    overflow-y: auto;\n}\n\n.changes {\n    grid-area: changes;\n\n    overflow-y: auto;\n}\n\ntable {\n    width: 100%;\n\n    border-spacing: 0;\n    border-collapse: collapse;\n    margin-top: 1px;\n    margin-bottom: 5px;\n}\n\ntd {\n    border: 1px solid black;\n    padding: 4px;\n}\n\n.error {\n    color: red;\n}\n\n.hidden {\n    display: none;\n}\n\n.indent {\n    margin-left: 1em;\n}\n\n.header {\n    background-color: #c5c5c5;\n}\n\n.inlinegui, .singletomultiple, .references {\n    background-color: #92d692;\n}\n\n.inlinecustomscript, .convertedtrigger, .generatedcallbacks {\n    background-color: #b9c1de;\n}\n\n.inlinepreset {\n    background-color: rgb(187, 187, 113);\n}\n\n.missingstring {\n    background-color: rgb(211, 105, 105);\n}\n\n.unknownsignature {\n    background-color: #eedddd;\n}\n"
  },
  {
    "path": "clients/weu/index.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n\n<head>\n    <title>WEU Converter</title>\n    <meta charset=\"utf-8\" />\n    <link href=\"index.css\" rel=\"stylesheet\">\n</head>\n\n<body>\n    <script src=\"../thirdparty/filesaver.js\"></script>\n    <script src=\"/clients/weu.min.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "clients/weu/index.js",
    "content": "import WeuConverter from './components/weuconverter';\n\nconst converter = new WeuConverter(document.body);\n\ndocument.addEventListener('dragover', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('dragend', e => {\n  e.preventDefault();\n});\n\ndocument.addEventListener('drop', e => {\n  e.preventDefault();\n\n  converter.convertFile(e.dataTransfer.files[0]);\n});\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"mdx-m3-viewer\",\n  \"version\": \"5.13.0\",\n  \"description\": \"A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.\",\n  \"main\": \"dist/cjs/index.js\",\n  \"types\": \"dist/cjs/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"webpack --mode=production\",\n    \"dev\": \"webpack -w --mode=development\",\n    \"serve\": \"webpack serve\",\n    \"prepublishOnly\": \"node clean.js && tsc && webpack --mode=production --env=umd\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/flowtsohg/mdx-m3-viewer.git\"\n  },\n  \"author\": \"Chananya Freiman\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/flowtsohg/mdx-m3-viewer/issues\"\n  },\n  \"homepage\": \"https://github.com/flowtsohg/mdx-m3-viewer#readme\",\n  \"dependencies\": {\n    \"fengari\": \"^0.1.4\",\n    \"gl-matrix\": \"3.3.0\",\n    \"pako\": \"^2.0.3\",\n    \"tga-js\": \"^1.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^12.12.17\",\n    \"@types/pako\": \"^1.0.2\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.30.0\",\n    \"@typescript-eslint/parser\": \"^4.30.0\",\n    \"eslint\": \"^7.29.0\",\n    \"ts-loader\": \"^9.2.3\",\n    \"typescript\": \"^4.3.5\",\n    \"webpack\": \"^5.0.0\",\n    \"webpack-cli\": \"^4.7.2\",\n    \"webpack-dev-server\": \"^3.11.2\"\n  }\n}"
  },
  {
    "path": "src/common/arrayunique.ts",
    "content": "/**\n * Returns an array that only contains unique values found in the source array.\n */\nexport default function unique<T>(a: T[]): T[] {\n  return a.reverse().filter((e, i, arr) => {\n    return arr.indexOf(e, i + 1) === -1;\n  }).reverse();\n}\n"
  },
  {
    "path": "src/common/audio.ts",
    "content": "let audioContext: OfflineAudioContext;\n\n// Some browsers don't have OfflineAudioContext or AudioContext.\nif (typeof OfflineAudioContext === 'function') {\n  audioContext = new OfflineAudioContext(1, 1, 48000);\n}\n\n/**\n * A context-less decodeAudioData().\n */\nexport async function decodeAudioData(buffer: ArrayBuffer): Promise<AudioBuffer | undefined> {\n  if (audioContext) {\n    return audioContext.decodeAudioData(buffer);\n  }\n\n  return;\n}\n"
  },
  {
    "path": "src/common/binarystream.ts",
    "content": "import { bytesOf } from './bytesof';\nimport { boundIndexOf } from './searches';\nimport { uint8ToInt8, uint8ToInt16, uint8ToInt32, uint8ToUint16, uint8ToUint32, uint8ToFloat32, uint8ToFloat64, int8ToUint8, int16ToUint8, int32ToUint8, uint16ToUint8, uint32ToUint8, float32ToUint8, float64ToUint8 } from './typecast';\nimport { decodeUtf8, encodeUtf8 } from './utf8';\n\n// Memory for all of the xxxToUint type casts.\nconst uint8 = new Uint8Array(8);\n\n/**\n * A binary stream.\n */\nexport default class BinaryStream {\n  buffer: ArrayBuffer;\n  uint8array: Uint8Array;\n  index = 0;\n  byteLength: number;\n  remaining: number;\n\n  constructor(buffer: ArrayBuffer | Uint8Array, byteOffset?: number, byteLength?: number) {\n    const bytes = bytesOf(buffer);\n\n    // For browsers not supporting the spec.\n    // Once upon a time I reported this issue on the Firefox tracker.\n    // Seems like Safari needs an issue report too.\n    byteOffset = byteOffset || 0;\n    byteLength = byteLength || bytes.length;\n\n    this.buffer = buffer;\n    this.uint8array = bytes.subarray(byteOffset, byteOffset + byteLength);\n    this.byteLength = byteLength;\n    this.remaining = byteLength;\n  }\n\n  /**\n   * Create a subreader of this reader, at its position, with the given byte length.\n   */\n  substream(byteLength: number): BinaryStream {\n    if (this.remaining < byteLength) {\n      throw new Error(`ByteStream: substream: want ${byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n\n    this.index += byteLength;\n\n    return new BinaryStream(this.uint8array.subarray(index, index + byteLength));\n  }\n\n  /**\n   * Skip a number of bytes.\n   */\n  skip(bytes: number): void {\n    if (this.remaining < bytes) {\n      throw new Error(`ByteStream: skip: premature end - want ${bytes} bytes but have ${this.remaining}`);\n    }\n\n    this.index += bytes;\n    this.remaining -= bytes;\n  }\n\n  /**\n   * Set the reader's index.\n   */\n  seek(index: number): void {\n    this.index = index;\n    this.remaining = this.byteLength - index;\n  }\n\n  /**\n   * Read a UTF8 string with the given number of bytes.\n   * \n   * The entire size will be read, however the string returned is NULL terminated in its memory block.\n   * \n   * For example, the MDX format has many strings that have a constant maximum size, where any bytes after the string are NULLs.\n   * Such strings will be loaded correctly given the maximum size.\n   */\n  read(bytes: number): string {\n    if (this.remaining < bytes) {\n      throw new Error(`ByteStream: read: premature end - want ${bytes} bytes but have ${this.remaining}`);\n    }\n\n    const uint8array = this.uint8array;\n    const start = this.index;\n    let end = boundIndexOf(uint8array, 0, start, bytes);\n\n    if (end === -1) {\n      end = start + bytes;\n    }\n\n    this.index += bytes;\n    this.remaining -= bytes;\n\n    return decodeUtf8(uint8array.subarray(start, end));\n  }\n\n  /**\n   * Read a UTF8 NULL terminated string.\n   */\n  readNull(): string {\n    if (this.remaining < 1) {\n      throw new Error(`ByteStream: readNull: premature end - want at least 1 byte but have 0`);\n    }\n\n    const uint8array = this.uint8array;\n    const start = this.index;\n    let end = uint8array.indexOf(0, start);\n\n    if (end === -1) {\n      end = uint8array.length - 1;\n    }\n\n    const bytes = end - start + 1;\n\n    this.index += bytes;\n    this.remaining -= bytes;\n\n    return decodeUtf8(uint8array.subarray(start, end));\n  }\n\n  /**\n   * Read a binary string with the given number of bytes.\n   */\n  readBinary(bytes: number): string {\n    if (this.remaining < bytes) {\n      throw new Error(`ByteStream: readBinary: premature end - want ${bytes} bytes but have ${this.remaining}`);\n    }\n\n    const uint8array = this.uint8array;\n    const index = this.index;\n    let data = '';\n\n    for (let i = 0; i < bytes; i++) {\n      data += String.fromCharCode(uint8array[index + i]);\n    }\n\n    this.index += bytes;\n    this.remaining -= bytes;\n\n    return data;\n  }\n\n  /**\n   * Read a 8 bit signed integer.\n   */\n  readInt8(): number {\n    if (this.remaining < 1) {\n      throw new Error(`ByteStream: readInt8: premature end - want 1 byte but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToInt8(uint8array[index]);\n\n    this.index += 1;\n    this.remaining -= 1;\n\n    return data;\n  }\n\n  /**\n   * Read a 16 bit signed integer.\n   */\n  readInt16(): number {\n    if (this.remaining < 2) {\n      throw new Error(`ByteStream: readInt16: premature end - want 2 bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToInt16(uint8array[index], uint8array[index + 1]);\n\n    this.index += 2;\n    this.remaining -= 2;\n\n    return data;\n  }\n\n  /**\n   * Read a 32 bit signed integer.\n   */\n  readInt32(): number {\n    if (this.remaining < 4) {\n      throw new Error(`ByteStream: readInt32: premature end - want 4 bytes but have ${this.remaining}`);\n    }\n\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToInt32(uint8array[index], uint8array[index + 1], uint8array[index + 2], uint8array[index + 3]);\n\n    this.index += 4;\n    this.remaining -= 4;\n\n    return data;\n  }\n\n  /**\n   * Read a 8 bit unsigned integer.\n   */\n  readUint8(): number {\n    if (this.remaining < 1) {\n      throw new Error(`ByteStream: readUint8: premature end - want 1 byte but have ${this.remaining}`);\n    }\n\n    const data = this.uint8array[this.index];\n\n    this.index += 1;\n    this.remaining -= 1;\n\n    return data;\n  }\n\n  /**\n   * Read a 16 bit unsigned integer.\n   */\n  readUint16(): number {\n    if (this.remaining < 2) {\n      throw new Error(`ByteStream: readUint16: premature end - want 2 bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToUint16(uint8array[index], uint8array[index + 1]);\n\n    this.index += 2;\n    this.remaining -= 2;\n\n    return data;\n  }\n\n  /**\n   * Read a 32 bit unsigned integer.\n   */\n  readUint32(): number {\n    if (this.remaining < 4) {\n      throw new Error(`ByteStream: readUint32: premature end - want 4 bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToUint32(uint8array[index], uint8array[index + 1], uint8array[index + 2], uint8array[index + 3]);\n\n    this.index += 4;\n    this.remaining -= 4;\n\n    return data;\n  }\n\n  /**\n   * Read a 32 bit float.\n   */\n  readFloat32(): number {\n    if (this.remaining < 4) {\n      throw new Error(`ByteStream: readFloat32: premature end - want 4 bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToFloat32(uint8array[index], uint8array[index + 1], uint8array[index + 2], uint8array[index + 3]);\n\n    this.index += 4;\n    this.remaining -= 4;\n\n    return data;\n  }\n\n  /**\n   * Read a 64 bit float.\n   */\n  readFloat64(): number {\n    if (this.remaining < 8) {\n      throw new Error(`ByteStream: readFloat64: premature end - want 8 bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const data = uint8ToFloat64(uint8array[index], uint8array[index + 1], uint8array[index + 2], uint8array[index + 3], uint8array[index + 4], uint8array[index + 5], uint8array[index + 6], uint8array[index + 7]);\n\n    this.index += 8;\n    this.remaining -= 8;\n\n    return data;\n  }\n\n  /**\n   * Read an array of 8 bit signed integers.\n   */\n  readInt8Array(view: number | Int8Array): Int8Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Int8Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readInt8Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      view[i] = uint8ToInt8(uint8array[index + i]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 16 bit signed integers.\n   */\n  readInt16Array(view: number | Int16Array): Int16Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Int16Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readInt16Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 2;\n\n      view[i] = uint8ToInt16(uint8array[offset], uint8array[offset + 1]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 32 bit signed integers.\n   */\n  readInt32Array(view: number | Int32Array): Int32Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Int32Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readInt32Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 4;\n\n      view[i] = uint8ToInt32(uint8array[offset], uint8array[offset + 1], uint8array[offset + 2], uint8array[offset + 3]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 8 bit unsigned integers.\n   */\n  readUint8Array(view: number | Uint8Array): Uint8Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Uint8Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readUint8Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      view[i] = uint8array[index + i];\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 16 bit unsigned integers.\n   */\n  readUint16Array(view: number | Uint16Array): Uint16Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Uint16Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readUint16Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 2;\n\n      view[i] = uint8ToUint16(uint8array[offset], uint8array[offset + 1]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 32 bit unsigned integers.\n   */\n  readUint32Array(view: number | Uint32Array): Uint32Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Uint32Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readUint32Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 4;\n\n      view[i] = uint8ToUint32(uint8array[offset], uint8array[offset + 1], uint8array[offset + 2], uint8array[offset + 3]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 32 bit floats.\n   */\n  readFloat32Array(view: number | Float32Array): Float32Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Float32Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readFloat32Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 4;\n\n      view[i] = uint8ToFloat32(uint8array[offset], uint8array[offset + 1], uint8array[offset + 2], uint8array[offset + 3]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Read an array of 64 bit floats.\n   */\n  readFloat64Array(view: number | Float64Array): Float64Array {\n    if (!ArrayBuffer.isView(view)) {\n      view = new Float64Array(view);\n    }\n\n    if (this.remaining < view.byteLength) {\n      throw new Error(`ByteStream: readFloat64Array: premature end - want ${view.byteLength} bytes but have ${this.remaining}`);\n    }\n\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 8;\n\n      view[i] = uint8ToFloat64(uint8array[offset], uint8array[offset + 1], uint8array[offset + 2], uint8array[offset + 3], uint8array[offset + 4], uint8array[offset + 5], uint8array[offset + 6], uint8array[offset + 7]);\n    }\n\n    this.index += view.byteLength;\n    this.remaining -= view.byteLength;\n\n    return view;\n  }\n\n  /**\n   * Write a UTF8 string.\n   * \n   * Returns the number of bytes that were written,\n   */\n  write(utf8: string): number {\n    const bytes = encodeUtf8(utf8);\n\n    this.writeUint8Array(bytes);\n\n    return bytes.length;\n  }\n\n  /**\n   * Write a UTF8 string as a NULL terminated string.\n   * \n   * Returns the number of bytes that were written, including the terminating NULL.\n   */\n  writeNull(utf8: string): number {\n    const bytes = this.write(utf8);\n\n    this.index++;\n    this.remaining--;\n\n    return bytes + 1;\n  }\n\n  /**\n   * Write a binary string.\n   */\n  writeBinary(value: string): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n    const count = value.length;\n\n    for (let i = 0; i < count; i++) {\n      uint8array[index + i] = value.charCodeAt(i);\n    }\n\n    this.index += count;\n  }\n\n  /**\n   * Write a 8 bit signed integer.\n   */\n  writeInt8(value: number): void {\n    this.uint8array[this.index] = int8ToUint8(value);\n    this.index += 1;\n  }\n\n  /**\n   * Write a 16 bit signed integer.\n   */\n  writeInt16(value: number): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    int16ToUint8(uint8, value);\n\n    uint8array[index] = uint8[0];\n    uint8array[index + 1] = uint8[1];\n\n    this.index += 2;\n  }\n\n  /**\n   * Write a 32 bit signed integer.\n   */\n  writeInt32(value: number): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    int32ToUint8(uint8, value);\n\n    uint8array[index] = uint8[0];\n    uint8array[index + 1] = uint8[1];\n    uint8array[index + 2] = uint8[2];\n    uint8array[index + 3] = uint8[3];\n\n    this.index += 4;\n  }\n\n  /**\n   * Write a 8 bit unsigned integer.\n   */\n  writeUint8(value: number): void {\n    this.uint8array[this.index] = value;\n    this.index += 1;\n  }\n\n  /**\n   * Write a 16 bit unsigned integer.\n   */\n  writeUint16(value: number): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    uint16ToUint8(uint8, value);\n\n    uint8array[index] = uint8[0];\n    uint8array[index + 1] = uint8[1];\n\n    this.index += 2;\n  }\n\n  /**\n   * Write a 32 bit unsigned integer.\n   */\n  writeUint32(value: number): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    uint32ToUint8(uint8, value);\n\n    uint8array[index] = uint8[0];\n    uint8array[index + 1] = uint8[1];\n    uint8array[index + 2] = uint8[2];\n    uint8array[index + 3] = uint8[3];\n\n    this.index += 4;\n  }\n\n  /**\n   * Write a 32 bit float.\n   */\n  writeFloat32(value: number): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    float32ToUint8(uint8, value);\n\n    uint8array[index] = uint8[0];\n    uint8array[index + 1] = uint8[1];\n    uint8array[index + 2] = uint8[2];\n    uint8array[index + 3] = uint8[3];\n\n    this.index += 4;\n  }\n\n  /**\n   * Write a 64 bit float.\n   */\n  writeFloat64(value: number): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    float64ToUint8(uint8, value);\n\n    uint8array[index] = uint8[0];\n    uint8array[index + 1] = uint8[1];\n    uint8array[index + 2] = uint8[2];\n    uint8array[index + 3] = uint8[3];\n    uint8array[index + 4] = uint8[4];\n    uint8array[index + 5] = uint8[5];\n    uint8array[index + 6] = uint8[6];\n    uint8array[index + 7] = uint8[7];\n\n    this.index += 8;\n  }\n\n  /**\n   * Write an array of 8 bit signed integers.\n   */\n  writeInt8Array(view: Int8Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      uint8array[index + i] = int8ToUint8(view[i]);\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 16 bit signed integers.\n   */\n  writeInt16Array(view: Int16Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 2;\n\n      int16ToUint8(uint8, view[i]);\n\n      uint8array[offset] = uint8[0];\n      uint8array[offset + 1] = uint8[1];\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 32 bit signed integers.\n   */\n  writeInt32Array(view: Int32Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 4;\n\n      int32ToUint8(uint8, view[i]);\n\n      uint8array[offset] = uint8[0];\n      uint8array[offset + 1] = uint8[1];\n      uint8array[offset + 2] = uint8[2];\n      uint8array[offset + 3] = uint8[3];\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 8 bit unsigned integers.\n   */\n  writeUint8Array(view: Uint8Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      uint8array[index + i] = view[i];\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 16 bit unsigned integers.\n   */\n  writeUint16Array(view: Uint16Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 2;\n\n      uint16ToUint8(uint8, view[i]);\n\n      uint8array[offset] = uint8[0];\n      uint8array[offset + 1] = uint8[1];\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 32 bit unsigned integers.\n   */\n  writeUint32Array(view: Uint32Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 4;\n\n      uint32ToUint8(uint8, view[i]);\n\n      uint8array[offset] = uint8[0];\n      uint8array[offset + 1] = uint8[1];\n      uint8array[offset + 2] = uint8[2];\n      uint8array[offset + 3] = uint8[3];\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 32 bit floats.\n   */\n  writeFloat32Array(view: Float32Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 4;\n\n      float32ToUint8(uint8, view[i]);\n\n      uint8array[offset] = uint8[0];\n      uint8array[offset + 1] = uint8[1];\n      uint8array[offset + 2] = uint8[2];\n      uint8array[offset + 3] = uint8[3];\n    }\n\n    this.index += view.byteLength;\n  }\n\n  /**\n   * Write an array of 64 bit floats.\n   */\n  writeFloat64Array(view: Float64Array): void {\n    const index = this.index;\n    const uint8array = this.uint8array;\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      const offset = index + i * 8;\n\n      float64ToUint8(uint8, view[i]);\n\n      uint8array[offset] = uint8[0];\n      uint8array[offset + 1] = uint8[1];\n      uint8array[offset + 2] = uint8[2];\n      uint8array[offset + 3] = uint8[3];\n      uint8array[offset + 4] = uint8[4];\n      uint8array[offset + 5] = uint8[5];\n      uint8array[offset + 6] = uint8[6];\n      uint8array[offset + 7] = uint8[7];\n    }\n\n    this.index += view.byteLength;\n  }\n}\n"
  },
  {
    "path": "src/common/bitstream.ts",
    "content": "import { bytesOf } from './bytesof';\n\n/**\n * A bit stream.\n */\nexport default class BitStream {\n  buffer: ArrayBuffer;\n  uint8array: Uint8Array;\n  index = 0;\n  byteLength: number;\n  bitBuffer = 0;\n  bits = 0;\n\n  constructor(buffer: ArrayBuffer | Uint8Array, byteOffset?: number, byteLength?: number) {\n    const bytes = bytesOf(buffer);\n\n    // For browsers not supporting the spec.\n    // Once upon a time I reported this issue on the Firefox tracker.\n    // Seems like Safari needs an issue report too.\n    byteOffset = byteOffset || 0;\n    byteLength = byteLength || bytes.length;\n\n    this.buffer = buffer;\n    this.uint8array = bytes.subarray(byteOffset, byteOffset + byteLength);\n    this.byteLength = buffer.byteLength;\n  }\n\n  /**\n   * Peek a number of bits.\n   */\n  peekBits(bits: number): number {\n    this.loadBits(bits);\n\n    return this.bitBuffer & ((1 << bits) - 1);\n  }\n\n  /**\n   * Read a number of bits.\n   */\n  readBits(bits: number): number {\n    const data = this.peekBits(bits);\n\n    this.bitBuffer >>>= bits;\n    this.bits -= bits;\n\n    return data;\n  }\n\n  /**\n   * Skip a number of bits.\n   */\n  skipBits(bits: number): void {\n    this.loadBits(bits);\n\n    this.bitBuffer >>>= bits;\n    this.bits -= bits;\n  }\n\n  /**\n   * Load more bits into the buffer.\n   */\n  loadBits(bits: number): void {\n    while (this.bits < bits) {\n      this.bitBuffer += this.uint8array[this.index] << this.bits;\n      this.bits += 8;\n      this.index += 1;\n    }\n  }\n}\n"
  },
  {
    "path": "src/common/bytesof.ts",
    "content": "import { encodeUtf8 } from './utf8';\n\n/**\n * Return the given buffer as a Uint8Array.\n * \n * Strings are encoded as UTF8.\n */\nexport function bytesOf(buffer: ArrayBuffer | Uint8Array | string | number[]): Uint8Array {\n  if (buffer instanceof Uint8Array) {\n    return buffer;\n  } else if (typeof buffer === 'string') {\n    return encodeUtf8(buffer);\n  } else {\n    return new Uint8Array(buffer);\n  }\n}\n"
  },
  {
    "path": "src/common/canvas.ts",
    "content": "let canvas: HTMLCanvasElement;\nlet ctx: CanvasRenderingContext2D;\nlet canvas2: HTMLCanvasElement;\nlet ctx2: CanvasRenderingContext2D;\n\n// Only create the canvases and contexts in browsers.\nif (typeof window === 'object') {\n  canvas = document.createElement('canvas');\n  ctx = <CanvasRenderingContext2D>canvas.getContext('2d');\n  canvas2 = document.createElement('canvas');\n  ctx2 = <CanvasRenderingContext2D>canvas2.getContext('2d');\n}\n\nexport function blobToImage(blob: Blob): Promise<HTMLImageElement> {\n  return new Promise<HTMLImageElement>((resolve,  reject) => {\n    const url = URL.createObjectURL(blob);\n    const image = new Image();\n\n    image.onload = (): void => {\n      resolve(image);\n    };\n\n    image.onerror = (e): void => {\n      reject(e);\n    };\n\n    image.src = url;\n  });\n}\n\nexport function blobToImageData(blob: Blob): Promise<ImageData> {\n  return new Promise<ImageData>((resolve, reject) => {\n    const url = URL.createObjectURL(blob);\n    const image = new Image();\n\n    image.onload = (): void => {\n      URL.revokeObjectURL(url);\n\n      canvas.width = image.width;\n      canvas.height = image.height;\n\n      ctx.drawImage(image, 0, 0);\n\n      resolve(ctx.getImageData(0, 0, image.width, image.height));\n    };\n\n    image.onerror = (e): void => {\n      reject(e);\n    };\n\n    image.src = url;\n  });\n}\n\nexport function imageDataToBlob(imageData: ImageData): Promise<Blob | null> {\n  return new Promise((resolve: BlobCallback) => {\n    canvas.width = imageData.width;\n    canvas.height = imageData.height;\n\n    ctx.putImageData(imageData, 0, 0);\n\n    canvas.toBlob((blob) => {\n      resolve(blob);\n    });\n  });\n}\n\nexport function imageDataToDataUrl(imageData: ImageData): string {\n  canvas.width = imageData.width;\n  canvas.height = imageData.height;\n\n  ctx.putImageData(imageData, 0, 0);\n\n  return canvas.toDataURL();\n}\n\nexport function imageDataToImage(imageData: ImageData): HTMLImageElement {\n  const image = new Image();\n\n  image.src = imageDataToDataUrl(imageData);\n\n  return image;\n}\n\nexport function imageToImageData(image: TexImageSource): ImageData {\n  const width = image.width;\n  const height = image.height;\n\n  canvas.width = width;\n  canvas.height = height;\n\n  ctx.drawImage(<CanvasImageSource>image, 0, 0);\n\n  return ctx.getImageData(0, 0, width, height);\n}\n\nexport function resizeImageData(data: TexImageSource, width: number, height: number): ImageData {\n  if (data instanceof ImageData) {\n    canvas.width = data.width;\n    canvas.height = data.height;\n\n    ctx.putImageData(data, 0, 0);\n\n    canvas2.width = width;\n    canvas2.height = height;\n\n    ctx2.drawImage(canvas, 0, 0, width, height);\n\n    return ctx2.getImageData(0, 0, width, height);\n  } else {\n    canvas.width = width;\n    canvas.height = height;\n\n    ctx.drawImage(data, 0, 0, width, height);\n\n    return ctx.getImageData(0, 0, width, height);\n  }\n}\n"
  },
  {
    "path": "src/common/convertbitrange.ts",
    "content": "/**\n * Returns a number, which when multiplied with a number of fromBits bits, will convert it to a toBits bits number.\n * \n * For example, 7 * convertBitRange(3, 8) == 255.\n * \n * In other words, if we look at the bits, 111 is the same to 3 bits as 11111111 is to 8 bits.\n */\nexport default function convertBitRange(fromBits: number, toBits: number): number {\n  return ((1 << toBits) - 1) / ((1 << fromBits) - 1);\n}\n"
  },
  {
    "path": "src/common/dxt.ts",
    "content": "import convertBitRange from './convertbitrange';\n\nconst dxt4to8 = convertBitRange(4, 8);\nconst dxt5to8 = convertBitRange(5, 8);\nconst dxt6to8 = convertBitRange(6, 8);\nconst dx1colors = new Uint8Array(16);\nconst dx3colors = new Uint8Array(12);\nconst dx5alphas = new Uint8Array(8);\nconst red = new Uint8Array(8);\nconst green = new Uint8Array(8);\n\nfunction dx1Colors(out: Uint8Array, color0: number, color1: number): void {\n  const r0 = ((color0 >> 11) & 31) * dxt5to8;\n  const g0 = ((color0 >> 5) & 63) * dxt6to8;\n  const b0 = (color0 & 31) * dxt5to8;\n  const r1 = ((color1 >> 11) & 31) * dxt5to8;\n  const g1 = ((color1 >> 5) & 63) * dxt6to8;\n  const b1 = (color1 & 31) * dxt5to8;\n\n  // Minimum and maximum colors.\n  out[0] = r0;\n  out[1] = g0;\n  out[2] = b0;\n  out[3] = 255;\n  out[4] = r1;\n  out[5] = g1;\n  out[6] = b1;\n  out[7] = 255;\n\n  // Interpolated colors.\n  if (color0 > color1) {\n    out[8] = (5 * r0 + 3 * r1) >> 3;\n    out[9] = (5 * g0 + 3 * g1) >> 3;\n    out[10] = (5 * b0 + 3 * b1) >> 3;\n    out[11] = 255;\n    out[12] = (5 * r1 + 3 * r0) >> 3;\n    out[13] = (5 * g1 + 3 * g0) >> 3;\n    out[14] = (5 * b1 + 3 * b0) >> 3;\n    out[15] = 255;\n  } else {\n    out[8] = (r0 + r1) >> 1;\n    out[9] = (g0 + g1) >> 1;\n    out[10] = (b0 + b1) >> 1;\n    out[11] = 255;\n    out[12] = 0;\n    out[13] = 0;\n    out[14] = 0;\n    out[15] = 0;\n  }\n}\n\nfunction dx3Colors(out: Uint8Array, color0: number, color1: number): void {\n  const r0 = ((color0 >> 11) & 31) * dxt5to8;\n  const g0 = ((color0 >> 5) & 63) * dxt6to8;\n  const b0 = (color0 & 31) * dxt5to8;\n  const r1 = ((color1 >> 11) & 31) * dxt5to8;\n  const g1 = ((color1 >> 5) & 63) * dxt6to8;\n  const b1 = (color1 & 31) * dxt5to8;\n\n  // Minimum and maximum colors.\n  out[0] = r0;\n  out[1] = g0;\n  out[2] = b0;\n  out[3] = r1;\n  out[4] = g1;\n  out[5] = b1;\n\n  // Interpolated colors.\n  out[6] = (5 * r0 + 3 * r1) >> 3;\n  out[7] = (5 * g0 + 3 * g1) >> 3;\n  out[8] = (5 * b0 + 3 * b1) >> 3;\n  out[9] = (5 * r1 + 3 * r0) >> 3;\n  out[10] = (5 * g1 + 3 * g0) >> 3;\n  out[11] = (5 * b1 + 3 * b0) >> 3;\n}\n\nfunction dx5Alphas(out: Uint8Array, alpha0: number, alpha1: number): void {\n  // Minimum and maximum alphas.\n  out[0] = alpha0;\n  out[1] = alpha1;\n\n  // Interpolated alphas.\n  if (alpha0 > alpha1) {\n    out[2] = (54 * alpha0 + 9 * alpha1) >> 6;\n    out[3] = (45 * alpha0 + 18 * alpha1) >> 6;\n    out[4] = (36 * alpha0 + 27 * alpha1) >> 6;\n    out[5] = (27 * alpha0 + 36 * alpha1) >> 6;\n    out[6] = (18 * alpha0 + 45 * alpha1) >> 6;\n    out[7] = (9 * alpha0 + 54 * alpha1) >> 6;\n  } else {\n    out[2] = (12 * alpha0 + 3 * alpha1) >> 4;\n    out[3] = (9 * alpha0 + 6 * alpha1) >> 4;\n    out[4] = (6 * alpha0 + 9 * alpha1) >> 4;\n    out[5] = (3 * alpha0 + 12 * alpha1) >> 4;\n    out[6] = 0;\n    out[7] = 255;\n  }\n}\n\nfunction rgColors(out: Uint8Array, color0: number, color1: number): void {\n  // Minimum and maximum red colors.\n  out[0] = color0;\n  out[1] = color1;\n\n  // Interpolated red colors.\n  if (color0 > color1) {\n    out[2] = (6 * color0 + 1 * color1) / 7;\n    out[3] = (5 * color0 + 2 * color1) / 7;\n    out[4] = (4 * color0 + 3 * color1) / 7;\n    out[5] = (3 * color0 + 4 * color1) / 7;\n    out[6] = (2 * color0 + 5 * color1) / 7;\n    out[7] = (1 * color0 + 6 * color1) / 7;\n  } else {\n    out[2] = (4 * color0 + 1 * color1) / 5;\n    out[3] = (3 * color0 + 2 * color1) / 5;\n    out[4] = (2 * color0 + 3 * color1) / 5;\n    out[5] = (1 * color0 + 4 * color1) / 5;\n    out[6] = 0;\n    out[7] = 1;\n  }\n}\n\n/**\n * Decodes DXT1 data to a Uint8Array typed array with 8-8-8-8 RGBA bits.\n * \n * DXT1 is also known as BC1.\n */\nexport function decodeDxt1(src: Uint8Array, width: number, height: number): Uint8Array {\n  const dst = new Uint8Array(width * height * 4);\n\n  for (let blockY = 0, blockHeight = height / 4; blockY < blockHeight; blockY++) {\n    for (let blockX = 0, blockWidth = width / 4; blockX < blockWidth; blockX++) {\n      const i = 8 * (blockY * blockWidth + blockX);\n\n      // Get the color values.\n      dx1Colors(dx1colors, src[i] + 256 * src[i + 1], src[i + 2] + 256 * src[i + 3]);\n\n      // The offset to the first pixel in the destination.\n      const dstI = (blockY * 16) * width + blockX * 16;\n\n      // All 32 color bits.\n      const bits = src[i + 4] | (src[i + 5] << 8) | (src[i + 6] << 16) | (src[i + 7] << 24);\n\n      for (let row = 0; row < 4; row++) {\n        const rowOffset = row * 8;\n        const dstOffset = dstI + row * width * 4;\n\n        for (let column = 0; column < 4; column++) {\n          const dstIndex = dstOffset + column * 4;\n          const colorOffset = ((bits >> (rowOffset + column * 2)) & 3) * 4;\n\n          dst[dstIndex + 0] = dx1colors[colorOffset + 0];\n          dst[dstIndex + 1] = dx1colors[colorOffset + 1];\n          dst[dstIndex + 2] = dx1colors[colorOffset + 2];\n          dst[dstIndex + 3] = dx1colors[colorOffset + 3];\n        }\n      }\n    }\n  }\n\n  return dst;\n}\n\n/**\n * Decodes DXT3 data to a Uint8Array typed array with 8-8-8-8 RGBA bits.\n * \n * DXT3 is also known as BC2.\n */\nexport function decodeDxt3(src: Uint8Array, width: number, height: number): Uint8Array {\n  const dst = new Uint8Array(width * height * 4);\n  const rowBytes = width * 4;\n\n  for (let blockY = 0, blockHeight = height / 4; blockY < blockHeight; blockY++) {\n    for (let blockX = 0, blockWidth = width / 4; blockX < blockWidth; blockX++) {\n      const i = 16 * (blockY * blockWidth + blockX);\n\n      // Get the color values.\n      dx3Colors(dx3colors, src[i + 8] + 256 * src[i + 9], src[i + 10] + 256 * src[i + 11]);\n\n      let dstI = (blockY * 16) * width + blockX * 16;\n\n      for (let row = 0; row < 4; row++) {\n        // Get 16 bits of alpha indices.\n        const alphaBits = src[i + row * 2] + 256 * src[i + 1 + row * 2];\n\n        // Get 8 bits of color indices.\n        const colorBits = src[i + 12 + row];\n\n        for (let column = 0; column < 4; column++) {\n          const dstIndex = dstI + column * 4;\n          const colorIndex = ((colorBits >> (column * 2)) & 3) * 3;\n\n          dst[dstIndex + 0] = dx3colors[colorIndex + 0];\n          dst[dstIndex + 1] = dx3colors[colorIndex + 1];\n          dst[dstIndex + 2] = dx3colors[colorIndex + 2];\n          dst[dstIndex + 3] = ((alphaBits >> (column * 4)) & 0xf) * dxt4to8;\n        }\n\n        dstI += rowBytes;\n      }\n    }\n  }\n\n  return dst;\n}\n\n/**\n * Decodes DXT5 data to a Uint8Array typed array with 8-8-8-8 RGBA bits.\n * \n * DXT5 is also known as BC3.\n */\nexport function decodeDxt5(src: Uint8Array, width: number, height: number): Uint8Array {\n  const dst = new Uint8Array(width * height * 4);\n  const rowBytes = width * 4;\n\n  for (let blockY = 0, blockHeight = height / 4; blockY < blockHeight; blockY++) {\n    for (let blockX = 0, blockWidth = width / 4; blockX < blockWidth; blockX++) {\n      const i = 16 * (blockY * blockWidth + blockX);\n\n      // Get the alpha values.\n      dx5Alphas(dx5alphas, src[i], src[i + 1]);\n\n      // Get the color values.\n      dx3Colors(dx3colors, src[i + 8] + 256 * src[i + 9], src[i + 10] + 256 * src[i + 11]);\n\n      // The offset to the first pixel in the destination.\n      let dstI = (blockY * 16) * width + blockX * 16;\n\n      // The outer loop is only needed because JS bitwise operators only work on 32bit integers, while the alpha flags contain 48 bits.\n      // Processing is instead done in two blocks, where each one handles 24 bits, or two rows of 4 pixels.\n      for (let block = 0; block < 2; block++) {\n        const alphaOffset = i + 2 + block * 3;\n        const colorOffset = i + 12 + block * 2;\n\n        // 24 alpha bits.\n        const alphaBits = src[alphaOffset] + 256 * (src[alphaOffset + 1] + 256 * src[alphaOffset + 2]);\n\n        // Go over two rows.\n        for (let row = 0; row < 2; row++) {\n          const colorBits = src[colorOffset + row];\n\n          // Go over four columns.\n          for (let column = 0; column < 4; column++) {\n            const dstIndex = dstI + column * 4;\n            const colorIndex = ((colorBits >> (column * 2)) & 3) * 3;\n            const alphaIndex = (alphaBits >> (row * 12 + column * 3)) & 7;\n\n            // Set the pixel.\n            dst[dstIndex + 0] = dx3colors[colorIndex + 0];\n            dst[dstIndex + 1] = dx3colors[colorIndex + 1];\n            dst[dstIndex + 2] = dx3colors[colorIndex + 2];\n            dst[dstIndex + 3] = dx5alphas[alphaIndex];\n          }\n\n          // Next row.\n          dstI += rowBytes;\n        }\n      }\n    }\n  }\n\n  return dst;\n}\n\n/**\n * Decodes RGTC data to a Uint8Array typed array with 8-8 RG bits.\n * \n * RGTC is also known as BC5, ATI2, and 3Dc.\n */\nexport function decodeRgtc(src: Uint8Array, width: number, height: number): Uint8Array {\n  const dst = new Uint8Array(width * height * 2);\n  const rowBytes = width * 2;\n\n  for (let blockY = 0, blockHeight = height / 4; blockY < blockHeight; blockY++) {\n    for (let blockX = 0, blockWidth = width / 4; blockX < blockWidth; blockX++) {\n      const i = 16 * (blockY * blockWidth + blockX);\n\n      // Get the red colors.\n      rgColors(red, src[i], src[i + 1]);\n\n      // Get the green colors.\n      rgColors(green, src[i + 8], src[i + 9]);\n\n      // The offset to the first pixel in the destination.\n      let dstI = (blockY * 8) * width + blockX * 8;\n\n      // Split to two blocks of two rows, because there are 48 color bits.\n      for (let block = 0; block < 2; block++) {\n        const blockOffset = i + block * 3;\n\n        // Get 24 bits of the color indices.\n        const redbits = src[blockOffset + 2] + 256 * (src[blockOffset + 3] + 256 * src[blockOffset + 4]);\n        const greenbits = src[blockOffset + 10] + 256 * (src[blockOffset + 11] + 256 * src[blockOffset + 12]);\n\n        for (let row = 0; row < 2; row++) {\n          const rowOffset = row * 4;\n\n          for (let column = 0; column < 4; column++) {\n            const dstOffset = dstI + column * 2;\n            const shifts = 3 * (rowOffset + column);\n\n            dst[dstOffset + 1] = red[(redbits >> shifts) & 7];\n            dst[dstOffset + 2] = green[(greenbits >> shifts) & 7];\n          }\n\n          // Next row.\n          dstI += rowBytes;\n        }\n      }\n    }\n  }\n\n  return dst;\n}\n"
  },
  {
    "path": "src/common/fetchdatatype.ts",
    "content": "/**\n * The valid data type names for resource fetches.\n */\nexport type FetchDataTypeName = 'image' | 'text' | 'arrayBuffer' | 'bytes' | 'blob';\n\n/**\n * The valid data types for resource fetches.\n */\nexport type FetchDataType = HTMLImageElement | string | ArrayBuffer | Uint8Array | Blob;\n\n/**\n * The structure that the promise returned by fetchDataType is resolved to.\n */\nexport interface FetchResult {\n  ok: boolean;\n  data: FetchDataType | Response | Event;\n  error?: string;\n}\n\n/**\n * Returns a promise that will resolve with the data from the given path.\n * \n * The data type determines the returned object:\n *\n *     \"image\" => Image\n *     \"text\" => string\n *     \"arrayBuffer\" => ArrayBuffer\n *     \"bytes\" => Uint8Array\n *     \"blob\" => Blob\n */\nexport async function fetchDataType(path: string, dataType: FetchDataTypeName): Promise<FetchResult> {\n  if (dataType === 'image') {\n    // Promise wrapper for an image load.\n    return new Promise<FetchResult>((resolve) => {\n      const image = new Image();\n\n      image.onload = (): void => {\n        resolve({ ok: true, data: image });\n      };\n\n      image.onerror = (e): void => {\n        resolve({ ok: false, error: 'Image Error', data: e });\n      };\n\n      image.src = path;\n    });\n  } else {\n    let response: Response;\n\n    // Fetch.\n    try {\n      response = await fetch(path);\n    } catch (e) {\n      return <FetchResult>{ ok: false, error: 'Network Error', data: e };\n    }\n\n    // Fetch went ok?\n    if (!response.ok) {\n      return <FetchResult>{ ok: false, error: 'Http Error', data: response };\n    }\n\n    // Try to get the requested data type.\n    try {\n      let data: string | ArrayBuffer | Blob | null = null;\n\n      if (dataType === 'text') {\n        data = await response.text();\n      } else if (dataType === 'arrayBuffer' || dataType === 'bytes') {\n        data = await response.arrayBuffer();\n      } else if (dataType === 'blob') {\n        data = await response.blob();\n      }\n\n      if (dataType === 'bytes') {\n        data = new Uint8Array(<ArrayBuffer>data);\n      }\n\n      return <FetchResult>{ ok: true, data };\n    } catch (e) {\n      return <FetchResult>{ ok: false, error: 'Data Error', data: e };\n    }\n  }\n}\n"
  },
  {
    "path": "src/common/gl-matrix-addon.ts",
    "content": "import { vec3, vec4, quat, mat4 } from 'gl-matrix';\n\nexport const VEC3_UNIT_X = vec3.fromValues(1, 0, 0);\nexport const VEC3_UNIT_Y = vec3.fromValues(0, 1, 0);\nexport const VEC3_UNIT_Z = vec3.fromValues(0, 0, 1);\nexport const VEC3_ZERO = vec3.create();\nexport const VEC3_ONE = vec3.fromValues(1, 1, 1);\nexport const QUAT_ZERO = quat.fromValues(0, 0, 0, 0);\nexport const QUAT_DEFAULT = quat.create();\n\nconst vec4Heap = vec4.create();\n\nexport function unproject(out: vec3, v: vec3, inverseMatrix: mat4, viewport: vec4): vec3 {\n  const x = 2 * (v[0] - viewport[0]) / viewport[2] - 1;\n  const y = 1 - 2 * (v[1] - viewport[1]) / viewport[3];\n  const z = 2 * v[2] - 1;\n\n  vec4.set(vec4Heap, x, y, z, 1);\n  vec4.transformMat4(vec4Heap, vec4Heap, inverseMatrix);\n  vec3.set(out, vec4Heap[0] / vec4Heap[3], vec4Heap[1] / vec4Heap[3], vec4Heap[2] / vec4Heap[3]);\n\n  return out;\n}\n\n/**\n * Get the distance of a point from a plane.\n * \n *     dot(plane, vec4(point, 1))\n */\nexport function distanceToPlane(plane: vec4, point: vec3): number {\n  return plane[0] * point[0] + plane[1] * point[1] + plane[2] * point[2] + plane[3];\n}\n\n/**\n * Get the distance of a point from a plane.\n * \n *     dot(plane, vec4(x, y, 0, 1))\n */\nexport function distanceToPlane2(plane: vec4, x: number, y: number): number {\n  return plane[0] * x + plane[1] * y + plane[3];\n}\n\n/**\n * Get the distance of a point from a plane.\n * \n *     dot(plane, vec4(x, y, z, 1))\n */\nexport function distanceToPlane3(plane: vec4, x: number, y: number, z: number): number {\n  return plane[0] * x + plane[1] * y + plane[2] * z + plane[3];\n}\n\n/**\n * Test if a sphere with the given center and radius intersects the given planes.\n * If it doesn't, the index of the first plane that proved this is returned.\n * Otherwise returns -1.\n *\n * If first is given, the test will begin from the plane at that index.\n */\nexport function testSphere(planes: vec4[], x: number, y: number, z: number, r: number, first: number): number {\n  if (first === -1) {\n    first = 0;\n  }\n\n  for (let i = 0; i < 6; i++) {\n    const index = (first + i) % 6;\n\n    if (distanceToPlane3(planes[index], x, y, z) <= -r) {\n      return index;\n    }\n  }\n\n  return -1;\n}\n\n/**\n * Test if a cell with the given coordinates intersects the given planes.\n * If it doesn't, the index of the first plane that proved this is returned.\n * Otherwise returns -1.\n *\n * If first is given, the test will begin from the plane at that index.\n */\nexport function testCell(planes: vec4[], left: number, right: number, bottom: number, top: number, first: number): number {\n  if (first === -1) {\n    first = 0;\n  }\n\n  for (let i = 0; i < 6; i++) {\n    const index = (first + i) % 6;\n    const plane = planes[index];\n\n    if (distanceToPlane2(plane, left, bottom) < 0 &&\n      distanceToPlane2(plane, left, top) < 0 &&\n      distanceToPlane2(plane, right, top) < 0 &&\n      distanceToPlane2(plane, right, bottom) < 0) {\n      return index;\n    }\n  }\n\n  return -1;\n}\n\nexport function planeLength(plane: vec4): number {\n  return Math.hypot(plane[0], plane[1], plane[2]);\n}\n\n/**\n * Normalize a plane.\n * \n * Note that this is not the same as normalizing a vec4.\n */\nexport function normalizePlane(out: vec4, plane: vec4): void {\n  const len = planeLength(plane);\n\n  out[0] = plane[0] / len;\n  out[1] = plane[1] / len;\n  out[2] = plane[2] / len;\n  out[3] = plane[3] / len;\n}\n\n/**\n * Unpacks a matrix's planes.\n */\nexport function unpackPlanes(planes: vec4[], m: mat4): void {\n  // eslint-disable-next-line one-var\n  const a00 = m[0], a01 = m[4], a02 = m[8], a03 = m[12],\n    a10 = m[1], a11 = m[5], a12 = m[9], a13 = m[13],\n    a20 = m[2], a21 = m[6], a22 = m[10], a23 = m[14],\n    a30 = m[3], a31 = m[7], a32 = m[11], a33 = m[15];\n  let plane;\n\n  // Left clipping plane\n  plane = planes[0];\n  plane[0] = a30 + a00;\n  plane[1] = a31 + a01;\n  plane[2] = a32 + a02;\n  plane[3] = a33 + a03;\n\n  // Right clipping plane\n  plane = planes[1];\n  plane[0] = a30 - a00;\n  plane[1] = a31 - a01;\n  plane[2] = a32 - a02;\n  plane[3] = a33 - a03;\n\n  // Top clipping plane\n  plane = planes[2];\n  plane[0] = a30 - a10;\n  plane[1] = a31 - a11;\n  plane[2] = a32 - a12;\n  plane[3] = a33 - a13;\n\n  // Bottom clipping plane\n  plane = planes[3];\n  plane[0] = a30 + a10;\n  plane[1] = a31 + a11;\n  plane[2] = a32 + a12;\n  plane[3] = a33 + a13;\n\n  // Near clipping plane\n  plane = planes[4];\n  plane[0] = a30 + a20;\n  plane[1] = a31 + a21;\n  plane[2] = a32 + a22;\n  plane[3] = a33 + a23;\n\n  // Far clipping plane\n  plane = planes[5];\n  plane[0] = a30 - a20;\n  plane[1] = a31 - a21;\n  plane[2] = a32 - a22;\n  plane[3] = a33 - a23;\n\n  normalizePlane(planes[0], planes[0]);\n  normalizePlane(planes[1], planes[1]);\n  normalizePlane(planes[2], planes[2]);\n  normalizePlane(planes[3], planes[3]);\n  normalizePlane(planes[4], planes[4]);\n  normalizePlane(planes[5], planes[5]);\n}\n\nconst F = vec3.create();\nconst R = vec3.create();\nconst U = vec3.create();\n\n/**\n * A look-at matrix, but for quaternions.\n * \n * See https://stackoverflow.com/a/52551983/2503048\n */\nexport function quatLookAt(out: quat, from: vec3, to: vec3, worldUp: vec3): quat {\n  vec3.normalize(F, vec3.sub(F, to, from));\n  vec3.normalize(R, vec3.cross(R, worldUp, F));\n  vec3.cross(U, R, F);\n\n  const trace = R[0] + U[2] + F[1];\n\n  if (trace > 0.0) {\n    const s = 0.5 / Math.sqrt(trace + 1.0);\n\n    out[3] = 0.25 / s;\n    out[0] = (U[1] - F[2]) * s;\n    out[2] = (F[0] - R[1]) * s;\n    out[1] = (R[2] - U[0]) * s;\n  } else {\n    if (R[0] > U[2] && R[0] > F[1]) {\n      const s = 2.0 * Math.sqrt(1.0 + R[0] - U[2] - F[1]);\n\n      out[3] = (U[1] - F[2]) / s;\n      out[0] = 0.25 * s;\n      out[2] = (U[0] + R[2]) / s;\n      out[1] = (F[0] + R[1]) / s;\n    } else if (U[2] > F[1]) {\n      const s = 2.0 * Math.sqrt(1.0 + U[2] - R[0] - F[1]);\n\n      out[3] = (F[0] - R[1]) / s;\n      out[0] = (U[0] + R[2]) / s;\n      out[2] = 0.25 * s;\n      out[1] = (F[2] + U[1]) / s;\n    } else {\n      const s = 2.0 * Math.sqrt(1.0 + F[1] - R[0] - U[2]);\n\n      out[3] = (R[2] - U[0]) / s;\n      out[0] = (F[0] + R[1]) / s;\n      out[2] = (F[2] + U[1]) / s;\n      out[1] = 0.25 * s;\n    }\n  }\n\n  return out;\n}\n"
  },
  {
    "path": "src/common/index.ts",
    "content": "import * as glMatrix from 'gl-matrix';\nimport * as glMatrixAddon from './gl-matrix-addon';\nimport * as math from './math';\nimport * as canvas from './canvas';\nimport BinaryStream from './binarystream';\nimport BitStream from './bitstream';\nimport urlWithParams from './urlwithparams';\nimport * as path from './path';\nimport { isPng, isJpeg, isGif, isWebP } from './isformat';\n\nexport default {\n  glMatrix,\n  glMatrixAddon,\n  math,\n  canvas,\n  BinaryStream,\n  BitStream,\n  urlWithParams,\n  path,\n  isPng,\n  isJpeg,\n  isGif,\n  isWebP,\n};\n"
  },
  {
    "path": "src/common/isformat.ts",
    "content": "/**\n * Detects if the given object is a PNG source.\n * \n * PNG starts with [89 50 4E 47 0D 0A 1A 0A]\n */\nexport function isPng(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47 && bytes[4] === 0x0d && bytes[5] === 0x0a && bytes[6] === 0x1a && bytes[7] === 0x0a) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Detects if the given object is a JPG source.\n * \n * JPG starts with [FF D8] and ends with [FF D9]\n */\nexport function isJpeg(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[bytes.length - 2] === 0xff && bytes[bytes.length - 1] === 0xd9) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Detects if the given object is a GIF source.\n * \n * GIF starts with [47 49 46 38 37 61] or [47 49 46 38 39 61]\n */\nexport function isGif(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x47 && bytes[1] === 0x49 && bytes[2] === 0x46 && bytes[3] === 0x38 && (bytes[4] === 0x37 || bytes[4] === 0x39) && bytes[5] === 0x61) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Detects if the given object is a WebP source.\n * \n * WebP starts with [52 49 46 46] followed by the file size - 8 followed by [57 45 42 50]\n */\nexport function isWebP(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x52 && bytes[1] === 0x49 && bytes[2] === 0x46 && bytes[3] === 0x46 && bytes[8] === 0x57 && bytes[9] === 0x45 && bytes[10] === 0x42 && bytes[11] === 0x50) {\n      return true;\n    }\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/common/math.ts",
    "content": "/**\n * Convert from degrees to radians.\n */\nexport function degToRad(degrees: number): number {\n  return degrees * (Math.PI / 180);\n}\n\n/**\n * Convert from radians to degrees.\n */\nexport function radToDeg(radians: number): number {\n  return radians * (180 / Math.PI);\n}\n\n/**\n * Gets a random number between a range.\n */\nexport function randomInRange(a: number, b: number): number {\n  return a + Math.random() * (b - a);\n}\n\n/**\n * Clamp a number in a range.\n */\nexport function clamp(x: number, minVal: number, maxVal: number): number {\n  return Math.min(Math.max(x, minVal), maxVal);\n}\n\n/**\n * Linear interpolation.\n */\nexport function lerp(a: number, b: number, t: number): number {\n  return a + t * (b - a);\n}\n\n/**\n * Hermite interpolation.\n */\nexport function hermite(a: number, b: number, c: number, d: number, t: number): number {\n  const factorTimes2 = t * t;\n  const factor1 = factorTimes2 * (2 * t - 3) + 1;\n  const factor2 = factorTimes2 * (t - 2) + t;\n  const factor3 = factorTimes2 * (t - 1);\n  const factor4 = factorTimes2 * (3 - 2 * t);\n\n  return (a * factor1) + (b * factor2) + (c * factor3) + (d * factor4);\n}\n\n/**\n * Bezier interpolation.\n */\nexport function bezier(a: number, b: number, c: number, d: number, t: number): number {\n  const invt = 1 - t;\n  const factorTimes2 = t * t;\n  const inverseFactorTimesTwo = invt * invt;\n  const factor1 = inverseFactorTimesTwo * invt;\n  const factor2 = 3 * t * inverseFactorTimesTwo;\n  const factor3 = 3 * factorTimes2 * invt;\n  const factor4 = factorTimes2 * t;\n\n  return (a * factor1) + (b * factor2) + (c * factor3) + (d * factor4);\n}\n\n/**\n * Copies the sign of one number onto another.\n */\nexport function copysign(x: number, y: number): number {\n  const signy = Math.sign(y);\n\n  if (signy === 0) {\n    return 0;\n  }\n\n  const signx = Math.sign(x);\n\n  if (signx !== signy) {\n    return -x;\n  }\n\n  return x;\n}\n\n/**\n * Gets the closest power of two bigger or equal to the given number.\n */\nexport function powerOfTwo(x: number): number {\n  x--;\n  x |= x >> 1;\n  x |= x >> 2;\n  x |= x >> 4;\n  x |= x >> 8;\n  x |= x >> 16;\n  x++;\n\n  return x;\n}\n\n/**\n * Is this number a power of two?\n */\nexport function isPowerOfTwo(x: number): boolean {\n  if (x === 0) {\n    return false;\n  }\n\n  return ((x & (x - 1)) === 0);\n}\n"
  },
  {
    "path": "src/common/path.ts",
    "content": "/**\n * Returns the base name of a file path.\n * \n * Path/To/My/File.ext => File.ext\n */\nexport function basename(path: string): string {\n  if (path && path.length) {\n    let index = path.lastIndexOf('/');\n\n    if (index !== -1) {\n      path = path.slice(index + 1);\n    }\n\n    index = path.lastIndexOf('\\\\');\n\n    if (index !== -1) {\n      path = path.slice(index + 1);\n    }\n\n    return path;\n  }\n\n  return '';\n}\n\n/**\n * Returns the extension name of a file path.\n * \n * Path/To/My/File.ext => .ext\n */\nexport function extname(path: string): string {\n  if (path && path.length) {\n    const index = path.lastIndexOf('.');\n\n    if (index !== -1) {\n      path = path.slice(index).toLowerCase();\n    }\n\n    return path;\n  }\n\n  return '';\n}\n\n/**\n * Returns the base name of a file path without the extension.\n * \n * Path/To/My/File.ext => File\n */\nexport function filename(path: string): string {\n  path = basename(path);\n\n  const index = path.lastIndexOf('.');\n\n  if (index !== -1) {\n    path = path.slice(0, index);\n  }\n\n  return path;\n}\n"
  },
  {
    "path": "src/common/searches.ts",
    "content": "export function isStringInBytes(buffer: Uint8Array, target: string, offset = 0, length = Infinity): boolean {\n  const start = Math.max(offset, 0);\n  const end = Math.min(start + length, buffer.length);\n  let whichByte = 0;\n  let targetByte = target.charCodeAt(0);\n\n  for (let i = start; i < end; i++) {\n    const byte = buffer[i];\n\n    if (byte === targetByte) {\n      whichByte += 1;\n\n      if (whichByte === target.length) {\n        return true;\n      }\n\n      targetByte = target.charCodeAt(whichByte);\n    } else if (whichByte > 0) {\n      whichByte = 0;\n      targetByte = target.charCodeAt(0);\n    }\n  }\n\n  return false;\n}\n\nexport function isStringInString(buffer: string, target: string, offset = 0, length = Infinity): boolean {\n  const start = Math.max(offset, 0);\n  const end = Math.min(start + length, buffer.length);\n  let whichByte = 0;\n  let targetByte = target[0];\n\n  for (let i = start; i < end; i++) {\n    const byte = buffer[i];\n\n    if (byte === targetByte) {\n      whichByte += 1;\n\n      if (whichByte === target.length) {\n        return true;\n      }\n\n      targetByte = target[whichByte];\n    } else if (whichByte > 0) {\n      whichByte = 0;\n      targetByte = target[0];\n    }\n  }\n\n  return false;\n}\n\nexport function boundIndexOf(buffer: Uint8Array, target: number, offset = 0, length = Infinity): number {\n  const start = Math.max(offset, 0);\n  const end = Math.min(start + length, buffer.length);\n\n  for (let i = start; i < end; i++) {\n    if (buffer[i] === target) {\n      return i;\n    }\n  }\n\n  return -1;\n}\n"
  },
  {
    "path": "src/common/seededrandom.ts",
    "content": "/**\n * Return a function that works in the same exact way as Math.random(), but with the given seed.\n * See http://indiegamr.com/generate-repeatable-random-numbers-in-js/\n */\nexport default function seededRandom(seed: number) {\n  return (): number => {\n    seed = (seed * 9301 + 49297) % 233280;\n\n    return seed / 233280;\n  };\n}\n"
  },
  {
    "path": "src/common/sstrhash2.ts",
    "content": "function hash(buffer: Uint8Array): number {\n  let o = 0;\n  let len = buffer.length;\n  let a = 0x9e3779b9;\n  let b = 0x9e3779b9;\n  let c = 0;\n\n  while (len >= 12) {\n    a += (buffer[o + 0] + (buffer[o + 1] << 8) + (buffer[o + 2] << 16) + (buffer[o + 3] << 24));\n    b += (buffer[o + 4] + (buffer[o + 5] << 8) + (buffer[o + 6] << 16) + (buffer[o + 7] << 24));\n    c += (buffer[o + 8] + (buffer[o + 9] << 8) + (buffer[o + 10] << 16) + (buffer[o + 11] << 24));\n\n    a -= b; a -= c; a ^= (c >> 13);\n    b -= c; b -= a; b ^= (a << 8);\n    c -= a; c -= b; c ^= (b >> 13);\n    a -= b; a -= c; a ^= (c >> 12);\n    b -= c; b -= a; b ^= (a << 16);\n    c -= a; c -= b; c ^= (b >> 5);\n    a -= b; a -= c; a ^= (c >> 3);\n    b -= c; b -= a; b ^= (a << 10);\n    c -= a; c -= b; c ^= (b >> 15);\n\n    o += 12;\n    len -= 12;\n  }\n\n  c += buffer.length;\n\n  if (len === 11) {\n    c += (buffer[o + 10] << 24);\n  } else if (len === 10) {\n    c += (buffer[o + 9] << 16);\n  } else if (len === 9) {\n    c += (buffer[o + 8] << 8);\n  } else if (len === 8) {\n    b += (buffer[o + 7] << 24);\n  } else if (len === 7) {\n    b += (buffer[o + 6] << 16);\n  } else if (len === 6) {\n    b += (buffer[o + 5] << 8);\n  } else if (len === 5) {\n    b += buffer[o + 4];\n  } else if (len === 4) {\n    a += (buffer[o + 3] << 24);\n  } else if (len === 3) {\n    a += (buffer[o + 2] << 16);\n  } else if (len === 2) {\n    a += (buffer[o + 1] << 8);\n  } else if (len === 1) {\n    a += buffer[o + 0];\n  }\n\n  a -= b; a -= c; a ^= (c >> 13);\n  b -= c; b -= a; b ^= (a << 8);\n  c -= a; c -= b; c ^= (b >> 13);\n  a -= b; a -= c; a ^= (c >> 12);\n  b -= c; b -= a; b ^= (a << 16);\n  c -= a; c -= b; c ^= (b >> 5);\n  a -= b; a -= c; a ^= (c >> 3);\n  b -= c; b -= a; b ^= (a << 10);\n  c -= a; c -= b; c ^= (b >> 15);\n\n  return c;\n}\n\nconst buffer = new Uint8Array(0x400);\n\n/**\n * A hash function used by Warcraft 3's Jass virtual machine.\n * \n * See http://burtleburtle.net/bob/hash/doobs.html\n */\nexport default function sstrhash2(key: string): number {\n  let offset = 0;\n\n  buffer.fill(0);\n\n  for (const char of key) {\n    const byte = char.charCodeAt(0);\n\n    if (byte < 97 || byte > 122) {\n      if (byte === 47) {\n        // slash to backwards slash.\n        buffer[offset] = 92;\n      } else {\n        buffer[offset] = byte;\n      }\n    } else {\n      // lower case ascii to upper case.\n      buffer[offset] = byte - 0x20;\n    }\n\n    offset += 1;\n  }\n\n  return hash(buffer);\n}\n"
  },
  {
    "path": "src/common/stringreverse.ts",
    "content": "/**\n * Reverses a string.\n */\nexport default function reverse(s: string): string {\n  return [...s].reverse().join('');\n}\n"
  },
  {
    "path": "src/common/typecast.ts",
    "content": "const buffer = new ArrayBuffer(8);\nconst int8 = new Int8Array(buffer);\nconst int16 = new Int16Array(buffer);\nconst int32 = new Int32Array(buffer);\nconst uint8 = new Uint8Array(buffer);\nconst uint16 = new Uint16Array(buffer);\nconst uint32 = new Uint32Array(buffer);\nconst float32 = new Float32Array(buffer);\nconst float64 = new Float64Array(buffer);\n\n/**\n * Typecast a 8 bit unsigned integer to a 8 bits signed integer.\n */\nexport function uint8ToInt8(a: number): number {\n  uint8[0] = a;\n\n  return int8[0];\n}\n\n/**\n * Typecast two 8 bit unsigned integers to a 16 bits signed integer.\n */\nexport function uint8ToInt16(a: number, b: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n\n  return int16[0];\n}\n\n/**\n * Typecast three 8 bit unsigned integers to a 24 bits signed integer.\n */\nexport function uint8ToInt24(a: number, b: number, c: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n  uint8[2] = c;\n  uint8[3] = 0;\n\n  return int32[0];\n}\n\n/**\n * Typecast four 8 bit unsigned integers to a 32 bits signed integer.\n */\nexport function uint8ToInt32(a: number, b: number, c: number, d: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n  uint8[2] = c;\n  uint8[3] = d;\n\n  return int32[0];\n}\n\n/**\n * Typecast two 8 bit unsigned integers to a 16 bits unsigned integer.\n */\nexport function uint8ToUint16(a: number, b: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n\n  return uint16[0];\n}\n\n/**\n * Typecast three 8 bit unsigned integers to a 24 bits unsigned integer.\n */\nexport function uint8ToUint24(a: number, b: number, c: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n  uint8[2] = c;\n  uint8[3] = 0;\n\n  return uint32[0];\n}\n\n/**\n * Typecast four 8 bit unsigned integers to a 32 bits unsigned integer.\n */\nexport function uint8ToUint32(a: number, b: number, c: number, d: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n  uint8[2] = c;\n  uint8[3] = d;\n\n  return uint32[0];\n}\n\n/**\n * Typecast four 8 bit unsigned integers to a 32 bits IEEE float.\n */\nexport function uint8ToFloat32(a: number, b: number, c: number, d: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n  uint8[2] = c;\n  uint8[3] = d;\n\n  return float32[0];\n}\n\n/**\n * Typecast eight 8 bit unsigned integers to a 64 bits IEEE float.\n */\nexport function uint8ToFloat64(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): number {\n  uint8[0] = a;\n  uint8[1] = b;\n  uint8[2] = c;\n  uint8[3] = d;\n  uint8[4] = e;\n  uint8[5] = f;\n  uint8[6] = g;\n  uint8[7] = h;\n\n  return float64[0];\n}\n\n/**\n * Typecast a 8 bit signed integer to a 8 bit unsigned integer.\n */\nexport function int8ToUint8(a: number): number {\n  uint8[0] = a;\n\n  return int8[0];\n}\n\n/**\n * Typecast a 16 bit signed integer to two 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function int16ToUint8(out: Uint8Array, a: number): Uint8Array {\n  int16[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n\n  return out;\n}\n\n/**\n * Typecast a 24 bit signed integer to three 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function int24ToUint8(out: Uint8Array, a: number): Uint8Array {\n  int32[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n  out[2] = uint8[2];\n\n  return out;\n}\n\n/**\n * Typecast a 32 bit signed integer to four 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function int32ToUint8(out: Uint8Array, a: number): Uint8Array {\n  int32[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n  out[2] = uint8[2];\n  out[3] = uint8[3];\n\n  return out;\n}\n\n/**\n * Typecast a 16 bit unsigned integer to two 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function uint16ToUint8(out: Uint8Array, a: number): Uint8Array {\n  uint16[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n\n  return out;\n}\n\n/**\n * Typecast a 24 bit unsigned integer to three 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function uint24ToUint8(out: Uint8Array, a: number): Uint8Array {\n  uint32[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n  out[2] = uint8[2];\n\n  return out;\n}\n\n/**\n * Typecast a 32 bit unsigned integer to four 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function uint32ToUint8(out: Uint8Array, a: number): Uint8Array {\n  uint32[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n  out[2] = uint8[2];\n  out[3] = uint8[3];\n\n  return out;\n}\n\n/**\n * Typecast a 32 bit IEEE float to four 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function float32ToUint8(out: Uint8Array, a: number): Uint8Array {\n  float32[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n  out[2] = uint8[2];\n  out[3] = uint8[3];\n\n  return out;\n}\n\n/**\n * Typecast a 64 bit IEEE float to eight 8 bit unsigned integers.\n * \n * The result is stored in out.\n */\nexport function float64ToUint8(out: Uint8Array, a: number): Uint8Array {\n  float64[0] = a;\n\n  out[0] = uint8[0];\n  out[1] = uint8[1];\n  out[2] = uint8[2];\n  out[3] = uint8[3];\n  out[4] = uint8[4];\n  out[5] = uint8[5];\n  out[6] = uint8[6];\n  out[7] = uint8[7];\n\n  return out;\n}\n\n/**\n * Typecast a normal JavaScript number to a 32 bits unsigned integer.\n */\nexport function numberToUint32(number: number): number {\n  uint32[0] = number;\n\n  return uint32[0];\n}\n\n/**\n * Interperts a string as a base 256 number.\n */\nexport function stringToBase256(string: string): number {\n  let number = 0;\n\n  for (const c of string) {\n    number = number * 256 + c.charCodeAt(0);\n  }\n\n  return number;\n}\n\n/**\n * Interperts a number as a base 256 string.\n */\nexport function base256ToString(number: number): string {\n  const array = [];\n\n  while (number > 0) {\n    array.push(String.fromCharCode(number % 256));\n    number = Math.floor(number / 256);\n  }\n\n  return array.reverse().join('');\n}\n"
  },
  {
    "path": "src/common/urlwithparams.ts",
    "content": "/**\n * Appends url parameters given in params to the url given in src.\n * \n * The source url can have url parameters already in it.\n */\nexport default function urlWithParams(src: string, params: {[key: string]: string }): string {\n  if (params) {\n    const entries = Object.entries(params);\n\n    if (entries.length) {\n      const encodedParams = entries.map(([key, value]) => `${key}=${value}`).join('&');\n      let separator = '&';\n\n      if (src.indexOf('?') === -1) {\n        separator = '?';\n      }\n\n      return `${src}${separator}${encodedParams}`;\n    }\n  }\n\n  return src;\n}\n"
  },
  {
    "path": "src/common/utf8.ts",
    "content": "const decoder = new TextDecoder();\nconst encoder = new TextEncoder();\n\n/**\n * Decode bytes as a UTF8 string.\n */\nexport function decodeUtf8(buffer: ArrayBuffer | Uint8Array): string {\n  return decoder.decode(buffer);\n}\n\n/**\n * Encode a UTF8 string to bytes.\n */\nexport function encodeUtf8(utf8: string): Uint8Array {\n  return encoder.encode(utf8);\n}\n\n/**\n * Get the byte length of a UTF8 string.\n * \n * @see https://stackoverflow.com/a/23329386\n */\nexport function byteLengthUtf8(str: string): number {\n  // returns the byte length of an utf8 string\n  let s = str.length;\n  for (let i = str.length - 1; i >= 0; i--) {\n    const code = str.charCodeAt(i);\n    if (code > 0x7f && code <= 0x7ff) s++;\n    else if (code > 0x7ff && code <= 0xffff) s += 2;\n    if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate\n  }\n  return s;\n}\n\n/**\n * Splits the given string into an array of strings.\n * \n * Each string will have a byte length smaller or equal to chunkBytelength when encoded as UTF8.\n * \n * @see https://stackoverflow.com/a/18729931\n */\nexport function splitUtf8ByteLength(str: string, chunkBytelength: number): string[] {\n  const chunks = [];\n  let pos = 0;\n  let bytes = 0;\n\n  for (let i = 0, l = str.length; i < l; i++) {\n    const code = str.charCodeAt(i);\n\n    if (code < 0x80) {\n      bytes += 1;\n    } else if (code < 0x800) {\n      bytes += 2;\n    } else if (code < 0xd800 || code >= 0xe000) {\n      bytes += 3;\n    } else {\n      i++;\n      bytes += 4;\n    }\n\n    if (bytes >= chunkBytelength - 3) {\n      chunks.push(str.substr(pos, i));\n\n      pos += i;\n      bytes = 0;\n    }\n  }\n\n  if (bytes > 0) {\n    chunks.push(str.substr(pos));\n  }\n\n  return chunks;\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "import { version } from './version';\nimport common from './common';\nimport parsers from './parsers';\nimport viewer from './viewer';\nimport utils from './utils';\n\nexport {\n  version,\n  common,\n  parsers,\n  viewer,\n  utils,\n};\n"
  },
  {
    "path": "src/parsers/blp/image.ts",
    "content": "import BitStream from '../../common/bitstream';\nimport { bytesOf } from '../../common/bytesof';\nimport convertBitRange from '../../common/convertbitrange';\nimport { JpegImage } from './jpg.js';\n\nexport const BLP1_MAGIC = 0x31504c42;\nexport const CONTENT_JPG = 0x0;\n// const CONTENT_PALLETE = 0x1;\n\n/**\n * A BLP1 image.\n */\nexport class BlpImage {\n  content = 0;\n  alphaBits = 0;\n  width = 0;\n  height = 0;\n  type = 0;\n  hasMipmaps = false;\n  mipmapOffsets = new Uint32Array(16);\n  mipmapSizes = new Uint32Array(16);\n  uint8array: Uint8Array | null = null;\n  /**\n   * Used for JPG images.\n   */\n  jpgHeader: Uint8Array | null = null;\n  /**\n   * Used for indexed images.\n   */\n  pallete: Uint8Array | null = null;\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const bytes = bytesOf(buffer);\n\n    // This includes the JPG header size, in case its a JPG image.\n    // Otherwise, the last element is ignored.\n    const header = new Int32Array(bytes.buffer, 0, 40);\n\n    if (header[0] !== BLP1_MAGIC) {\n      throw new Error('WrongMagicNumber');\n    }\n\n    this.content = header[1];\n    this.alphaBits = header[2];\n    this.width = header[3];\n    this.height = header[4];\n    this.type = header[5];\n    this.hasMipmaps = header[6] !== 0;\n\n    for (let i = 0; i < 16; i++) {\n      this.mipmapOffsets[i] = header[7 + i];\n      this.mipmapSizes[i] = header[23 + i];\n    }\n\n    this.uint8array = bytes;\n\n    if (this.content === CONTENT_JPG) {\n      this.jpgHeader = bytes.subarray(160, 160 + header[39]);\n    } else {\n      this.pallete = bytes.subarray(156, 156 + 1024);\n    }\n  }\n\n  getMipmap(level: number): ImageData {\n    const uint8array = <Uint8Array>this.uint8array;\n    const offset = this.mipmapOffsets[level];\n    const size = this.mipmapSizes[level];\n    let imageData: ImageData;\n\n    if (this.content === CONTENT_JPG) {\n      const jpgHeader = <Uint8Array>this.jpgHeader;\n      const data = new Uint8Array(jpgHeader.length + size);\n      const jpegImage = new JpegImage();\n\n      data.set(jpgHeader);\n      data.set(uint8array.subarray(offset, offset + size), jpgHeader.length);\n\n      jpegImage.parse(data);\n\n      // The JPG data might not actually match the correct mipmap size.\n      imageData = new ImageData(jpegImage.width, jpegImage.height);\n\n      jpegImage.getData(imageData);\n    } else {\n      const pallete = <Uint8Array>this.pallete;\n      const width = Math.max(this.width / (1 << level), 1); // max of 1 because for non-square textures one dimension will eventually be <1.\n      const height = Math.max(this.height / (1 << level), 1);\n      const size = width * height;\n      let alphaBits = this.alphaBits;\n      let bitStream;\n      let bitsToByte = 0;\n\n      imageData = new ImageData(width, height);\n\n      if (alphaBits > 0) {\n        if (alphaBits > 8) {\n          alphaBits = 8;\n        }\n        \n        bitStream = new BitStream(uint8array.buffer, offset + size, Math.ceil((size * alphaBits) / 8));\n        bitsToByte = convertBitRange(alphaBits, 8);\n      }\n\n      const data = imageData.data;\n\n      for (let i = 0; i < size; i++) {\n        const dataIndex = i * 4;\n        const paletteIndex = uint8array[offset + i] * 4;\n\n        // BGRA->RGBA\n        data[dataIndex] = pallete[paletteIndex + 2];\n        data[dataIndex + 1] = pallete[paletteIndex + 1];\n        data[dataIndex + 2] = pallete[paletteIndex];\n\n        if (alphaBits > 0) {\n          data[dataIndex + 3] = (<BitStream>bitStream).readBits(alphaBits) * bitsToByte;\n        } else {\n          data[dataIndex + 3] = 255;\n        }\n      }\n    }\n\n    return imageData;\n  }\n\n  mipmaps(): number {\n    let mipmaps = 0;\n\n    for (const size of this.mipmapSizes) {\n      if (size > 0) {\n        mipmaps += 1;\n      }\n    }\n\n    return mipmaps;\n  }\n\n  fakeMipmaps(): number {\n    const offsets = this.mipmapOffsets;\n    let mipmaps = 0;\n\n    for (let i = 0; i < 16; i++) {\n      const offset = offsets[i];\n\n      if (offset > 0) {\n        for (let j = i + 1; j < 16; j++) {\n          if (offset === offsets[j]) {\n            mipmaps += 1;\n            break;\n          }\n        }\n      }\n    }\n\n    return mipmaps;\n  }\n}\n"
  },
  {
    "path": "src/parsers/blp/index.ts",
    "content": "import { BlpImage as Image } from './image';\n\nexport default {\n  Image,\n};\n"
  },
  {
    "path": "src/parsers/blp/isformat.ts",
    "content": "/**\n * Detects if the given object is a BLP source.\n */\nexport default function isBlp(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x42 && bytes[1] === 0x4c && bytes[2] === 0x50 && bytes[3] === 0x31) {\n      return true;\n    }\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/parsers/blp/jpg.js",
    "content": "/* eslint-disable */\n\n/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the 'License');\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// NOTICE: This file was edited to support loading JPEG data stored in BLP files, which use a non-standard RGBA pixel format.\n// NOTICE2: It has been edited more to support modern building.\n\nconst _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (obj) {\n  return typeof obj;\n} : function (obj) {\n  return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;\n};\n\n\nconst JpegError = function JpegErrorClosure() {\n  function JpegError(msg) {\n    this.message = 'JPEG error: ' + msg;\n  }\n  JpegError.prototype = new Error();\n  JpegError.prototype.name = 'JpegError';\n  JpegError.constructor = JpegError;\n  return JpegError;\n}();\n\nconst dctZigZag = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]);\nconst dctCos1 = 4017;\nconst dctSin1 = 799;\nconst dctCos3 = 3406;\nconst dctSin3 = 2276;\nconst dctCos6 = 1567;\nconst dctSin6 = 3784;\nconst dctSqrt2 = 5793;\nconst dctSqrt1d2 = 2896;\n\nfunction buildHuffmanTable(codeLengths, values) {\n  let k = 0,\n    code = [],\n    i,\n    j,\n    length = 16;\n  while (length > 0 && !codeLengths[length - 1]) {\n    length--;\n  }\n  code.push({\n    children: [],\n    index: 0,\n  });\n  let p = code[0],\n    q;\n  for (i = 0; i < length; i++) {\n    for (j = 0; j < codeLengths[i]; j++) {\n      p = code.pop();\n      p.children[p.index] = values[k];\n      while (p.index > 0) {\n        p = code.pop();\n      }\n      p.index++;\n      code.push(p);\n      while (code.length <= i) {\n        code.push(q = {\n          children: [],\n          index: 0,\n        });\n        p.children[p.index] = q.children;\n        p = q;\n      }\n      k++;\n    }\n    if (i + 1 < length) {\n      code.push(q = {\n        children: [],\n        index: 0,\n      });\n      p.children[p.index] = q.children;\n      p = q;\n    }\n  }\n  return code[0].children;\n}\nfunction getBlockBufferOffset(component, row, col) {\n  return 64 * ((component.blocksPerLine + 1) * row + col);\n}\nfunction decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {\n  const mcusPerLine = frame.mcusPerLine;\n  const progressive = frame.progressive;\n  let startOffset = offset,\n    bitsData = 0,\n    bitsCount = 0;\n  function readBit() {\n    if (bitsCount > 0) {\n      bitsCount--;\n      return bitsData >> bitsCount & 1;\n    }\n    bitsData = data[offset++];\n    if (bitsData === 0xFF) {\n      const nextByte = data[offset++];\n      if (nextByte) {\n        throw new JpegError('unexpected marker ' + (bitsData << 8 | nextByte).toString(16));\n      }\n    }\n    bitsCount = 7;\n    return bitsData >>> 7;\n  }\n  function decodeHuffman(tree) {\n    let node = tree;\n    while (true) {\n      node = node[readBit()];\n      if (typeof node === 'number') {\n        return node;\n      }\n      if ((typeof node === 'undefined' ? 'undefined' : _typeof(node)) !== 'object') {\n        throw new JpegError('invalid huffman sequence');\n      }\n    }\n  }\n  function receive(length) {\n    let n = 0;\n    while (length > 0) {\n      n = n << 1 | readBit();\n      length--;\n    }\n    return n;\n  }\n  function receiveAndExtend(length) {\n    if (length === 1) {\n      return readBit() === 1 ? 1 : -1;\n    }\n    const n = receive(length);\n    if (n >= 1 << length - 1) {\n      return n;\n    }\n    return n + (-1 << length) + 1;\n  }\n  function decodeBaseline(component, offset) {\n    const t = decodeHuffman(component.huffmanTableDC);\n    const diff = t === 0 ? 0 : receiveAndExtend(t);\n    component.blockData[offset] = component.pred += diff;\n    let k = 1;\n    while (k < 64) {\n      const rs = decodeHuffman(component.huffmanTableAC);\n      const s = rs & 15,\n        r = rs >> 4;\n      if (s === 0) {\n        if (r < 15) {\n          break;\n        }\n        k += 16;\n        continue;\n      }\n      k += r;\n      const z = dctZigZag[k];\n      component.blockData[offset + z] = receiveAndExtend(s);\n      k++;\n    }\n  }\n  function decodeDCFirst(component, offset) {\n    const t = decodeHuffman(component.huffmanTableDC);\n    const diff = t === 0 ? 0 : receiveAndExtend(t) << successive;\n    component.blockData[offset] = component.pred += diff;\n  }\n  function decodeDCSuccessive(component, offset) {\n    component.blockData[offset] |= readBit() << successive;\n  }\n  let eobrun = 0;\n  function decodeACFirst(component, offset) {\n    if (eobrun > 0) {\n      eobrun--;\n      return;\n    }\n    let k = spectralStart,\n      e = spectralEnd;\n    while (k <= e) {\n      const rs = decodeHuffman(component.huffmanTableAC);\n      const s = rs & 15,\n        r = rs >> 4;\n      if (s === 0) {\n        if (r < 15) {\n          eobrun = receive(r) + (1 << r) - 1;\n          break;\n        }\n        k += 16;\n        continue;\n      }\n      k += r;\n      const z = dctZigZag[k];\n      component.blockData[offset + z] = receiveAndExtend(s) * (1 << successive);\n      k++;\n    }\n  }\n  let successiveACState = 0,\n    successiveACNextValue;\n  function decodeACSuccessive(component, offset) {\n    let k = spectralStart;\n    const e = spectralEnd;\n    let r = 0;\n    let s;\n    let rs;\n    while (k <= e) {\n      const z = dctZigZag[k];\n      switch (successiveACState) {\n        case 0:\n          rs = decodeHuffman(component.huffmanTableAC);\n          s = rs & 15;\n          r = rs >> 4;\n          if (s === 0) {\n            if (r < 15) {\n              eobrun = receive(r) + (1 << r);\n              successiveACState = 4;\n            } else {\n              r = 16;\n              successiveACState = 1;\n            }\n          } else {\n            if (s !== 1) {\n              throw new JpegError('invalid ACn encoding');\n            }\n            successiveACNextValue = receiveAndExtend(s);\n            successiveACState = r ? 2 : 3;\n          }\n          continue;\n        case 1:\n        case 2:\n          if (component.blockData[offset + z]) {\n            component.blockData[offset + z] += readBit() << successive;\n          } else {\n            r--;\n            if (r === 0) {\n              successiveACState = successiveACState === 2 ? 3 : 0;\n            }\n          }\n          break;\n        case 3:\n          if (component.blockData[offset + z]) {\n            component.blockData[offset + z] += readBit() << successive;\n          } else {\n            component.blockData[offset + z] = successiveACNextValue << successive;\n            successiveACState = 0;\n          }\n          break;\n        case 4:\n          if (component.blockData[offset + z]) {\n            component.blockData[offset + z] += readBit() << successive;\n          }\n          break;\n      }\n      k++;\n    }\n    if (successiveACState === 4) {\n      eobrun--;\n      if (eobrun === 0) {\n        successiveACState = 0;\n      }\n    }\n  }\n  function decodeMcu(component, decode, mcu, row, col) {\n    const mcuRow = mcu / mcusPerLine | 0;\n    const mcuCol = mcu % mcusPerLine;\n    const blockRow = mcuRow * component.v + row;\n    const blockCol = mcuCol * component.h + col;\n    const offset = getBlockBufferOffset(component, blockRow, blockCol);\n    decode(component, offset);\n  }\n  function decodeBlock(component, decode, mcu) {\n    const blockRow = mcu / component.blocksPerLine | 0;\n    const blockCol = mcu % component.blocksPerLine;\n    const offset = getBlockBufferOffset(component, blockRow, blockCol);\n    decode(component, offset);\n  }\n  const componentsLength = components.length;\n  let component, i, j, k, n;\n  let decodeFn;\n  if (progressive) {\n    if (spectralStart === 0) {\n      decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;\n    } else {\n      decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive;\n    }\n  } else {\n    decodeFn = decodeBaseline;\n  }\n  let mcu = 0,\n    fileMarker;\n  let mcuExpected;\n  if (componentsLength === 1) {\n    mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;\n  } else {\n    mcuExpected = mcusPerLine * frame.mcusPerColumn;\n  }\n  let h, v;\n  while (mcu < mcuExpected) {\n    const mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected;\n    for (i = 0; i < componentsLength; i++) {\n      components[i].pred = 0;\n    }\n    eobrun = 0;\n    if (componentsLength === 1) {\n      component = components[0];\n      for (n = 0; n < mcuToRead; n++) {\n        decodeBlock(component, decodeFn, mcu);\n        mcu++;\n      }\n    } else {\n      for (n = 0; n < mcuToRead; n++) {\n        for (i = 0; i < componentsLength; i++) {\n          component = components[i];\n          h = component.h;\n          v = component.v;\n          for (j = 0; j < v; j++) {\n            for (k = 0; k < h; k++) {\n              decodeMcu(component, decodeFn, mcu, j, k);\n            }\n          }\n        }\n        mcu++;\n      }\n    }\n    bitsCount = 0;\n    fileMarker = findNextFileMarker(data, offset);\n    if (fileMarker && fileMarker.invalid) {\n      // (0, _util.warn)('decodeScan - unexpected MCU data, next marker is: ' + fileMarker.invalid);\n      offset = fileMarker.offset;\n    }\n    const marker = fileMarker && fileMarker.marker;\n    if (!marker || marker <= 0xFF00) {\n      throw new JpegError('marker was not found');\n    }\n    if (marker >= 0xFFD0 && marker <= 0xFFD7) {\n      offset += 2;\n    } else {\n      break;\n    }\n  }\n  fileMarker = findNextFileMarker(data, offset);\n  if (fileMarker && fileMarker.invalid) {\n    // (0, _util.warn)('decodeScan - unexpected Scan data, next marker is: ' + fileMarker.invalid);\n    offset = fileMarker.offset;\n  }\n  return offset - startOffset;\n}\nfunction quantizeAndInverse(component, blockBufferOffset, p) {\n  const qt = component.quantizationTable,\n    blockData = component.blockData;\n  let v0, v1, v2, v3, v4, v5, v6, v7;\n  let p0, p1, p2, p3, p4, p5, p6, p7;\n  let t;\n  if (!qt) {\n    throw new JpegError('missing required Quantization Table.');\n  }\n  for (let row = 0; row < 64; row += 8) {\n    p0 = blockData[blockBufferOffset + row];\n    p1 = blockData[blockBufferOffset + row + 1];\n    p2 = blockData[blockBufferOffset + row + 2];\n    p3 = blockData[blockBufferOffset + row + 3];\n    p4 = blockData[blockBufferOffset + row + 4];\n    p5 = blockData[blockBufferOffset + row + 5];\n    p6 = blockData[blockBufferOffset + row + 6];\n    p7 = blockData[blockBufferOffset + row + 7];\n    p0 *= qt[row];\n    if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {\n      t = dctSqrt2 * p0 + 512 >> 10;\n      p[row] = t;\n      p[row + 1] = t;\n      p[row + 2] = t;\n      p[row + 3] = t;\n      p[row + 4] = t;\n      p[row + 5] = t;\n      p[row + 6] = t;\n      p[row + 7] = t;\n      continue;\n    }\n    p1 *= qt[row + 1];\n    p2 *= qt[row + 2];\n    p3 *= qt[row + 3];\n    p4 *= qt[row + 4];\n    p5 *= qt[row + 5];\n    p6 *= qt[row + 6];\n    p7 *= qt[row + 7];\n    v0 = dctSqrt2 * p0 + 128 >> 8;\n    v1 = dctSqrt2 * p4 + 128 >> 8;\n    v2 = p2;\n    v3 = p6;\n    v4 = dctSqrt1d2 * (p1 - p7) + 128 >> 8;\n    v7 = dctSqrt1d2 * (p1 + p7) + 128 >> 8;\n    v5 = p3 << 4;\n    v6 = p5 << 4;\n    v0 = v0 + v1 + 1 >> 1;\n    v1 = v0 - v1;\n    t = v2 * dctSin6 + v3 * dctCos6 + 128 >> 8;\n    v2 = v2 * dctCos6 - v3 * dctSin6 + 128 >> 8;\n    v3 = t;\n    v4 = v4 + v6 + 1 >> 1;\n    v6 = v4 - v6;\n    v7 = v7 + v5 + 1 >> 1;\n    v5 = v7 - v5;\n    v0 = v0 + v3 + 1 >> 1;\n    v3 = v0 - v3;\n    v1 = v1 + v2 + 1 >> 1;\n    v2 = v1 - v2;\n    t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;\n    v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;\n    v7 = t;\n    t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;\n    v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;\n    v6 = t;\n    p[row] = v0 + v7;\n    p[row + 7] = v0 - v7;\n    p[row + 1] = v1 + v6;\n    p[row + 6] = v1 - v6;\n    p[row + 2] = v2 + v5;\n    p[row + 5] = v2 - v5;\n    p[row + 3] = v3 + v4;\n    p[row + 4] = v3 - v4;\n  }\n  for (let col = 0; col < 8; ++col) {\n    p0 = p[col];\n    p1 = p[col + 8];\n    p2 = p[col + 16];\n    p3 = p[col + 24];\n    p4 = p[col + 32];\n    p5 = p[col + 40];\n    p6 = p[col + 48];\n    p7 = p[col + 56];\n    if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {\n      t = dctSqrt2 * p0 + 8192 >> 14;\n      t = t < -2040 ? 0 : t >= 2024 ? 255 : t + 2056 >> 4;\n      blockData[blockBufferOffset + col] = t;\n      blockData[blockBufferOffset + col + 8] = t;\n      blockData[blockBufferOffset + col + 16] = t;\n      blockData[blockBufferOffset + col + 24] = t;\n      blockData[blockBufferOffset + col + 32] = t;\n      blockData[blockBufferOffset + col + 40] = t;\n      blockData[blockBufferOffset + col + 48] = t;\n      blockData[blockBufferOffset + col + 56] = t;\n      continue;\n    }\n    v0 = dctSqrt2 * p0 + 2048 >> 12;\n    v1 = dctSqrt2 * p4 + 2048 >> 12;\n    v2 = p2;\n    v3 = p6;\n    v4 = dctSqrt1d2 * (p1 - p7) + 2048 >> 12;\n    v7 = dctSqrt1d2 * (p1 + p7) + 2048 >> 12;\n    v5 = p3;\n    v6 = p5;\n    v0 = (v0 + v1 + 1 >> 1) + 4112;\n    v1 = v0 - v1;\n    t = v2 * dctSin6 + v3 * dctCos6 + 2048 >> 12;\n    v2 = v2 * dctCos6 - v3 * dctSin6 + 2048 >> 12;\n    v3 = t;\n    v4 = v4 + v6 + 1 >> 1;\n    v6 = v4 - v6;\n    v7 = v7 + v5 + 1 >> 1;\n    v5 = v7 - v5;\n    v0 = v0 + v3 + 1 >> 1;\n    v3 = v0 - v3;\n    v1 = v1 + v2 + 1 >> 1;\n    v2 = v1 - v2;\n    t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;\n    v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;\n    v7 = t;\n    t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;\n    v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;\n    v6 = t;\n    p0 = v0 + v7;\n    p7 = v0 - v7;\n    p1 = v1 + v6;\n    p6 = v1 - v6;\n    p2 = v2 + v5;\n    p5 = v2 - v5;\n    p3 = v3 + v4;\n    p4 = v3 - v4;\n    p0 = p0 < 16 ? 0 : p0 >= 4080 ? 255 : p0 >> 4;\n    p1 = p1 < 16 ? 0 : p1 >= 4080 ? 255 : p1 >> 4;\n    p2 = p2 < 16 ? 0 : p2 >= 4080 ? 255 : p2 >> 4;\n    p3 = p3 < 16 ? 0 : p3 >= 4080 ? 255 : p3 >> 4;\n    p4 = p4 < 16 ? 0 : p4 >= 4080 ? 255 : p4 >> 4;\n    p5 = p5 < 16 ? 0 : p5 >= 4080 ? 255 : p5 >> 4;\n    p6 = p6 < 16 ? 0 : p6 >= 4080 ? 255 : p6 >> 4;\n    p7 = p7 < 16 ? 0 : p7 >= 4080 ? 255 : p7 >> 4;\n    blockData[blockBufferOffset + col] = p0;\n    blockData[blockBufferOffset + col + 8] = p1;\n    blockData[blockBufferOffset + col + 16] = p2;\n    blockData[blockBufferOffset + col + 24] = p3;\n    blockData[blockBufferOffset + col + 32] = p4;\n    blockData[blockBufferOffset + col + 40] = p5;\n    blockData[blockBufferOffset + col + 48] = p6;\n    blockData[blockBufferOffset + col + 56] = p7;\n  }\n}\nfunction buildComponentData(frame, component) {\n  const blocksPerLine = component.blocksPerLine;\n  const blocksPerColumn = component.blocksPerColumn;\n  const computationBuffer = new Int16Array(64);\n  for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {\n    for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {\n      const offset = getBlockBufferOffset(component, blockRow, blockCol);\n      quantizeAndInverse(component, offset, computationBuffer);\n    }\n  }\n  return component.blockData;\n}\nfunction clamp0to255(a) {\n  return a <= 0 ? 0 : a >= 255 ? 255 : a;\n}\nfunction findNextFileMarker(data, currentPos, startPos) {\n  function peekUint16(pos) {\n    return data[pos] << 8 | data[pos + 1];\n  }\n  const maxPos = data.length - 1;\n  let newPos = startPos < currentPos ? startPos : currentPos;\n  if (currentPos >= maxPos) {\n    return null;\n  }\n  const currentMarker = peekUint16(currentPos);\n  if (currentMarker >= 0xFFC0 && currentMarker <= 0xFFFE) {\n    return {\n      invalid: null,\n      marker: currentMarker,\n      offset: currentPos,\n    };\n  }\n  let newMarker = peekUint16(newPos);\n  while (!(newMarker >= 0xFFC0 && newMarker <= 0xFFFE)) {\n    if (++newPos >= maxPos) {\n      return null;\n    }\n    newMarker = peekUint16(newPos);\n  }\n  return {\n    invalid: currentMarker.toString(16),\n    marker: newMarker,\n    offset: newPos,\n  };\n}\n\nexport class JpegImage {\n  constructor() {\n    this.decodeTransform = null;\n    this.colorTransform = -1;\n    this.width = 0;\n    this.height = 0;\n  }\n\n  parse(data) {\n    function readUint16() {\n      const value = data[offset] << 8 | data[offset + 1];\n      offset += 2;\n      return value;\n    }\n    function readDataBlock() {\n      const length = readUint16();\n      let endOffset = offset + length - 2;\n      const fileMarker = findNextFileMarker(data, endOffset, offset);\n      if (fileMarker && fileMarker.invalid) {\n        // (0, _util.warn)('readDataBlock - incorrect length, next marker is: ' + fileMarker.invalid);\n        endOffset = fileMarker.offset;\n      }\n      const array = data.subarray(offset, endOffset);\n      offset += array.length;\n      return array;\n    }\n    function prepareComponents(frame) {\n      const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);\n      const mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);\n      for (let i = 0; i < frame.components.length; i++) {\n        component = frame.components[i];\n        const blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / frame.maxH);\n        const blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * component.v / frame.maxV);\n        const blocksPerLineForMcu = mcusPerLine * component.h;\n        const blocksPerColumnForMcu = mcusPerColumn * component.v;\n        const blocksBufferSize = 64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);\n        component.blockData = new Int16Array(blocksBufferSize);\n        component.blocksPerLine = blocksPerLine;\n        component.blocksPerColumn = blocksPerColumn;\n      }\n      frame.mcusPerLine = mcusPerLine;\n      frame.mcusPerColumn = mcusPerColumn;\n    }\n    var offset = 0;\n    let jfif = null;\n    let adobe = null;\n    let frame, resetInterval;\n    const quantizationTables = [];\n    const huffmanTablesAC = [],\n      huffmanTablesDC = [];\n    let fileMarker = readUint16();\n    if (fileMarker !== 0xFFD8) {\n      throw new JpegError('SOI not found');\n    }\n    fileMarker = readUint16();\n    while (fileMarker !== 0xFFD9) {\n      var i, j, l;\n      switch (fileMarker) {\n        case 0xFFE0:\n        case 0xFFE1:\n        case 0xFFE2:\n        case 0xFFE3:\n        case 0xFFE4:\n        case 0xFFE5:\n        case 0xFFE6:\n        case 0xFFE7:\n        case 0xFFE8:\n        case 0xFFE9:\n        case 0xFFEA:\n        case 0xFFEB:\n        case 0xFFEC:\n        case 0xFFED:\n        case 0xFFEE:\n        case 0xFFEF:\n        case 0xFFFE:\n          var appData = readDataBlock();\n          if (fileMarker === 0xFFE0) {\n            if (appData[0] === 0x4A && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) {\n              jfif = {\n                version: {\n                  major: appData[5],\n                  minor: appData[6],\n                },\n                densityUnits: appData[7],\n                xDensity: appData[8] << 8 | appData[9],\n                yDensity: appData[10] << 8 | appData[11],\n                thumbWidth: appData[12],\n                thumbHeight: appData[13],\n                thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13]),\n              };\n            }\n          }\n          if (fileMarker === 0xFFEE) {\n            if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6F && appData[3] === 0x62 && appData[4] === 0x65) {\n              adobe = {\n                version: appData[5] << 8 | appData[6],\n                flags0: appData[7] << 8 | appData[8],\n                flags1: appData[9] << 8 | appData[10],\n                transformCode: appData[11],\n              };\n            }\n          }\n          break;\n        case 0xFFDB:\n          var quantizationTablesLength = readUint16();\n          var quantizationTablesEnd = quantizationTablesLength + offset - 2;\n          var z;\n          while (offset < quantizationTablesEnd) {\n            const quantizationTableSpec = data[offset++];\n            const tableData = new Uint16Array(64);\n            if (quantizationTableSpec >> 4 === 0) {\n              for (j = 0; j < 64; j++) {\n                z = dctZigZag[j];\n                tableData[z] = data[offset++];\n              }\n            } else if (quantizationTableSpec >> 4 === 1) {\n              for (j = 0; j < 64; j++) {\n                z = dctZigZag[j];\n                tableData[z] = readUint16();\n              }\n            } else {\n              throw new JpegError('DQT - invalid table spec');\n            }\n            quantizationTables[quantizationTableSpec & 15] = tableData;\n          }\n          break;\n        case 0xFFC0:\n        case 0xFFC1:\n        case 0xFFC2:\n          if (frame) {\n            throw new JpegError('Only single frame JPEGs supported');\n          }\n          readUint16();\n          frame = {};\n          frame.extended = fileMarker === 0xFFC1;\n          frame.progressive = fileMarker === 0xFFC2;\n          frame.precision = data[offset++];\n          frame.scanLines = readUint16();\n          frame.samplesPerLine = readUint16();\n          frame.components = [];\n          frame.componentIds = {};\n          var componentsCount = data[offset++],\n            componentId;\n          var maxH = 0,\n            maxV = 0;\n          for (i = 0; i < componentsCount; i++) {\n            componentId = data[offset];\n            const h = data[offset + 1] >> 4;\n            const v = data[offset + 1] & 15;\n            if (maxH < h) {\n              maxH = h;\n            }\n            if (maxV < v) {\n              maxV = v;\n            }\n            const qId = data[offset + 2];\n            l = frame.components.push({\n              h: h,\n              v: v,\n              quantizationId: qId,\n              quantizationTable: null,\n            });\n            frame.componentIds[componentId] = l - 1;\n            offset += 3;\n          }\n          frame.maxH = maxH;\n          frame.maxV = maxV;\n          prepareComponents(frame);\n          break;\n        case 0xFFC4:\n          var huffmanLength = readUint16();\n          for (i = 2; i < huffmanLength;) {\n            const huffmanTableSpec = data[offset++];\n            const codeLengths = new Uint8Array(16);\n            let codeLengthSum = 0;\n            for (j = 0; j < 16; j++, offset++) {\n              codeLengthSum += codeLengths[j] = data[offset];\n            }\n            const huffmanValues = new Uint8Array(codeLengthSum);\n            for (j = 0; j < codeLengthSum; j++, offset++) {\n              huffmanValues[j] = data[offset];\n            }\n            i += 17 + codeLengthSum;\n            (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);\n          }\n          break;\n        case 0xFFDD:\n          readUint16();\n          resetInterval = readUint16();\n          break;\n        case 0xFFDA:\n          readUint16();\n          var selectorsCount = data[offset++];\n          var components = [],\n            component;\n          for (i = 0; i < selectorsCount; i++) {\n            const componentIndex = frame.componentIds[data[offset++]];\n            component = frame.components[componentIndex];\n            const tableSpec = data[offset++];\n            component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4];\n            component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];\n            components.push(component);\n          }\n          var spectralStart = data[offset++];\n          var spectralEnd = data[offset++];\n          var successiveApproximation = data[offset++];\n          var processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15);\n          offset += processed;\n          break;\n        case 0xFFFF:\n          if (data[offset] !== 0xFF) {\n            offset--;\n          }\n          break;\n        default:\n          if (data[offset - 3] === 0xFF && data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) {\n            offset -= 3;\n            break;\n          }\n          throw new JpegError('unknown marker ' + fileMarker.toString(16));\n      }\n      fileMarker = readUint16();\n    }\n    this.width = frame.samplesPerLine;\n    this.height = frame.scanLines;\n    this.jfif = jfif;\n    this.adobe = adobe;\n    this.components = [];\n    for (i = 0; i < frame.components.length; i++) {\n      component = frame.components[i];\n      const quantizationTable = quantizationTables[component.quantizationId];\n      if (quantizationTable) {\n        component.quantizationTable = quantizationTable;\n      }\n      this.components.push({\n        output: buildComponentData(frame, component),\n        scaleX: component.h / frame.maxH,\n        scaleY: component.v / frame.maxV,\n        blocksPerLine: component.blocksPerLine,\n        blocksPerColumn: component.blocksPerColumn,\n      });\n    }\n    this.numComponents = this.components.length;\n  }\n  getData(imageData) {\n    const data = imageData.data;\n    const components = this.components;\n    const lineData = new Uint8Array((components[0].blocksPerLine << 3) * components[0].blocksPerColumn * 8);\n\n    // NOTICE: This forces BGR->RGB conversion without adding any costs, since really we know this is going to be a hacky BGRA BLP file.\n    [components[0], components[2]] = [components[2], components[0]];\n\n    for (let i = 0, numComponents = components.length; i < numComponents; i++) {\n      const component = components[i];\n      const blocksPerLine = component.blocksPerLine;\n      const blocksPerColumn = component.blocksPerColumn;\n      const samplesPerLine = blocksPerLine << 3;\n      var j, k, ll = 0;\n      var lineOffset = 0;\n\n      for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {\n        const scanLine = blockRow << 3;\n\n        for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {\n          const bufferOffset = getBlockBufferOffset(component, blockRow, blockCol);\n          let offset2 = 0, sample = blockCol << 3;\n\n          for (j = 0; j < 8; j++) {\n            var lineOffset = (scanLine + j) * samplesPerLine;\n\n            for (k = 0; k < 8; k++) {\n              lineData[lineOffset + sample + k] = component.output[bufferOffset + offset2++];\n            }\n          }\n        }\n      }\n\n      let offset = i;\n\n      for (let y = 0; y < this.height; y++) {\n        for (let x = 0; x < this.width; x++) {\n          data[offset] = lineData[y * samplesPerLine + x];\n          offset += numComponents;\n        }\n      }\n    }\n\n    return data;\n  }\n}\n"
  },
  {
    "path": "src/parsers/dds/image.ts",
    "content": "import { base256ToString } from '../../common/typecast';\nimport { decodeDxt1, decodeDxt3, decodeDxt5, decodeRgtc } from '../../common/dxt';\nimport { bytesOf } from '../../common/bytesof';\n\nexport const DDS_MAGIC = 0x20534444;\nconst DDSD_MIPMAPCOUNT = 0x20000;\nconst DDPF_FOURCC = 0x4;\n\nexport const FOURCC_DXT1 = 0x31545844;\nexport const FOURCC_DXT3 = 0x33545844;\nexport const FOURCC_DXT5 = 0x35545844;\nexport const FOURCC_ATI2 = 0x32495441;\n\nconst FOURCC_DX10 = 0x30315844;\nconst DXGI_FORMAT_BC1_UNORM = 0x00000047;\nconst DXGI_FORMAT_BC2_UNORM = 0x0000004A;\nconst DXGI_FORMAT_BC3_UNORM = 0x0000004D;\nconst DXGI_FORMAT_BC5_UNORM = 0x00000053;\n\n/**\n * A DDS image.\n */\nexport class DdsImage {\n  width = 0;\n  height = 0;\n  format = 0;\n  mipmapWidths: number[] = [];\n  mipmapHeights: number[] = [];\n  mipmapDatas: Uint8Array[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const bytes = bytesOf(buffer);\n    const header = new Int32Array(bytes.buffer, 0, 31);\n    let offset = 128; // sizeof(DDS_HEADER) + 4 for the magic.\n\n    if (header[0] !== DDS_MAGIC) {\n      throw new Error('Wrong magic number');\n    }\n\n    if (!(header[20] & DDPF_FOURCC)) {\n      throw new Error('Not FourCC');\n    }\n\n    let fourCC = header[21];\n    \n    if (fourCC !== FOURCC_DXT1 && fourCC !== FOURCC_DXT3 && fourCC !== FOURCC_DXT5 && fourCC !== FOURCC_ATI2) {\n      if (fourCC === FOURCC_DX10) {\n        offset += 20; // sizeof(DDS_HEADER_DXT10)\n\n        const extendedHeader = new Int32Array(bytes.buffer, 128, 5);\n        const dxgiFormat = extendedHeader[0];\n\n        if (dxgiFormat === DXGI_FORMAT_BC1_UNORM) {\n          fourCC = FOURCC_DXT1;\n        } else if (dxgiFormat === DXGI_FORMAT_BC2_UNORM) {\n          fourCC = FOURCC_DXT3;\n        } else if (dxgiFormat === DXGI_FORMAT_BC3_UNORM) {\n          fourCC = FOURCC_DXT5;\n        } else if (dxgiFormat === DXGI_FORMAT_BC5_UNORM) {\n          fourCC = FOURCC_ATI2;\n        } else {\n          throw new Error(`Unsupported DXGI format: ${dxgiFormat}`);\n        }\n\n        console.log(extendedHeader);\n      } else {\n        throw new Error(`Unsupported FourCC: ${base256ToString(fourCC)}`);\n      }\n    }\n\n    this.format = fourCC;\n\n    let mipmaps = 1;\n\n    if (header[2] & DDSD_MIPMAPCOUNT) {\n      mipmaps = Math.max(1, header[7]);\n    }\n\n    let width = header[4];\n    let height = header[3];\n    let blockSize = 16;\n\n    // DXT3, DXT5, and RGTC, all have 16 bytes per block.\n    if (fourCC === FOURCC_DXT1) {\n      blockSize = 8;\n    }\n\n    this.width = width;\n    this.height = height;\n\n    for (let i = 0; i < mipmaps; i++) {\n      const size = Math.max(4, width) / 4 * Math.max(4, height) / 4 * blockSize;\n\n      this.mipmapWidths[i] = width;\n      this.mipmapHeights[i] = height;\n      this.mipmapDatas[i] = bytes.subarray(offset, offset + size);\n\n      offset += size;\n      width = Math.max(width / 2, 1);\n      height = Math.max(height / 2, 1);\n    }\n  }\n\n  mipmaps(): number {\n    return this.mipmapDatas.length;\n  }\n\n  getMipmap(level: number, raw = false): { width: number, height: number, data: Uint8Array } {\n    const width = this.mipmapWidths[level];\n    const height = this.mipmapHeights[level];\n    const data = this.mipmapDatas[level];\n    let mipmap: Uint16Array | Uint8Array;\n\n    if (raw) {\n      mipmap = data;\n    } else if (this.format === FOURCC_DXT1) {\n      mipmap = decodeDxt1(data, width, height);\n    } else if (this.format === FOURCC_DXT3) {\n      mipmap = decodeDxt3(data, width, height);\n    } else if (this.format === FOURCC_DXT5) {\n      mipmap = decodeDxt5(data, width, height);\n    } else {\n      mipmap = decodeRgtc(data, width, height);\n    }\n\n    return { width, height, data: mipmap };\n  }\n}\n"
  },
  {
    "path": "src/parsers/dds/index.ts",
    "content": "import { DdsImage as Image, FOURCC_DXT1, FOURCC_DXT3, FOURCC_DXT5, FOURCC_ATI2 } from './image';\nimport isDds from './isformat';\n\nexport default {\n  Image,\n  FOURCC_DXT1,\n  FOURCC_DXT3,\n  FOURCC_DXT5,\n  FOURCC_ATI2,\n  isDds,\n};\n"
  },
  {
    "path": "src/parsers/dds/isformat.ts",
    "content": "/**\n * Detects if the given object is a DDS source.\n */\nexport default function isDds(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x44 && bytes[1] === 0x44 && bytes[2] === 0x53 && bytes[3] === 0x20) {\n      return true;\n    }\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/parsers/index.ts",
    "content": "import ini from './ini';\nimport slk from './slk';\nimport m3 from './m3';\nimport mdlx from './mdlx';\nimport mpq from './mpq';\nimport w3x from './w3x';\nimport blp from './blp';\nimport dds from './dds';\nimport tga from './tga';\n\nexport default {\n  ini,\n  slk,\n  m3,\n  mdlx,\n  mpq,\n  w3x,\n  blp,\n  dds,\n  tga,\n};\n"
  },
  {
    "path": "src/parsers/ini/file.ts",
    "content": "/**\n * An INI section.\n */\nexport type IniSection = Map<string, string>;\n\n/**\n * An INI file.\n */\nexport class IniFile {\n  properties: Map<string, string> = new Map();\n  sections: Map<string, IniSection> = new Map();\n\n  load(buffer: string): void {\n    // All properties added until a section is reached are added to the properties map.\n    // Once a section is reached, any further properties will be added to it until matching another section, etc.\n    let section: IniSection | null = this.properties;\n    const sections = this.sections;\n\n    for (const line of buffer.split('\\r\\n')) {\n      // INI defines comments as starting with a semicolon ';'.\n      // However, Warcraft 3 INI files use normal C comments '//'.\n      // In addition, Warcraft 3 files have empty lines.\n      // Therefore, ignore any line matching any of these conditions.\n      if (line.length && !line.startsWith('//') && !line.startsWith(';')) {\n        let match = line.match(/^\\[(.+?)\\]/);\n\n        if (match) {\n          const name = match[1].trim();\n\n          section = <IniSection | null>sections.get(name);\n\n          if (!section) {\n            section = new Map();\n\n            sections.set(name, section);\n          }\n        } else {\n          match = line.match(/^(.+?)=(.*?)$/);\n\n          if (match) {\n            let value = match[2];\n\n            if (value[0] === '\"') {\n              value = value.slice(1, -1);\n            }\n\n            section.set(match[1], value);\n          }\n        }\n      }\n    }\n  }\n\n  save(): string {\n    const lines = [];\n\n    for (const [key, value] of this.properties) {\n      lines.push(`${key}=${value}`);\n    }\n\n    for (const [name, section] of this.sections) {\n      lines.push(`[${name}]`);\n\n      for (const [key, value] of section) {\n        lines.push(`${key}=${value}`);\n      }\n    }\n\n    return lines.join('\\r\\n');\n  }\n\n  getSection(name: string): IniSection | undefined {\n    return this.sections.get(name);\n  }\n}\n"
  },
  {
    "path": "src/parsers/ini/index.ts",
    "content": "import { IniFile as File } from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/parsers/m3/animationreference.ts",
    "content": "import BinaryStream from '../../common/binarystream';\n\n/**\n * The base class to all animation references.\n */\nexport abstract class AnimationReference {\n  interpolationType = 0;\n  animFlags = 0;\n  animId = -1;\n  initValue: number | Uint8Array | Float32Array | null = null;\n  nullValue: number | Uint8Array | Float32Array | null = null;\n\n  abstract readInitNullValues(stream: BinaryStream): void;\n\n  load(stream: BinaryStream): void {\n    this.interpolationType = stream.readUint16();\n    this.animFlags = stream.readUint16();\n    this.animId = stream.readUint32();\n\n    this.readInitNullValues(stream);\n\n    stream.skip(4); // ?\n  }\n}\n\n/**\n * A pixel animation reference.\n */\nexport class PixelAnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readUint8Array(4);\n    this.nullValue = stream.readUint8Array(4);\n  }\n}\n\n/**\n * A uint16 animation reference.\n */\nexport class Uint16AnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readUint16();\n    this.nullValue = stream.readUint16();\n  }\n}\n\n/**\n * A uint32 animation reference.\n */\nexport class Uint32AnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readUint32();\n    this.nullValue = stream.readUint32();\n  }\n}\n\n/**\n * A float32 animation reference.\n */\nexport class Float32AnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readFloat32();\n    this.nullValue = stream.readFloat32();\n  }\n}\n\n/**\n * A vec2 animation reference.\n */\nexport class Vector2AnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readFloat32Array(2);\n    this.nullValue = stream.readFloat32Array(2);\n  }\n}\n\n/**\n * A vec3 animation reference.\n */\nexport class Vector3AnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readFloat32Array(3);\n    this.nullValue = stream.readFloat32Array(3);\n  }\n}\n\n/**\n * A quat animation reference.\n */\nexport class Vector4AnimationReference extends AnimationReference {\n  readInitNullValues(stream: BinaryStream): void {\n    this.initValue = stream.readFloat32Array(4);\n    this.nullValue = stream.readFloat32Array(4);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/attachmentpoint.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * An attachment point.\n */\nexport default class AttachmentPoint {\n  version = -1;\n  unknown = 0;\n  name = new Reference();\n  bone = -1;\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.unknown = stream.readInt32();\n    this.name.load(stream, index);\n    this.bone = stream.readUint32();\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/batch.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\n\n/**\n * A batch.\n */\nexport default class Batch {\n  version = -1;\n  unknown0 = 0;\n  regionIndex = -1;\n  unknown1 = 0;\n  materialReferenceIndex = -1;\n  unknown2 = 0;\n\n  load(stream: BinaryStream, version: number, _index: IndexEntry[]): void {\n    this.version = version;\n    this.unknown0 = stream.readUint32();\n    this.regionIndex = stream.readUint16();\n    this.unknown1 = stream.readUint32();\n    this.materialReferenceIndex = stream.readUint16();\n    this.unknown2 = stream.readUint16();\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/bone.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\nimport { Uint32AnimationReference, Vector3AnimationReference, Vector4AnimationReference } from './animationreference';\n\n/**\n * A bone.\n */\nexport default class Bone {\n  version = -1;\n  unknown0 = 0;\n  name = new Reference();\n  flags = 0;\n  parent = -1;\n  unknown1 = 0;\n  location = new Vector3AnimationReference();\n  rotation = new Vector4AnimationReference();\n  scale = new Vector3AnimationReference();\n  visibility = new Uint32AnimationReference();\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.unknown0 = stream.readInt32();\n    this.name.load(stream, index);\n    this.flags = stream.readUint32();\n    this.parent = stream.readInt16();\n    this.unknown1 = stream.readUint16();\n    this.location.load(stream);\n    this.rotation.load(stream);\n    this.scale.load(stream);\n    this.visibility.load(stream);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/boundingshape.ts",
    "content": "import BinaryStream from '../../common/binarystream';\n\n/**\n * A bounding shape.\n */\nexport default class BoundingShape {\n  shape = -1;\n  bone = -1;\n  unknown0 = 0;\n  matrix = new Float32Array(16);\n  unknown1 = 0;\n  unknown2 = 0;\n  unknown3 = 0;\n  unknown4 = 0;\n  unknown5 = 0;\n  unknown6 = 0;\n  size = new Float32Array(3);\n\n  load(stream: BinaryStream): void {\n    this.shape = stream.readUint32();\n    this.bone = stream.readInt16();\n    this.unknown0 = stream.readUint16();\n    stream.readFloat32Array(this.matrix);\n    this.unknown1 = stream.readUint32();\n    this.unknown2 = stream.readUint32();\n    this.unknown3 = stream.readUint32();\n    this.unknown4 = stream.readUint32();\n    this.unknown5 = stream.readUint32();\n    this.unknown6 = stream.readUint32();\n    stream.readFloat32Array(this.size);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/boundingsphere.ts",
    "content": "import BinaryStream from '../../common/binarystream';\n\n/**\n * A bounding sphere.\n */\nexport default class BoundingSphere {\n  min = new Float32Array(3);\n  max = new Float32Array(3);\n  radius = 0;\n\n  load(stream: BinaryStream): void {\n    stream.readFloat32Array(this.min);\n    stream.readFloat32Array(this.max);\n    this.radius = stream.readFloat32();\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/camera.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\nimport { Float32AnimationReference } from './animationreference';\n\n/**\n * A camera.\n */\nexport default class Camera {\n  version = -1;\n  bone = -1;\n  name = new Reference();\n  fieldOfView = new Float32AnimationReference();\n  unknown0 = 0;\n  farClip = new Float32AnimationReference();\n  nearClip = new Float32AnimationReference();\n  clip2 = new Float32AnimationReference();\n  focalDepth = new Float32AnimationReference();\n  falloffStart = new Float32AnimationReference();\n  falloffEnd = new Float32AnimationReference();\n  depthOfField = new Float32AnimationReference();\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.bone = stream.readUint32();\n    this.name.load(stream, index);\n    this.fieldOfView.load(stream);\n    this.unknown0 = stream.readUint32();\n    this.farClip.load(stream);\n    this.nearClip.load(stream);\n    this.clip2.load(stream);\n    this.focalDepth.load(stream);\n    this.falloffStart.load(stream);\n    this.falloffEnd.load(stream);\n    this.depthOfField.load(stream);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/division.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * A division.\n */\nexport default class Division {\n  version = -1;\n  triangles = new Reference();\n  regions = new Reference();\n  batches = new Reference();\n  MSEC = new Reference();\n  unknown0 = 0;\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.triangles.load(stream, index);\n    this.regions.load(stream, index);\n    this.batches.load(stream, index);\n    this.MSEC.load(stream, index);\n    this.unknown0 = stream.readUint32();\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/event.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * An event.\n */\nexport default class Event {\n  version = -1;\n  name = new Reference();\n  unknown0 = 0;\n  unknown1 = 0;\n  unknown2 = 0;\n  matrix = new Float32Array(16);\n  unknown3 = 0;\n  unknown4 = 0;\n  unknown5 = 0;\n  unknown6 = 0;\n  unknown7 = 0;\n  unknown8 = 0;\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.name.load(stream, index);\n    this.unknown0 = stream.readInt32();\n    this.unknown1 = stream.readInt16();\n    this.unknown2 = stream.readUint16();\n    stream.readFloat32Array(this.matrix);\n    this.unknown3 = stream.readInt32();\n    this.unknown4 = stream.readInt32();\n    this.unknown5 = stream.readInt32();\n\n    if (version > 0) {\n      this.unknown6 = stream.readInt32();\n      this.unknown7 = stream.readInt32();\n    }\n\n    if (version > 1) {\n      this.unknown8 = stream.readInt32();\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/index.ts",
    "content": "import Model from './model';\nimport isM3 from './isformat';\n\nexport default {\n  Model,\n  isM3,\n};\n"
  },
  {
    "path": "src/parsers/m3/indexentry.ts",
    "content": "import reverse from '../../common/stringreverse';\nimport BinaryStream from '../../common/binarystream';\nimport Md34 from './md34';\nimport ModelHeader from './modelheader';\nimport Sequence from './sequence';\nimport Stc from './stc';\nimport Stg from './stg';\nimport Sts from './sts';\nimport Bone from './bone';\nimport Division from './division';\nimport Region from './region';\nimport Batch from './batch';\nimport MaterialReference from './materialreference';\nimport StandardMaterial from './standardmaterial';\nimport Layer from './layer';\nimport Event from './event';\nimport BoundingSphere from './boundingsphere';\nimport AttachmentPoint from './attachmentpoint';\nimport Camera from './camera';\nimport Sd from './sd';\nimport UnsupportedEntry from './unsupportedentry';\n\n\n// Mapping from entry tags, to their constructors and known version->size values.\nconst tagMapping = {\n  // Objects\n  MD34: [Md34, { 11: 24 }],\n  MODL: [ModelHeader, { 23: 784, 25: 808, 26: 820, 28: 844, 29: 856 }],\n  SEQS: [Sequence, { 1: 96, 2: 92 }],\n  STC_: [Stc, { 4: 204 }],\n  STG_: [Stg, { 0: 24 }],\n  STS_: [Sts, { 0: 28 }],\n  BONE: [Bone, { 1: 160 }],\n  DIV_: [Division, { 2: 52 }],\n  REGN: [Region, { 3: 36, 4: 40, 5: 48 }],\n  BAT_: [Batch, { 1: 14 }],\n  MATM: [MaterialReference, { 0: 8 }],\n  MAT_: [StandardMaterial, { 15: 268, 16: 280, 17: 280, 18: 280, 19: 340 }],\n  LAYR: [Layer, { 22: 356, 24: 436, 25: 468, 26: 464 }],\n  EVNT: [Event, { 0: 96, 1: 104, 2: 108 }],\n  BNDS: [BoundingSphere, { 0: 28 }],\n  ATT_: [AttachmentPoint, { 1: 20 }],\n  CAM_: [Camera, { 3: 180, 5: 264 }],\n  SDEV: [Sd, { 0: 32 }],\n  SDU6: [Sd, { 0: 32 }],\n  SDFG: [Sd, { 0: 32 }],\n  SDS6: [Sd, { 0: 32 }],\n  SDR3: [Sd, { 0: 32 }],\n  SD2V: [Sd, { 0: 32 }],\n  SD3V: [Sd, { 0: 32 }],\n  SD4Q: [Sd, { 0: 32 }],\n  SDCC: [Sd, { 0: 32 }],\n  SDMB: [Sd, { 0: 32 }],\n  FLAG: [Sd, { 0: 32 }],\n  // Unsupported entries\n  MSEC: [UnsupportedEntry, { 1: 72 }],\n  LITE: [UnsupportedEntry, { 7: 212 }],\n  ATVL: [UnsupportedEntry, { 0: 116 }],\n  PATU: [UnsupportedEntry, { 4: 152 }],\n  TRGD: [UnsupportedEntry, { 0: 24 }],\n  DIS_: [UnsupportedEntry, { 4: 68 }],\n  CMS_: [UnsupportedEntry, { 0: 24 }],\n  CMP_: [UnsupportedEntry, { 2: 28 }],\n  TER_: [UnsupportedEntry, { 0: 24, 1: 28 }],\n  VOL_: [UnsupportedEntry, { 0: 84 }],\n  VON_: [UnsupportedEntry, { 0: 268 }],\n  CREP: [UnsupportedEntry, { 0: 24, 1: 28 }],\n  STBM: [UnsupportedEntry, { 0: 48 }],\n  LFSB: [UnsupportedEntry, { 2: 56 }],\n  LFLR: [UnsupportedEntry, { 2: 80, 3: 152 }],\n  PAR_: [UnsupportedEntry, { 12: 1316, 17: 1460, 18: 1464, 19: 1464, 21: 1464, 22: 1484, 23: 1492, 24: 1496 }],\n  PARC: [UnsupportedEntry, { 0: 40 }],\n  PROJ: [UnsupportedEntry, { 4: 388, 5: 382 }],\n  PHYJ: [UnsupportedEntry, { 0: 180 }],\n  PHCC: [UnsupportedEntry, { 0: 76 }],\n  PHAC: [UnsupportedEntry, { 0: 32 }],\n  PHCL: [UnsupportedEntry, { 2: 128 }],\n  FOR_: [UnsupportedEntry, { 1: 104, 2: 104 }],\n  DMSE: [UnsupportedEntry, { 0: 4 }],\n  PHSH: [UnsupportedEntry, { 1: 132, 3: 300 }],\n  PHRB: [UnsupportedEntry, { 2: 104, 4: 80 }],\n  SSGS: [UnsupportedEntry, { 1: 108 }],\n  BBSC: [UnsupportedEntry, { 0: 48 }],\n  SRIB: [UnsupportedEntry, { 0: 272 }],\n  RIB_: [UnsupportedEntry, { 6: 748, 8: 756, 9: 760 }],\n  IKJT: [UnsupportedEntry, { 0: 32 }],\n  SHBX: [UnsupportedEntry, { 0: 64 }],\n  WRP_: [UnsupportedEntry, { 1: 132 }],\n};\n\nexport type EntryType = Md34[] | ModelHeader[] | Sequence[] | Stc[] | Stg[] | Sts[] | Bone[] | Division[] | Region[] | Batch[] | MaterialReference[] | StandardMaterial[] | Layer[] | Event[] | BoundingSphere[] | AttachmentPoint[] | Camera[] | Sd[] | UnsupportedEntry[] | string | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Float32Array | Float32Array[];\nexport type SingleEntryType = Md34 | ModelHeader | Sequence | Stc | Stg | Sts | Bone | Division | Region | Batch | MaterialReference | StandardMaterial | Layer | Event | BoundingSphere | AttachmentPoint | Camera | Sd | UnsupportedEntry | string | number | Float32Array;\n\n/**\n * An index entry.\n */\nexport default class IndexEntry {\n  index: IndexEntry[];\n  tag: string;\n  offset: number;\n  version: number;\n  entries: EntryType;\n\n  constructor(stream: BinaryStream, index: IndexEntry[]) {\n    const tag = reverse(stream.readBinary(4));\n    const offset = stream.readUint32();\n    const entriesCount = stream.readUint32();\n    const version = stream.readUint32();\n\n    this.index = index;\n    this.tag = tag;\n    this.offset = offset;\n    this.version = version;\n\n    const mapping = tagMapping[tag];\n    const readerOffset = stream.index;\n\n    stream.seek(offset);\n\n    // This is an object\n    if (mapping) {\n      const constructor = mapping[0];\n      const entrySize = mapping[1][version];\n\n      if (!entrySize) {\n        // Yey found a new version!\n        throw new Error(': Unsupported object version - tag ' + tag + ' and version ' + version);\n      }\n\n      this.entries = [];\n\n      for (let i = 0, l = entriesCount; i < l; i++) {\n        // A sub stream is given for each object constructor.\n        // This allows for parsing to work consistently, even if we don't quite know exactly how the structures look.\n        // If some bytes aren't read, the error will not carry to the next object.\n        // Since new versions of objects usually add data to the end, this allows the parser to work, even if trying to load newer versions.\n        // Of course, the new version size needs to be added to IndexEntry.tagMapping, when finding one.\n        if (constructor === UnsupportedEntry) {\n          this.entries[i] = new UnsupportedEntry(stream.substream(entrySize), version, index);\n        } else {\n          const entry = new constructor();\n\n          entry.load(stream.substream(entrySize), version, index);\n\n          this.entries[i] = entry;\n        }\n      }\n      // This is maybe a typed array?\n    } else if (tag === 'CHAR' || tag === 'SCHR') {\n      this.entries = stream.read(entriesCount);\n    } else if (tag === 'U8__') {\n      this.entries = stream.readUint8Array(entriesCount);\n    } else if (tag === 'U16_') {\n      this.entries = stream.readUint16Array(entriesCount);\n    } else if (tag === 'U32_') {\n      this.entries = stream.readUint32Array(entriesCount);\n    } else if (tag === 'I16_') {\n      this.entries = stream.readInt16Array(entriesCount);\n    } else if (tag === 'I32_') {\n      this.entries = stream.readInt32Array(entriesCount);\n    } else if (tag === 'REAL') {\n      this.entries = stream.readFloat32Array(entriesCount);\n    } else if (tag === 'VEC2') {\n      this.entries = [];\n\n      for (let i = 0; i < entriesCount; i++) {\n        this.entries[i] = stream.readFloat32Array(2);\n      }\n    } else if (tag === 'VEC3' || tag === 'SVC3') {\n      this.entries = [];\n\n      for (let i = 0; i < entriesCount; i++) {\n        this.entries[i] = stream.readFloat32Array(3);\n      }\n    } else if (tag === 'VEC4' || tag === 'QUAT') {\n      this.entries = [];\n\n      for (let i = 0; i < entriesCount; i++) {\n        this.entries[i] = stream.readFloat32Array(4);\n      }\n    } else if (tag === 'IREF') {\n      this.entries = [];\n\n      for (let i = 0; i < entriesCount; i++) {\n        this.entries[i] = stream.readFloat32Array(16);\n      }\n    } else {\n      this.entries = [];\n\n      throw new Error(': Unsupported object tag - tag ' + tag + ' and version ' + version);\n    }\n\n    stream.seek(readerOffset);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/isformat.ts",
    "content": "/**\n * Detects if the given object is an M3 source.\n */\nexport default function isM3(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x34 && bytes[1] === 0x33 && bytes[2] === 0x44 && bytes[3] === 0x4d) {\n      return true;\n    }\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/parsers/m3/layer.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\nimport { PixelAnimationReference, Uint16AnimationReference, Uint32AnimationReference, Float32AnimationReference, Vector2AnimationReference, Vector3AnimationReference } from './animationreference';\n\n/**\n * A layer.\n */\nexport default class Layer {\n  version = -1;\n  unknown0 = 0;\n  imagePath = new Reference();\n  color = new PixelAnimationReference();\n  flags = 0;\n  uvSource = -1;\n  colorChannelSetting = 0;\n  brightMult = new Float32AnimationReference();\n  midtoneOffset = new Float32AnimationReference();\n  unknown1 = 0;\n  noiseAmp = 0;\n  noiseFreq = 0;\n  rttChannel = 0;\n  videoFrameRate = 0;\n  videoStartFrame = 0;\n  videoEndFrame = 0;\n  videoMode = 0;\n  videoSyncTiming = 0;\n  videoPlay = new Uint32AnimationReference();\n  videoRestart = new Uint32AnimationReference();\n  flipBookRows = 0;\n  flipBookColumns = 0;\n  flipBookFrame = new Uint16AnimationReference();\n  uvOffset = new Vector2AnimationReference();\n  uvAngle = new Vector3AnimationReference();\n  uvTiling = new Vector2AnimationReference();\n  unknown2 = new Uint32AnimationReference();\n  unknown3 = new Float32AnimationReference();\n  brightness = new Float32AnimationReference();\n  triPlanarOffset = new Vector3AnimationReference();\n  triPlanarScale = new Vector3AnimationReference();\n  unknown4 = 0;\n  fresnelType = 0;\n  fresnelExponent = 0;\n  fresnelMin = 0;\n  fresnelMaxOffset = 0;\n  unknown5 = 0;\n  unknown6 = new Uint8Array(8);\n  fresnelInvertedMaskX = 0;\n  fresnelInvertedMaskY = 0;\n  fresnelInvertedMaskZ = 0;\n  fresnelRotationYaw = 0;\n  fresnelRotationPitch = 0;\n  unknown7 = 0;\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.unknown0 = stream.readUint32();\n    this.imagePath.load(stream, index);\n    this.color.load(stream);\n    this.flags = stream.readUint32();\n    this.uvSource = stream.readUint32();\n    this.colorChannelSetting = stream.readUint32();\n    this.brightMult.load(stream);\n    this.midtoneOffset.load(stream);\n    this.unknown1 = stream.readUint32();\n\n    if (version > 23) {\n      this.noiseAmp = stream.readFloat32();\n      this.noiseFreq = stream.readFloat32();\n    }\n\n    this.rttChannel = stream.readInt32();\n    this.videoFrameRate = stream.readUint32();\n    this.videoStartFrame = stream.readUint32();\n    this.videoEndFrame = stream.readInt32();\n    this.videoMode = stream.readUint32();\n    this.videoSyncTiming = stream.readUint32();\n    this.videoPlay.load(stream);\n    this.videoRestart.load(stream);\n    this.flipBookRows = stream.readUint32();\n    this.flipBookColumns = stream.readUint32();\n    this.flipBookFrame.load(stream);\n    this.uvOffset.load(stream);\n    this.uvAngle.load(stream);\n    this.uvTiling.load(stream);\n    this.unknown2.load(stream);\n    this.unknown3.load(stream);\n    this.brightness.load(stream);\n\n    if (version > 23) {\n      this.triPlanarOffset.load(stream);\n      this.triPlanarScale.load(stream);\n    }\n\n    this.unknown4 = stream.readInt32();\n    this.fresnelType = stream.readUint32();\n    this.fresnelExponent = stream.readFloat32();\n    this.fresnelMin = stream.readFloat32();\n    this.fresnelMaxOffset = stream.readFloat32();\n    this.unknown5 = stream.readFloat32();\n\n    if (version > 24) {\n      this.unknown6 = stream.readUint8Array(8);\n      this.fresnelInvertedMaskX = stream.readFloat32();\n      this.fresnelInvertedMaskY = stream.readFloat32();\n      this.fresnelInvertedMaskZ = stream.readFloat32();\n      this.fresnelRotationYaw = stream.readFloat32();\n      this.fresnelRotationPitch = stream.readFloat32();\n      this.unknown7 = stream.readUint32();\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/light.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport { Float32AnimationReference, Vector3AnimationReference } from './animationreference';\n\n/**\n * A light.\n */\nexport default class Light {\n  version = -1;\n  type = 0;\n  unknown0 = 0;\n  bone = -1;\n  flags = 0;\n  unknown1 = 0;\n  unknown2 = 0;\n  lightColor = new Vector3AnimationReference();\n  lightIntensity = new Float32AnimationReference();\n  specularColor = new Vector3AnimationReference();\n  specularIntensity = new Float32AnimationReference();\n  attenuationFar = new Float32AnimationReference();\n  unknown3 = 0;\n  attenuationNear = new Float32AnimationReference();\n  hotSpot = new Float32AnimationReference();\n  falloff = new Float32AnimationReference();\n\n  load(stream: BinaryStream, version: number, _index: IndexEntry[]): void {\n    this.version = version;\n    this.type = stream.readUint8();\n    this.unknown0 = stream.readUint8();\n    this.bone = stream.readInt16();\n    this.flags = stream.readUint32();\n    this.unknown1 = stream.readUint32();\n    this.unknown2 = stream.readInt32();\n    this.lightColor.load(stream);\n    this.lightIntensity.load(stream);\n    this.specularColor.load(stream);\n    this.specularIntensity.load(stream);\n    this.attenuationFar.load(stream);\n    this.unknown3 = stream.readFloat32();\n    this.attenuationNear.load(stream);\n    this.hotSpot.load(stream);\n    this.falloff.load(stream);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/materialreference.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\n\n/**\n * A material reference.\n */\nexport default class MaterialReference {\n  version = -1;\n  materialType = 0;\n  materialIndex = -1;\n\n  load(stream: BinaryStream, version: number, _index: IndexEntry[]): void {\n    this.version = version;\n    this.materialType = stream.readUint32();\n    this.materialIndex = stream.readUint32();\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/md34.ts",
    "content": "import reverse from '../../common/stringreverse';\nimport BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * The M3 header.\n */\nexport default class Md34 {\n  version = -1;\n  tag = '';\n  offset = 0;\n  entries = 0;\n  model = new Reference();\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.tag = reverse(stream.readBinary(4));\n    this.offset = stream.readUint32();\n    this.entries = stream.readUint32();\n    this.model.load(stream, index);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/model.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Md34 from './md34';\nimport ModelHeader from './modelheader';\n\n/**\n * A model.\n */\nexport default class Model {\n  index: IndexEntry[] = [];\n  model: ModelHeader | null = null;\n\n  load(src: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(src);\n    const header = new Md34();\n\n    header.load(stream, 11, this.index);\n\n    if (header.tag !== 'MD34') {\n      throw new Error('WrongMagicNumber');\n    }\n\n    stream.seek(header.offset);\n\n    // Read the index entries\n    for (let i = 0, l = header.entries; i < l; i++) {\n      this.index[i] = new IndexEntry(stream, this.index);\n    }\n\n    const modelEntries = this.index[header.model.id].entries;\n\n    if (modelEntries) {\n      this.model = <ModelHeader>modelEntries[0];\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/modelheader.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\nimport BoundingSphere from './boundingsphere';\nimport BoundingShape from './boundingshape';\n\n/**\n * The model information structure.\n */\nexport default class ModelHeader {\n  version = -1;\n  modelName = new Reference();\n  flags = 0;\n  sequences = new Reference();\n  stc = new Reference();\n  stg = new Reference();\n  unknown0 = 0;\n  unknown1 = 0;\n  unknown2 = 0;\n  unknown3 = 0;\n  sts = new Reference();\n  bones = new Reference();\n  numberOfBonesToCheckForSkin = 0;\n  vertexFlags = 0;\n  vertices = new Reference();\n  divisions = new Reference();\n  boneLookup = new Reference();\n  boundings = new BoundingSphere();\n  unknown4To20 = new Uint32Array(16);\n  attachmentPoints = new Reference();\n  attachmentPointAddons = new Reference();\n  ligts = new Reference();\n  shbxData = new Reference();\n  cameras = new Reference();\n  unknown21 = new Reference();\n  materialReferences = new Reference();\n  materials: Reference[] = [];\n  particleEmitters = new Reference();\n  particleEmitterCopies = new Reference();\n  ribbonEmitters = new Reference();\n  projections = new Reference();\n  forces = new Reference();\n  warps = new Reference();\n  unknown22 = new Reference();\n  rigidBodies = new Reference();\n  unknown23 = new Reference();\n  physicsJoints = new Reference();\n  clothBehavior = new Reference();\n  unknown24 = new Reference();\n  ikjtData = new Reference();\n  unknown25 = new Reference();\n  unknown26 = new Reference();\n  partsOfTurrentBehaviors = new Reference();\n  turrentBehaviors = new Reference();\n  absoluteInverseBoneRestPositions = new Reference();\n  tightHitTest = new BoundingShape();\n  fuzzyHitTestObjects = new Reference();\n  attachmentVolumes = new Reference();\n  attachmentVolumesAddon0 = new Reference();\n  attachmentVolumesAddon1 = new Reference();\n  billboardBehaviors = new Reference();\n  tmdData = new Reference();\n  unknown27 = 0;\n  unknown28 = new Reference();\n\n  constructor() {\n    for (let i = 0; i < 11; i++) {\n      this.materials[i] = new Reference();\n    }\n  }\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.modelName.load(stream, index);\n    this.flags = stream.readUint32();\n    this.sequences.load(stream, index);\n    this.stc.load(stream, index);\n    this.stg.load(stream, index);\n    this.unknown0 = stream.readFloat32();\n    this.unknown1 = stream.readFloat32();\n    this.unknown2 = stream.readFloat32();\n    this.unknown3 = stream.readFloat32();\n    this.sts.load(stream, index);\n    this.bones.load(stream, index);\n    this.numberOfBonesToCheckForSkin = stream.readUint32();\n    this.vertexFlags = stream.readUint32();\n    this.vertices.load(stream, index);\n    this.divisions.load(stream, index);\n    this.boneLookup.load(stream, index);\n    this.boundings.load(stream);\n    stream.readUint32Array(this.unknown4To20);\n    this.attachmentPoints.load(stream, index);\n    this.attachmentPointAddons.load(stream, index);\n    this.ligts.load(stream, index);\n    this.shbxData.load(stream, index);\n    this.cameras.load(stream, index);\n    this.unknown21.load(stream, index);\n    this.materialReferences.load(stream, index);\n\n    for (let i = 0; i < 7; i++) {\n      this.materials[i].load(stream, index); // Standard, Displacement, Composite, Terrain, Volume, ?, Creep\n    }\n\n    if (version > 24) {\n      this.materials[7].load(stream, index); // Volume noise\n    }\n\n    if (version > 25) {\n      this.materials[8].load(stream, index); // Splat terrain bake\n    }\n\n    if (version > 27) {\n      this.materials[9].load(stream, index); // ?\n    }\n\n    if (version > 28) {\n      this.materials[10].load(stream, index); // Lens flare\n    }\n\n    this.particleEmitters.load(stream, index);\n    this.particleEmitterCopies.load(stream, index);\n    this.ribbonEmitters.load(stream, index);\n    this.projections.load(stream, index);\n    this.forces.load(stream, index);\n    this.warps.load(stream, index);\n    this.unknown22.load(stream, index); // ?\n    this.rigidBodies.load(stream, index);\n    this.unknown23.load(stream, index); // ?\n    this.physicsJoints.load(stream, index);\n\n    if (version > 27) {\n      this.clothBehavior.load(stream, index);\n    }\n\n    this.unknown24.load(stream, index); // ?\n    this.ikjtData.load(stream, index);\n    this.unknown25.load(stream, index); // ?\n\n    if (version > 24) {\n      this.unknown26.load(stream, index); // ?\n    }\n\n    this.partsOfTurrentBehaviors.load(stream, index);\n    this.turrentBehaviors.load(stream, index);\n    this.absoluteInverseBoneRestPositions.load(stream, index);\n    this.tightHitTest.load(stream);\n    this.fuzzyHitTestObjects.load(stream, index);\n    this.attachmentVolumes.load(stream, index);\n    this.attachmentVolumesAddon0.load(stream, index);\n    this.attachmentVolumesAddon1.load(stream, index);\n    this.billboardBehaviors.load(stream, index);\n    this.tmdData.load(stream, index);\n    this.unknown27 = stream.readUint32(); // ?\n    this.unknown28.load(stream, index); // ?\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/reference.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry, { EntryType, SingleEntryType } from './indexentry';\n\n/**\n * A reference.\n */\nexport default class Reference {\n  index: IndexEntry[] | null = null;\n  entries = 0;\n  id = 0;\n  flags = 0;\n\n  load(stream: BinaryStream, index: IndexEntry[]): void {\n    this.index = index;\n    this.entries = stream.readUint32();\n    this.id = stream.readUint32();\n    this.flags = stream.readUint32();\n  }\n\n  /**\n   * Get the entries this index entry references.\n   */\n  get(): EntryType | undefined {\n    if (this.index && this.id !== 0 && this.entries !== 0) {\n      return this.index[this.id].entries;\n    }\n\n    return;\n  }\n\n  /**\n   * Get the first entry this index entry references.\n   */\n  first(): SingleEntryType | undefined {\n    const entries = this.get();\n\n    if (entries) {\n      return entries[0];\n    }\n\n    return;\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/region.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\n\n/**\n * A region.\n */\nexport default class Region {\n  version = -1;\n  unknown0 = 0;\n  unknown1 = 0;\n  firstVertexIndex = -1;\n  verticesCount = 0;\n  firstTriangleIndex = -1;\n  triangleIndicesCount = 0;\n  bonesCount = 0;\n  firstBoneLookupIndex = -1;\n  boneLookupIndicesCount = 0;\n  unknown2 = 0;\n  boneWeightPairsCount = 0;\n  unknown3 = 0;\n  rootBoneIndex = -1;\n  unknown4 = 0;\n  unknown5 = new Uint8Array(8);\n\n  load(stream: BinaryStream, version: number, _index: IndexEntry[]): void {\n    this.version = version;\n    this.unknown0 = stream.readUint32();\n    this.unknown1 = stream.readUint32();\n    this.firstVertexIndex = stream.readUint32();\n    this.verticesCount = stream.readUint32();\n    this.firstTriangleIndex = stream.readUint32();\n    this.triangleIndicesCount = stream.readUint32();\n    this.bonesCount = stream.readUint16();\n    this.firstBoneLookupIndex = stream.readUint16();\n    this.boneLookupIndicesCount = stream.readUint16();\n    this.unknown2 = stream.readUint16();\n    this.boneWeightPairsCount = stream.readUint8();\n    this.unknown3 = stream.readUint8();\n    this.rootBoneIndex = stream.readUint16();\n\n    if (version > 3) {\n      this.unknown4 = stream.readUint32();\n    }\n\n    if (version > 4) {\n      stream.readUint8Array(this.unknown5);\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/sd.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * Sequence data.\n */\nexport default class Sd {\n  version = -1;\n  keys = new Reference();\n  flags = 0;\n  biggestKey = -1;\n  values = new Reference();\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.keys.load(stream, index);\n    this.flags = stream.readUint32();\n    this.biggestKey = stream.readUint32();\n    this.values.load(stream, index);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/sequence.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\nimport BoundingSphere from './boundingsphere';\n\n/**\n * A sequence.\n */\nexport default class Sequence {\n  version = -1;\n  name = new Reference();\n  interval = new Uint32Array(2);\n  movementSpeed = 0;\n  flags = 0;\n  frequency = 0;\n  boundingSphere = new BoundingSphere();\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n\n    stream.skip(8); // ?\n\n    this.name.load(stream, index);\n    stream.readUint32Array(this.interval);\n    this.movementSpeed = stream.readFloat32();\n    this.flags = stream.readUint32();\n    this.frequency = stream.readUint32();\n\n    stream.skip(12); // ?\n\n    if (version < 2) {\n      stream.skip(4); // ?\n    }\n\n    this.boundingSphere.load(stream);\n\n    stream.skip(12); // ?\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/standardmaterial.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\nimport { Float32AnimationReference, Uint32AnimationReference } from './animationreference';\n\n/**\n * A standard material.\n */\nexport default class StandardMaterial {\n  version = -1;\n  name = new Reference();\n  additionalFlags = 0;\n  flags = 0;\n  blendMode = 0;\n  priority = 0;\n  usedRTTChannels = 0;\n  specularity = 0;\n  depthBlendFalloff = 0;\n  cutoutThreshold = 0;\n  unknown1 = 0;\n  unknown2 = 0;\n  unknown3 = 0;\n  specMult = 0;\n  emisMult = 0;\n  diffuseLayer = new Reference();\n  decalLayer = new Reference();\n  specularLayer = new Reference();\n  glossLayer = new Reference();\n  emissiveLayer = new Reference();\n  emissive2Layer = new Reference();\n  evioLayer = new Reference();\n  evioMaskLayer = new Reference();\n  alphaMaskLayer = new Reference();\n  alphaMask2Layer = new Reference();\n  normalLayer = new Reference();\n  heightLayer = new Reference();\n  lightMapLayer = new Reference();\n  ambientOcclusionLayer = new Reference();\n  unknown4 = new Reference();\n  unknown5 = new Reference();\n  unknown6 = new Reference();\n  unknown7 = new Reference();\n  unknown8 = 0;\n  layerBlendType = 0;\n  emisBlendType = 0;\n  emisMode = 0;\n  specType = 0;\n  unknown9 = new Float32AnimationReference();\n  unknown10 = new Uint32AnimationReference();\n  unknown11 = new Uint8Array(12);\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.name.load(stream, index);\n    this.additionalFlags = stream.readUint32();\n    this.flags = stream.readUint32();\n    this.blendMode = stream.readUint32();\n    this.priority = stream.readInt32();\n    this.usedRTTChannels = stream.readUint32();\n    this.specularity = stream.readFloat32();\n    this.depthBlendFalloff = stream.readFloat32();\n    this.cutoutThreshold = stream.readUint8();\n    this.unknown1 = stream.readUint8(); // ?\n    this.unknown2 = stream.readUint8(); // ?\n    this.unknown3 = stream.readUint8(); // ?\n    this.specMult = stream.readFloat32();\n    this.emisMult = stream.readFloat32();\n    this.diffuseLayer.load(stream, index);\n    this.decalLayer.load(stream, index);\n    this.specularLayer.load(stream, index);\n\n    if (version > 15) {\n      this.glossLayer.load(stream, index);\n    }\n\n    this.emissiveLayer.load(stream, index);\n    this.emissive2Layer.load(stream, index);\n    this.evioLayer.load(stream, index);\n    this.evioMaskLayer.load(stream, index);\n    this.alphaMaskLayer.load(stream, index);\n    this.alphaMask2Layer.load(stream, index);\n    this.normalLayer.load(stream, index);\n    this.heightLayer.load(stream, index);\n    this.lightMapLayer.load(stream, index);\n    this.ambientOcclusionLayer.load(stream, index);\n\n    if (version > 18) {\n      this.unknown4.load(stream, index); // Unknown layer\n      this.unknown5.load(stream, index); // Unknown layer\n      this.unknown6.load(stream, index); // Unknown layer\n      this.unknown7.load(stream, index); // Unknown layer\n    }\n\n    this.unknown8 = stream.readUint32(); // ?\n    this.layerBlendType = stream.readUint32();\n    this.emisBlendType = stream.readUint32();\n    this.emisMode = stream.readUint32();\n    this.specType = stream.readUint32();\n\n    this.unknown9.load(stream); // ?\n    this.unknown10.load(stream); // ?\n\n    if (version > 18) {\n      this.unknown11 = stream.readUint8Array(this.unknown11); // ?\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/stc.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * An animation timeline.\n */\nexport default class Stc {\n  version = -1;\n  name = new Reference();\n  runsConcurrent = 0;\n  priority = 0;\n  stsIndex = -1;\n  stsIndexCopy = -1;\n  animIds = new Reference();\n  animRefs = new Reference();\n  sd: Reference[] = [];\n\n  constructor() {\n    for (let i = 0; i < 13; i++) {\n      this.sd[i] = new Reference();\n    }\n  }\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.name.load(stream, index);\n    this.runsConcurrent = stream.readUint16();\n    this.priority = stream.readUint16();\n    this.stsIndex = stream.readUint16();\n    this.stsIndexCopy = stream.readUint16(); // ?\n    this.animIds.load(stream, index);\n    this.animRefs.load(stream, index);\n\n    stream.skip(4); // ?\n\n    for (let i = 0; i < 13; i++) {\n      this.sd[i].load(stream, index);\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/stg.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * An animation getter.\n */\nexport default class Stg {\n  version = -1;\n  name = new Reference();\n  stcIndices = new Reference();\n\n  load(stream: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.name.load(stream, index);\n    this.stcIndices.load(stream, index);\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/sts.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\nimport Reference from './reference';\n\n/**\n * An animation validator.\n */\nexport default class Sts {\n  version = -1;\n  animIds = new Reference();\n\n  load(reader: BinaryStream, version: number, index: IndexEntry[]): void {\n    this.version = version;\n    this.animIds.load(reader, index);\n\n    reader.skip(16); // ?\n  }\n}\n"
  },
  {
    "path": "src/parsers/m3/unsupportedentry.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport IndexEntry from './indexentry';\n\n/**\n * An unsupported entry.\n * \n * This is used for entries that have known structures (or at least sizes), but this parser isn't going to actually parse.\n * The entry will contain its own reader and version, in case the client code wants to do anything with it.\n */\nexport default class UnsupportedEntry {\n  stream: BinaryStream;\n  version: number;\n  index: IndexEntry[];\n\n  constructor(stream: BinaryStream, version: number, index: IndexEntry[]) {\n    this.stream = stream;\n    this.version = version;\n    this.index = index;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/animatedobject.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport { Animation } from './animations';\nimport animationMap from './animationmap';\n\n/**\n * The parent class for all objects that have animated data in them.\n */\nexport default class AnimatedObject {\n  animations: Animation[] = [];\n\n  readAnimations(stream: BinaryStream, size: number): void {\n    const end = stream.index + size;\n\n    while (stream.index < end) {\n      const name = stream.readBinary(4);\n      const animation = new animationMap[name][1]();\n\n      animation.readMdx(stream, name);\n\n      this.animations.push(animation);\n    }\n  }\n\n  writeAnimations(stream: BinaryStream): void {\n    for (const animation of this.animations) {\n      animation.writeMdx(stream);\n    }\n  }\n\n  /**\n   * A wrapper around readBlock() which merges static tokens.\n   * E.g.: static Color\n   * This makes the condition blocks in the parent objects linear and simple.\n   */\n  * readAnimatedBlock(stream: TokenStream): Generator<string> {\n    for (const token of stream.readBlock()) {\n      if (token === 'static') {\n        yield `static ${stream.read()}`;\n      } else {\n        yield token;\n      }\n    }\n  }\n\n  readAnimation(stream: TokenStream, name: string): void {\n    const animation = new animationMap[name][1]();\n\n    animation.readMdl(stream, name);\n\n    this.animations.push(animation);\n  }\n\n  writeAnimation(stream: TokenStream, name: string): boolean {\n    for (const animation of this.animations) {\n      if (animation.name === name) {\n        animation.writeMdl(stream, animationMap[name][0]);\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * AnimatedObject itself doesn't care about versions, however objects that inherit it do.\n   */\n  getByteLength(_version = 0): number {\n    let size = 0;\n\n    for (const animation of this.animations) {\n      size += animation.getByteLength();\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/animationmap.ts",
    "content": "import { UintAnimation, FloatAnimation, Vector3Animation, Vector4Animation } from './animations';\n\n// A map from MDX animation tags to their equivalent MDL tokens, and the implementation objects.\nexport default {\n  // Layer\n  KMTF: ['TextureID', UintAnimation],\n  KMTA: ['Alpha', FloatAnimation],\n  KMTE: ['EmissiveGain', FloatAnimation],\n  KFC3: ['FresnelColor', Vector3Animation],\n  KFCA: ['FresnelOpacity', FloatAnimation],\n  KFTC: ['FresnelTeamColor', UintAnimation],\n  // TextureAnimation\n  KTAT: ['Translation', Vector3Animation],\n  KTAR: ['Rotation', Vector4Animation],\n  KTAS: ['Scaling', Vector3Animation],\n  // GeosetAnimation\n  KGAO: ['Alpha', FloatAnimation],\n  KGAC: ['Color', Vector3Animation],\n  // GenericObject\n  KGTR: ['Translation', Vector3Animation],\n  KGRT: ['Rotation', Vector4Animation],\n  KGSC: ['Scaling', Vector3Animation],\n  // Light\n  KLAS: ['AttenuationStart', FloatAnimation],\n  KLAE: ['AttenuationEnd', FloatAnimation],\n  KLAC: ['Color', Vector3Animation],\n  KLAI: ['Intensity', FloatAnimation],\n  KLBI: ['AmbIntensity', FloatAnimation],\n  KLBC: ['AmbColor', Vector3Animation],\n  KLAV: ['Visibility', FloatAnimation],\n  // Attachment\n  KATV: ['Visibility', FloatAnimation],\n  // ParticleEmitter\n  KPEE: ['EmissionRate', FloatAnimation],\n  KPEG: ['Gravity', FloatAnimation],\n  KPLN: ['Longitude', FloatAnimation],\n  KPLT: ['Latitude', FloatAnimation],\n  KPEL: ['LifeSpan', FloatAnimation],\n  KPES: ['InitVelocity', FloatAnimation],\n  KPEV: ['Visibility', FloatAnimation],\n  // ParticleEmitter2\n  KP2S: ['Speed', FloatAnimation],\n  KP2R: ['Variation', FloatAnimation],\n  KP2L: ['Latitude', FloatAnimation],\n  KP2G: ['Gravity', FloatAnimation],\n  KP2E: ['EmissionRate', FloatAnimation],\n  KP2N: ['Width', FloatAnimation],\n  KP2W: ['Length', FloatAnimation],\n  KP2V: ['Visibility', FloatAnimation],\n  // ParticleEmitterCorn\n  KPPA: ['Alpha', FloatAnimation],\n  KPPC: ['Color', Vector3Animation],\n  KPPE: ['EmissionRate', FloatAnimation],\n  KPPL: ['LifeSpan', FloatAnimation],\n  KPPS: ['Speed', FloatAnimation],\n  KPPV: ['Visibility', FloatAnimation],\n  // RibbonEmitter\n  KRHA: ['HeightAbove', FloatAnimation],\n  KRHB: ['HeightBelow', FloatAnimation],\n  KRAL: ['Alpha', FloatAnimation],\n  KRCO: ['Color', Vector3Animation],\n  KRTX: ['TextureSlot', UintAnimation],\n  KRVS: ['Visibility', FloatAnimation],\n  // Camera\n  KCTR: ['Translation', Vector3Animation],\n  KTTR: ['Translation', Vector3Animation],\n  KCRL: ['Rotation', FloatAnimation],\n};\n"
  },
  {
    "path": "src/parsers/mdlx/animations.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\n\nexport const enum InterpolationType {\n  DontInterp = 0,\n  Linear = 1,\n  Hermite = 2,\n  Bezier = 3,\n}\n/**\n * An animation.\n */\nexport abstract class Animation {\n  name = '';\n  interpolationType = InterpolationType.DontInterp;\n  globalSequenceId = -1;\n  frames: number[] = [];\n  values: (Uint32Array | Float32Array)[] = [];\n  inTans: (Uint32Array | Float32Array)[] = [];\n  outTans: (Uint32Array | Float32Array)[] = [];\n\n  abstract readMdxValue(stream: BinaryStream): Uint32Array | Float32Array;\n  abstract writeMdxValue(stream: BinaryStream, value: Uint32Array | Float32Array): void;\n  abstract readMdlValue(stream: TokenStream): Uint32Array | Float32Array;\n  abstract writeMdlValue(stream: TokenStream, name: string, value: Uint32Array | Float32Array): void;\n\n  readMdx(stream: BinaryStream, name: string): void {\n    const frames = this.frames;\n    const values = this.values;\n    const inTans = this.inTans;\n    const outTans = this.outTans;\n    const tracksCount = stream.readUint32();\n    const interpolationType = stream.readUint32();\n\n    this.name = name;\n    this.interpolationType = interpolationType;\n    this.globalSequenceId = stream.readInt32();\n\n    for (let i = 0; i < tracksCount; i++) {\n      frames.push(stream.readInt32());\n      values.push(this.readMdxValue(stream));\n\n      if (interpolationType > 1) {\n        inTans.push(this.readMdxValue(stream));\n        outTans.push(this.readMdxValue(stream));\n      }\n    }\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    const interpolationType = this.interpolationType;\n    const frames = this.frames;\n    const values = this.values;\n    const inTans = this.inTans;\n    const outTans = this.outTans;\n    const tracksCount = frames.length;\n\n    stream.writeBinary(this.name);\n    stream.writeUint32(tracksCount);\n    stream.writeUint32(interpolationType);\n    stream.writeInt32(this.globalSequenceId);\n\n    for (let i = 0; i < tracksCount; i++) {\n      stream.writeInt32(frames[i]);\n      this.writeMdxValue(stream, values[i]);\n\n      if (interpolationType > InterpolationType.Linear) {\n        this.writeMdxValue(stream, inTans[i]);\n        this.writeMdxValue(stream, outTans[i]);\n      }\n    }\n  }\n\n  readMdl(stream: TokenStream, name: string): void {\n    const frames = this.frames;\n    const values = this.values;\n    const inTans = this.inTans;\n    const outTans = this.outTans;\n\n    this.name = name;\n\n    const tracksCount = stream.readInt();\n\n    stream.read(); // {\n\n    let interpolationType = 0;\n    const token = stream.read();\n\n    if (token === 'DontInterp') {\n      interpolationType = InterpolationType.DontInterp;\n    } else if (token === 'Linear') {\n      interpolationType = InterpolationType.Linear;\n    } else if (token === 'Hermite') {\n      interpolationType = InterpolationType.Hermite;\n    } else if (token === 'Bezier') {\n      interpolationType = InterpolationType.Bezier;\n    }\n\n    this.interpolationType = interpolationType;\n\n    // GlobalSeqId only exists if it's not -1.\n    if (stream.peek() === 'GlobalSeqId') {\n      stream.read();\n\n      this.globalSequenceId = stream.readInt();\n    }\n\n    for (let i = 0; i < tracksCount; i++) {\n      frames[i] = stream.readInt();\n      values[i] = this.readMdlValue(stream);\n\n      if (interpolationType > InterpolationType.Linear) {\n        stream.read(); // InTan\n        inTans[i] = this.readMdlValue(stream);\n        stream.read(); // OutTan\n        outTans[i] = this.readMdlValue(stream);\n      }\n    }\n\n    stream.read(); // }\n  }\n\n  writeMdl(stream: TokenStream, name: string): void {\n    const interpolationType = this.interpolationType;\n    const frames = this.frames;\n    const values = this.values;\n    const inTans = this.inTans;\n    const outTans = this.outTans;\n    const tracksCount = frames.length;\n\n    stream.startBlock(name, this.frames.length);\n\n    let token = '';\n\n    if (this.interpolationType === InterpolationType.DontInterp) {\n      token = 'DontInterp';\n    } else if (this.interpolationType === InterpolationType.Linear) {\n      token = 'Linear';\n    } else if (this.interpolationType === InterpolationType.Hermite) {\n      token = 'Hermite';\n    } else if (this.interpolationType === InterpolationType.Bezier) {\n      token = 'Bezier';\n    }\n\n    stream.writeFlag(token);\n\n    if (this.globalSequenceId !== -1) {\n      stream.writeNumberAttrib('GlobalSeqId', this.globalSequenceId);\n    }\n\n    for (let i = 0; i < tracksCount; i++) {\n      this.writeMdlValue(stream, `${frames[i]}:`, values[i]);\n\n      if (interpolationType > InterpolationType.Linear) {\n        stream.indent();\n        this.writeMdlValue(stream, 'InTan', inTans[i]);\n        this.writeMdlValue(stream, 'OutTan', outTans[i]);\n        stream.unindent();\n      }\n    }\n\n    stream.endBlock();\n  }\n\n  getByteLength(): number {\n    const tracksCount = this.frames.length;\n    let size = 16;\n\n    if (tracksCount) {\n      const bytesPerValue = this.values[0].byteLength;\n      let valuesPerTrack = 1;\n\n      if (this.interpolationType > InterpolationType.Linear) {\n        valuesPerTrack = 3;\n      }\n\n      size += (4 + valuesPerTrack * bytesPerValue) * tracksCount;\n    }\n\n    return size;\n  }\n}\n\n/**\n * A uint animation.\n */\nexport class UintAnimation extends Animation {\n  readMdxValue(stream: BinaryStream): Uint32Array {\n    return stream.readUint32Array(1);\n  }\n\n  writeMdxValue(stream: BinaryStream, value: Uint32Array): void {\n    stream.writeUint32(value[0]);\n  }\n\n  readMdlValue(stream: TokenStream): Uint32Array {\n    return new Uint32Array([stream.readInt()]);\n  }\n\n  writeMdlValue(stream: TokenStream, name: string, value: Uint32Array): void {\n    stream.writeNumberAttrib(name, value[0]);\n  }\n}\n\n/**\n * A float animation\n */\nexport class FloatAnimation extends Animation {\n  readMdxValue(stream: BinaryStream): Float32Array {\n    return stream.readFloat32Array(1);\n  }\n\n  writeMdxValue(stream: BinaryStream, value: Float32Array): void {\n    stream.writeFloat32(value[0]);\n  }\n\n  readMdlValue(stream: TokenStream): Float32Array {\n    return new Float32Array([stream.readFloat()]);\n  }\n\n  writeMdlValue(stream: TokenStream, name: string, value: Float32Array): void {\n    stream.writeNumberAttrib(name, value[0]);\n  }\n}\n\n/**\n * A vector 3 animation.\n */\nexport class Vector3Animation extends Animation {\n  readMdxValue(stream: BinaryStream): Float32Array {\n    return stream.readFloat32Array(3);\n  }\n\n  writeMdxValue(stream: BinaryStream, value: Float32Array): void {\n    stream.writeFloat32Array(value);\n  }\n\n  readMdlValue(stream: TokenStream): Float32Array {\n    return stream.readVector(new Float32Array(3));\n  }\n\n  writeMdlValue(stream: TokenStream, name: string, value: Float32Array): void {\n    stream.writeVectorAttrib(name, value);\n  }\n}\n\n/**\n * A vector 4 animation.\n */\nexport class Vector4Animation extends Animation {\n  readMdxValue(stream: BinaryStream): Float32Array {\n    return stream.readFloat32Array(4);\n  }\n\n  writeMdxValue(stream: BinaryStream, value: Float32Array): void {\n    stream.writeFloat32Array(value);\n  }\n\n  readMdlValue(stream: TokenStream): Float32Array {\n    return stream.readVector(new Float32Array(4));\n  }\n\n  writeMdlValue(stream: TokenStream, name: string, value: Float32Array): void {\n    stream.writeVectorAttrib(name, value);\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/attachment.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\n/**\n * An attachment.\n */\nexport default class Attachment extends GenericObject {\n  path = '';\n  attachmentId = 0;\n\n  constructor() {\n    super(0x800);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    super.readMdx(stream);\n\n    this.path = stream.read(260);\n    this.attachmentId = stream.readInt32();\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n\n    super.writeMdx(stream);\n\n    stream.skip(260 - stream.write(this.path));\n    stream.writeInt32(this.attachmentId);\n\n    this.writeNonGenericAnimationChunks(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'AttachmentID') {\n        this.attachmentId = stream.readInt();\n      } else if (token === 'Path') {\n        this.path = stream.read();\n      } else if (token === 'Visibility') {\n        this.readAnimation(stream, 'KATV');\n      } else {\n        throw new Error(`Unknown token in Attachment ${this.name}: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('Attachment', this.name);\n    this.writeGenericHeader(stream);\n\n    stream.writeNumberAttrib('AttachmentID', this.attachmentId); // Is this needed? MDX supplies it, but MdlxConv does not use it.\n\n    if (this.path.length) {\n      stream.writeStringAttrib('Path', this.path);\n    }\n\n    this.writeAnimation(stream, 'KATV');\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 268 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/bone.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\n/**\n * A bone.\n */\nexport default class Bone extends GenericObject {\n  geosetId = -1;\n  geosetAnimationId = -1;\n\n  constructor() {\n    super(0x100);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    super.readMdx(stream);\n\n    this.geosetId = stream.readInt32();\n    this.geosetAnimationId = stream.readInt32();\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    super.writeMdx(stream);\n\n    stream.writeInt32(this.geosetId);\n    stream.writeInt32(this.geosetAnimationId);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (let token of super.readGenericBlock(stream)) {\n      if (token === 'GeosetId') {\n        token = stream.read();\n\n        if (token === 'Multiple') {\n          this.geosetId = -1;\n        } else {\n          this.geosetId = parseInt(token);\n        }\n      } else if (token === 'GeosetAnimId') {\n        token = stream.read();\n\n        if (token === 'None') {\n          this.geosetAnimationId = -1;\n        } else {\n          this.geosetAnimationId = parseInt(token);\n        }\n      } else {\n        throw new Error(`Unknown token in Bone ${this.name}: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('Bone', this.name);\n    this.writeGenericHeader(stream);\n\n    if (this.geosetId === -1) {\n      stream.writeFlagAttrib('GeosetId', 'Multiple');\n    } else {\n      stream.writeNumberAttrib('GeosetId', this.geosetId);\n    }\n\n    if (this.geosetAnimationId === -1) {\n      stream.writeFlagAttrib('GeosetAnimId', 'None');\n    } else {\n      stream.writeNumberAttrib('GeosetAnimId', this.geosetAnimationId);\n    }\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 8 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/camera.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport AnimatedObject from './animatedobject';\n\n/**\n * A camera.\n */\nexport default class Camera extends AnimatedObject {\n  name = '';\n  position = new Float32Array(3);\n  fieldOfView = 0;\n  farClippingPlane = 0;\n  nearClippingPlane = 0;\n  targetPosition = new Float32Array(3);\n\n  readMdx(stream: BinaryStream): void {\n    const size = stream.readUint32();\n\n    this.name = stream.read(80);\n    stream.readFloat32Array(this.position);\n    this.fieldOfView = stream.readFloat32();\n    this.farClippingPlane = stream.readFloat32();\n    this.nearClippingPlane = stream.readFloat32();\n    stream.readFloat32Array(this.targetPosition);\n\n    this.readAnimations(stream, size - 120);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n    stream.skip(80 - stream.write(this.name));\n    stream.writeFloat32Array(this.position);\n    stream.writeFloat32(this.fieldOfView);\n    stream.writeFloat32(this.farClippingPlane);\n    stream.writeFloat32(this.nearClippingPlane);\n    stream.writeFloat32Array(this.targetPosition);\n\n    this.writeAnimations(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    this.name = stream.read();\n\n    for (let token of stream.readBlock()) {\n      if (token === 'Position') {\n        stream.readVector(this.position);\n      } else if (token === 'Translation') {\n        this.readAnimation(stream, 'KCTR');\n      } else if (token === 'Rotation') {\n        this.readAnimation(stream, 'KCRL');\n      } else if (token === 'FieldOfView') {\n        this.fieldOfView = stream.readFloat();\n      } else if (token === 'FarClip') {\n        this.farClippingPlane = stream.readFloat();\n      } else if (token === 'NearClip') {\n        this.nearClippingPlane = stream.readFloat();\n      } else if (token === 'Target') {\n        for (token of stream.readBlock()) {\n          if (token === 'Position') {\n            stream.readVector(this.targetPosition);\n          } else if (token === 'Translation') {\n            this.readAnimation(stream, 'KTTR');\n          } else {\n            throw new Error(`Unknown token in Camera ${this.name}'s Target: \"${token}\"`);\n          }\n        }\n      } else {\n        throw new Error(`Unknown token in Camera ${this.name}: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('Camera', this.name);\n\n    stream.writeVectorAttrib('Position', this.position);\n    this.writeAnimation(stream, 'KCTR');\n    this.writeAnimation(stream, 'KCRL');\n    stream.writeNumberAttrib('FieldOfView', this.fieldOfView);\n    stream.writeNumberAttrib('FarClip', this.farClippingPlane);\n    stream.writeNumberAttrib('NearClip', this.nearClippingPlane);\n\n    stream.startBlock('Target');\n    stream.writeVectorAttrib('Position', this.targetPosition);\n    this.writeAnimation(stream, 'KTTR');\n    stream.endBlock();\n\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 120 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/collisionshape.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\nexport const enum Shape {\n  Box = 0,\n  Plane = 1,\n  Sphere = 2,\n  Cylinder = 3,\n}\n\n/**\n * A collision shape.\n */\nexport default class CollisionShape extends GenericObject {\n  type = Shape.Box;\n  vertices: Float32Array[] = [new Float32Array(3), new Float32Array(3)];\n  boundsRadius = 0;\n\n  constructor() {\n    super(0x2000);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    super.readMdx(stream);\n\n    this.type = stream.readUint32();\n\n    stream.readFloat32Array(this.vertices[0]);\n\n    if (this.type !== Shape.Sphere) {\n      stream.readFloat32Array(this.vertices[1]);\n    }\n\n    if (this.type === Shape.Sphere || this.type === Shape.Cylinder) {\n      this.boundsRadius = stream.readFloat32();\n    }\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    super.writeMdx(stream);\n\n    stream.writeUint32(this.type);\n    stream.writeFloat32Array(this.vertices[0]);\n\n    if (this.type !== Shape.Sphere) {\n      stream.writeFloat32Array(this.vertices[1]);\n    }\n\n    if (this.type === Shape.Sphere || this.type === Shape.Cylinder) {\n      stream.writeFloat32(this.boundsRadius);\n    }\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'Box') {\n        this.type = Shape.Box;\n      } else if (token === 'Plane') {\n        this.type = Shape.Plane;\n      } else if (token === 'Sphere') {\n        this.type = Shape.Sphere;\n      } else if (token === 'Cylinder') {\n        this.type = Shape.Cylinder;\n      } else if (token === 'Vertices') {\n        const count = stream.readInt();\n\n        stream.read(); // {\n\n        stream.readVector(this.vertices[0]);\n\n        if (count === 2) {\n          stream.readVector(this.vertices[1]);\n        }\n\n        stream.read(); // }\n      } else if (token === 'BoundsRadius') {\n        this.boundsRadius = stream.readFloat();\n      } else {\n        throw new Error(`Unknown token in CollisionShape: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('CollisionShape', this.name);\n    this.writeGenericHeader(stream);\n\n    let type = '';\n    let vertices = 2;\n    let boundsRadius = false;\n\n    if (this.type === Shape.Box) {\n      type = 'Box';\n    } else if (this.type === Shape.Plane) {\n      type = 'Plane';\n    } else if (this.type === Shape.Sphere) {\n      type = 'Sphere';\n      vertices = 1;\n      boundsRadius = true;\n    } else if (this.type === Shape.Cylinder) {\n      type = 'Cylinder';\n      boundsRadius = true;\n    }\n\n    stream.writeFlag(type);\n    stream.startBlock('Vertices', vertices);\n    stream.writeVector(this.vertices[0]);\n\n    if (vertices === 2) {\n      stream.writeVector(this.vertices[1]);\n    }\n\n    stream.endBlock();\n\n    if (boundsRadius) {\n      stream.writeNumberAttrib('BoundsRadius', this.boundsRadius);\n    }\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    let size = 16 + super.getByteLength();\n\n    if (this.type !== Shape.Sphere) {\n      size += 12;\n    }\n\n    if (this.type === Shape.Sphere || this.type === Shape.Cylinder) {\n      size += 4;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/eventobject.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\n/**\n * An event object.\n */\nexport default class EventObject extends GenericObject {\n  globalSequenceId = -1;\n  tracks = new Uint32Array(0);\n\n  constructor() {\n    super(0x400);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    super.readMdx(stream);\n\n    stream.skip(4); // KEVT\n\n    const count = stream.readUint32();\n\n    this.globalSequenceId = stream.readInt32();\n    this.tracks = stream.readUint32Array(count);\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    super.writeMdx(stream);\n    stream.writeBinary('KEVT');\n    stream.writeUint32(this.tracks.length);\n    stream.writeInt32(this.globalSequenceId);\n    stream.writeUint32Array(this.tracks);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'EventTrack') {\n        const count = stream.readInt();\n\n        this.tracks = new Uint32Array(count);\n\n        stream.read(); // {\n\n        if (stream.peek() === 'GlobalSeqId') {\n          stream.read();\n\n          this.globalSequenceId = stream.readInt();\n        }\n\n        for (let i = 0; i < count; i++) {\n          this.tracks[i] = stream.readInt();\n        }\n\n        stream.read(); // }\n      } else {\n        throw new Error(`Unknown token in EventObject: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('EventObject', this.name);\n    this.writeGenericHeader(stream);\n\n    stream.startBlock('EventTrack', this.tracks.length);\n\n    if (this.globalSequenceId !== -1) {\n      stream.writeNumberAttrib('GlobalSeqId', this.globalSequenceId);\n    }\n\n    for (const track of this.tracks) {\n      stream.writeFlag(`${track}`);\n    }\n\n    stream.endBlock();\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 12 + this.tracks.byteLength + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/extent.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\n\n/**\n * An extent.\n */\nexport default class Extent {\n  boundsRadius = 0;\n  min = new Float32Array(3);\n  max = new Float32Array(3);\n\n  readMdx(stream: BinaryStream): void {\n    this.boundsRadius = stream.readFloat32();\n    stream.readFloat32Array(this.min);\n    stream.readFloat32Array(this.max);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeFloat32(this.boundsRadius);\n    stream.writeFloat32Array(this.min);\n    stream.writeFloat32Array(this.max);\n  }\n\n  writeMdl(stream: TokenStream): void {\n    if (this.min[0] !== 0 || this.min[1] !== 0 || this.min[2] !== 0) {\n      stream.writeVectorAttrib('MinimumExtent', this.min);\n    }\n\n    if (this.max[0] !== 0 || this.max[1] !== 0 || this.max[2] !== 0) {\n      stream.writeVectorAttrib('MaximumExtent', this.max);\n    }\n\n    if (this.boundsRadius !== 0) {\n      stream.writeNumberAttrib('BoundsRadius', this.boundsRadius);\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/faceeffect.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\n\n/**\n * A face effect.\n */\nexport default class FaceEffect {\n  type = '';\n  path = '';\n\n  readMdx(stream: BinaryStream): void {\n    this.type = stream.read(80);\n    this.path = stream.read(260);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.skip(80 - stream.write(this.type));\n    stream.skip(260 - stream.write(this.path));\n  }\n\n  readMdl(stream: TokenStream): void {\n    this.type = stream.read();\n\n    for (const token of stream.readBlock()) {\n      if (token === 'Path') {\n        this.path = stream.read();\n      } else {\n        throw new Error(`Unknown token in FaceEffect: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('FaceFX', this.type);\n    stream.writeStringAttrib('Path', this.path);\n    stream.endBlock();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/genericobject.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport AnimatedObject from './animatedobject';\nimport { Animation } from './animations';\n\nexport const enum Flags {\n  None = 0x0,\n  DontInheritTranslation = 0x1,\n  DontInheritScaling = 0x2,\n  DontInheritRotation = 0x4,\n  Billboarded = 0x8,\n  BillboardedLockX = 0x10,\n  BillboardedLockY = 0x20,\n  BillboardedLockZ = 0x40,\n  CameraAnchored = 0x80,\n}\n\n/**\n * A generic object.\n *\n * The parent class for all objects that exist in the world, and may contain spatial animations.\n * This includes bones, particle emitters, and many other things.\n */\nexport default abstract class GenericObject extends AnimatedObject {\n  name = '';\n  objectId = -1;\n  parentId = -1;\n  flags: Flags;\n\n  constructor(flags = Flags.None) {\n    super();\n\n    this.flags = flags;\n  }\n\n  readMdx(stream: BinaryStream): void {\n    const size = stream.readUint32();\n\n    this.name = stream.read(80);\n    this.objectId = stream.readInt32();\n    this.parentId = stream.readInt32();\n    this.flags = stream.readUint32();\n\n    this.readAnimations(stream, size - 96);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getGenericByteLength());\n    stream.skip(80 - stream.write(this.name));\n    stream.writeInt32(this.objectId);\n    stream.writeInt32(this.parentId);\n    stream.writeUint32(this.flags);\n\n    for (const animation of this.eachAnimation(true)) {\n      animation.writeMdx(stream);\n    }\n  }\n\n  writeNonGenericAnimationChunks(stream: BinaryStream): void {\n    for (const animation of this.eachAnimation(false)) {\n      animation.writeMdx(stream);\n    }\n  }\n\n  * readGenericBlock(stream: TokenStream): Generator<string> {\n    this.name = stream.read();\n\n    for (let token of this.readAnimatedBlock(stream)) {\n      if (token === 'ObjectId') {\n        this.objectId = stream.readInt();\n      } else if (token === 'Parent') {\n        this.parentId = stream.readInt();\n      } else if (token === 'BillboardedLockZ') {\n        this.flags |= Flags.BillboardedLockZ;\n      } else if (token === 'BillboardedLockY') {\n        this.flags |= Flags.BillboardedLockY;\n      } else if (token === 'BillboardedLockX') {\n        this.flags |= Flags.BillboardedLockX;\n      } else if (token === 'Billboarded') {\n        this.flags |= Flags.Billboarded;\n      } else if (token === 'CameraAnchored') {\n        this.flags |= Flags.CameraAnchored;\n      } else if (token === 'DontInherit') {\n        for (token of stream.readBlock()) {\n          if (token === 'Rotation') {\n            this.flags |= Flags.DontInheritRotation;\n          } else if (token === 'Translation') {\n            this.flags |= Flags.DontInheritTranslation;\n          } else if (token === 'Scaling') {\n            this.flags |= Flags.DontInheritScaling;\n          }\n        }\n      } else if (token === 'Translation') {\n        this.readAnimation(stream, 'KGTR');\n      } else if (token === 'Rotation') {\n        this.readAnimation(stream, 'KGRT');\n      } else if (token === 'Scaling') {\n        this.readAnimation(stream, 'KGSC');\n      } else {\n        yield token;\n      }\n    }\n  }\n\n  writeGenericHeader(stream: TokenStream): void {\n    stream.writeNumberAttrib('ObjectId', this.objectId);\n\n    if (this.parentId !== -1) {\n      stream.writeNumberAttrib('Parent', this.parentId);\n    }\n\n    if (this.flags & Flags.BillboardedLockZ) {\n      stream.writeFlag('BillboardedLockZ');\n    }\n\n    if (this.flags & Flags.BillboardedLockY) {\n      stream.writeFlag('BillboardedLockY');\n    }\n\n    if (this.flags & Flags.BillboardedLockX) {\n      stream.writeFlag('BillboardedLockX');\n    }\n\n    if (this.flags & Flags.Billboarded) {\n      stream.writeFlag('Billboarded');\n    }\n\n    if (this.flags & Flags.CameraAnchored) {\n      stream.writeFlag('CameraAnchored');\n    }\n\n    if (this.flags & Flags.DontInheritRotation) {\n      stream.writeFlag(`DontInherit { Rotation }`);\n    }\n\n    if (this.flags & Flags.DontInheritTranslation) {\n      stream.writeFlag(`DontInherit { Translation }`);\n    }\n\n    if (this.flags & Flags.DontInheritScaling) {\n      stream.writeFlag(`DontInherit { Scaling }`);\n    }\n  }\n\n  writeGenericAnimations(stream: TokenStream): void {\n    this.writeAnimation(stream, 'KGTR');\n    this.writeAnimation(stream, 'KGRT');\n    this.writeAnimation(stream, 'KGSC');\n  }\n\n  /**\n   * Allows to easily iterate either the GenericObject animations or the parent object animations.\n   */\n  * eachAnimation(wantGeneric: boolean): Generator<Animation> {\n    for (const animation of this.animations) {\n      const name = animation.name;\n      const isGeneric = (name === 'KGTR' || name === 'KGRT' || name === 'KGSC');\n\n      if ((wantGeneric && isGeneric) || (!wantGeneric && !isGeneric)) {\n        yield animation;\n      }\n    }\n  }\n\n  /**\n   * Gets the byte length of the GenericObject part of whatever this object this.\n   * \n   * This is needed because only the KGTR, KGRT, and KGSC animations actually belong to it.\n   */\n  getGenericByteLength(): number {\n    let size = 96;\n\n    for (const animation of this.eachAnimation(true)) {\n      size += animation.getByteLength();\n    }\n\n    return size;\n  }\n\n  override getByteLength(): number {\n    return 96 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/geoset.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport Extent from './extent';\n\n/**\n * A geoset.\n */\nexport default class Geoset {\n  vertices = new Float32Array(0);\n  normals = new Float32Array(0);\n  faceTypeGroups = new Uint32Array(0);\n  faceGroups = new Uint32Array(0);\n  faces = new Uint16Array(0);\n  vertexGroups = new Uint8Array(0);\n  matrixGroups = new Uint32Array(0);\n  matrixIndices = new Uint32Array(0);\n  materialId = 0;\n  selectionGroup = 0;\n  selectionFlags = 0;\n  /** \n   * @since 900\n   */\n  lod = -1;\n  /** \n   * @since 900\n   */\n  lodName = '';\n  extent = new Extent();\n  sequenceExtents: Extent[] = [];\n  /** \n   * @since 900\n   */\n  tangents = new Float32Array(0);\n  /**\n   * An array of bone indices and weights.\n   * Every 8 consecutive elements describe the following:\n   *    [B0, B1, B2, B3, W0, W1, W2, W3]\n   * Where:\n   *     Bn is a bone index.\n   *     Wn is a weight, which can be normalized with Wn/255.\n   *\n   * @since 900\n   */\n  skin = new Uint8Array(0);\n  uvSets: Float32Array[] = [];\n\n  readMdx(stream: BinaryStream, version: number): void {\n    stream.readUint32(); // Don't care about the size.\n\n    stream.skip(4); // VRTX\n    this.vertices = stream.readFloat32Array(stream.readUint32() * 3);\n    stream.skip(4); // NRMS\n    this.normals = stream.readFloat32Array(stream.readUint32() * 3);\n    stream.skip(4); // PTYP\n    this.faceTypeGroups = stream.readUint32Array(stream.readUint32());\n    stream.skip(4); // PCNT\n    this.faceGroups = stream.readUint32Array(stream.readUint32());\n    stream.skip(4); // PVTX\n    this.faces = stream.readUint16Array(stream.readUint32());\n    stream.skip(4); // GNDX\n    this.vertexGroups = stream.readUint8Array(stream.readUint32());\n    stream.skip(4); // MTGC\n    this.matrixGroups = stream.readUint32Array(stream.readUint32());\n    stream.skip(4); // MATS\n    this.matrixIndices = stream.readUint32Array(stream.readUint32());\n    this.materialId = stream.readUint32();\n    this.selectionGroup = stream.readUint32();\n    this.selectionFlags = stream.readUint32();\n\n    if (version > 800) {\n      this.lod = stream.readInt32();\n      this.lodName = stream.read(80);\n    }\n\n    this.extent.readMdx(stream);\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const extent = new Extent();\n\n      extent.readMdx(stream);\n\n      this.sequenceExtents.push(extent);\n    }\n\n    // Non-reforged models that come with reforged are saved with version >800, however they don't have TANG and SKIN.\n    if (version > 800) {\n      if (stream.readBinary(4) === 'TANG') {\n        this.tangents = stream.readFloat32Array(stream.readUint32() * 4);\n      } else {\n        stream.skip(-4);\n      }\n\n      if (stream.readBinary(4) === 'SKIN') {\n        this.skin = stream.readUint8Array(stream.readUint32());\n      } else {\n        stream.skip(-4);\n      }\n    }\n\n    stream.skip(4); // UVAS\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      stream.skip(4); // UVBS\n      this.uvSets.push(stream.readFloat32Array(stream.readUint32() * 2));\n    }\n  }\n\n  writeMdx(stream: BinaryStream, version: number): void {\n    stream.writeUint32(this.getByteLength(version));\n    stream.writeBinary('VRTX');\n    stream.writeUint32(this.vertices.length / 3);\n    stream.writeFloat32Array(this.vertices);\n    stream.writeBinary('NRMS');\n    stream.writeUint32(this.normals.length / 3);\n    stream.writeFloat32Array(this.normals);\n    stream.writeBinary('PTYP');\n    stream.writeUint32(this.faceTypeGroups.length);\n    stream.writeUint32Array(this.faceTypeGroups);\n    stream.writeBinary('PCNT');\n    stream.writeUint32(this.faceGroups.length);\n    stream.writeUint32Array(this.faceGroups);\n    stream.writeBinary('PVTX');\n    stream.writeUint32(this.faces.length);\n    stream.writeUint16Array(this.faces);\n    stream.writeBinary('GNDX');\n    stream.writeUint32(this.vertexGroups.length);\n    stream.writeUint8Array(this.vertexGroups);\n    stream.writeBinary('MTGC');\n    stream.writeUint32(this.matrixGroups.length);\n    stream.writeUint32Array(this.matrixGroups);\n    stream.writeBinary('MATS');\n    stream.writeUint32(this.matrixIndices.length);\n    stream.writeUint32Array(this.matrixIndices);\n    stream.writeUint32(this.materialId);\n    stream.writeUint32(this.selectionGroup);\n    stream.writeUint32(this.selectionFlags);\n\n    if (version > 800) {\n      stream.writeInt32(this.lod);\n      stream.skip(80 - stream.write(this.lodName));\n    }\n\n    this.extent.writeMdx(stream);\n\n    stream.writeUint32(this.sequenceExtents.length);\n\n    for (const sequenceExtent of this.sequenceExtents) {\n      sequenceExtent.writeMdx(stream);\n    }\n\n    if (version > 800) {\n      if (this.tangents.length) {\n        stream.writeBinary('TANG');\n        stream.writeUint32(this.tangents.length / 4);\n        stream.writeFloat32Array(this.tangents);\n      }\n\n      if (this.skin.length) {\n        stream.writeBinary('SKIN');\n        stream.writeUint32(this.skin.length);\n        stream.writeUint8Array(this.skin);\n      }\n    }\n\n    stream.writeBinary('UVAS');\n    stream.writeUint32(this.uvSets.length);\n\n    for (const uvSet of this.uvSets) {\n      stream.writeBinary('UVBS');\n      stream.writeUint32(uvSet.length / 2);\n      stream.writeFloat32Array(uvSet);\n    }\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (let token of stream.readBlock()) {\n      if (token === 'Vertices') {\n        this.vertices = stream.readVectorsBlock(new Float32Array(stream.readInt() * 3), 3);\n      } else if (token === 'Normals') {\n        this.normals = stream.readVectorsBlock(new Float32Array(stream.readInt() * 3), 3);\n      } else if (token === 'TVertices') {\n        this.uvSets.push(stream.readVectorsBlock(new Float32Array(stream.readInt() * 2), 2));\n      } else if (token === 'VertexGroup') {\n        // Vertex groups are stored in a block with no count, can't allocate the buffer yet.\n        const vertexGroups = [];\n\n        for (const vertexGroup of stream.readBlock()) {\n          vertexGroups.push(parseInt(vertexGroup));\n        }\n\n        this.vertexGroups = new Uint8Array(vertexGroups);\n      } else if (token === 'Tangents') {\n        this.tangents = stream.readVectorsBlock(new Float32Array(stream.readInt() * 4), 4);\n      } else if (token === 'SkinWeights') {\n        this.skin = stream.readVector(new Uint8Array(stream.readInt() * 8));\n      } else if (token === 'Faces') {\n        // For now hardcoded for triangles, until I see a model with something different.\n        this.faceTypeGroups = new Uint32Array([4]);\n\n        // Number of vectors the indices are spread over.\n        const vectors = stream.readInt();\n\n        // Total number of indices.\n        const count = stream.readInt();\n\n        stream.read(); // {\n        stream.read(); // Triangles\n\n        this.faces = stream.readVectorsBlock(new Uint16Array(count), count / vectors);\n\n        // Declare that all of the faces are in one group to conform with MDX.\n        this.faceGroups = new Uint32Array([count]);\n\n        stream.read(); // }\n      } else if (token === 'Groups') {\n        const indices = [];\n        const groups = [];\n\n        stream.readInt(); // matrices count\n        stream.readInt(); // total indices\n\n        for (const _ of stream.readBlock()) {\n          let size = 0;\n\n          for (const index of stream.readBlock()) {\n            indices.push(parseInt(index));\n            size += 1;\n          }\n\n          groups.push(size);\n        }\n\n        this.matrixIndices = new Uint32Array(indices);\n        this.matrixGroups = new Uint32Array(groups);\n      } else if (token === 'MinimumExtent') {\n        stream.readVector(this.extent.min);\n      } else if (token === 'MaximumExtent') {\n        stream.readVector(this.extent.max);\n      } else if (token === 'BoundsRadius') {\n        this.extent.boundsRadius = stream.readFloat();\n      } else if (token === 'Anim') {\n        const extent = new Extent();\n\n        for (token of stream.readBlock()) {\n          if (token === 'MinimumExtent') {\n            stream.readVector(extent.min);\n          } else if (token === 'MaximumExtent') {\n            stream.readVector(extent.max);\n          } else if (token === 'BoundsRadius') {\n            extent.boundsRadius = stream.readFloat();\n          }\n        }\n\n        this.sequenceExtents.push(extent);\n      } else if (token === 'MaterialID') {\n        this.materialId = stream.readInt();\n      } else if (token === 'SelectionGroup') {\n        this.selectionGroup = stream.readInt();\n      } else if (token === 'Unselectable') {\n        this.selectionFlags = 4;\n      } else if (token === 'LevelOfDetail') {\n        this.lod = stream.readInt();\n      } else if (token === 'Name') {\n        this.lodName = stream.read();\n      } else {\n        throw new Error(`Unknown token in Geoset: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream, version: number): void {\n    stream.startBlock('Geoset');\n\n    stream.writeVectorArrayBlock('Vertices', this.vertices, 3);\n    stream.writeVectorArrayBlock('Normals', this.normals, 3);\n\n    for (const uvSet of this.uvSets) {\n      stream.writeVectorArrayBlock('TVertices', uvSet, 2);\n    }\n\n    if (version > 800 && this.tangents.length) {\n      stream.writeVectorArrayBlock('Tangents', this.tangents, 4);\n    }\n\n    // Always write vertex groups if they exist.\n    if (this.vertexGroups.length) {\n      stream.startBlock('VertexGroup');\n\n      for (let i = 0, l = this.vertexGroups.length; i < l; i++) {\n        stream.writeLine(`${this.vertexGroups[i]},`);\n      }\n\n      stream.endBlock();\n    }\n\n    // If this is a Reforged HD geoset, write the skin.\n    if (version > 800 && this.skin.length) {\n      stream.startBlock('SkinWeights', this.skin.length / 8);\n\n      for (let i = 0, l = this.skin.length; i < l; i += 8) {\n        stream.writeLine(`${this.skin.subarray(i, i + 8).join(', ')},`);\n      }\n\n      stream.endBlock();\n    }\n\n    // For now hardcoded for triangles, until I see a model with something different.\n    stream.startBlock('Faces', 1, this.faces.length);\n    stream.startBlock('Triangles');\n    stream.writeVector(this.faces);\n    stream.endBlock();\n    stream.endBlock();\n\n    stream.startBlock('Groups', this.matrixGroups.length, this.matrixIndices.length);\n    let index = 0;\n    for (const groupSize of this.matrixGroups) {\n      stream.writeVectorAttrib('Matrices', this.matrixIndices.subarray(index, index + groupSize));\n      index += groupSize;\n    }\n    stream.endBlock();\n\n    this.extent.writeMdl(stream);\n\n    for (const sequenceExtent of this.sequenceExtents) {\n      stream.startBlock('Anim');\n      sequenceExtent.writeMdl(stream);\n      stream.endBlock();\n    }\n\n    stream.writeNumberAttrib('MaterialID', this.materialId);\n    stream.writeNumberAttrib('SelectionGroup', this.selectionGroup);\n\n    if (this.selectionFlags === 4) {\n      stream.writeFlag('Unselectable');\n    }\n\n    if (version > 800) {\n      stream.writeNumberAttrib('LevelOfDetail', this.lod);\n\n      if (this.lodName.length) {\n        stream.writeStringAttrib('Name', this.lodName);\n      }\n    }\n\n    stream.endBlock();\n  }\n\n  getByteLength(version: number): number {\n    let size = 120 + this.vertices.byteLength + this.normals.byteLength + this.faceTypeGroups.byteLength + this.faceGroups.byteLength + this.faces.byteLength + this.vertexGroups.byteLength + this.matrixGroups.byteLength + this.matrixIndices.byteLength + this.sequenceExtents.length * 28;\n\n    if (version > 800) {\n      size += 84;\n\n      if (this.tangents.length) {\n        size += 8 + this.tangents.byteLength;\n      }\n\n      if (this.skin.length) {\n        size += 8 + this.skin.byteLength;\n      }\n    }\n\n    for (const uvSet of this.uvSets) {\n      size += 8 + uvSet.byteLength;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/geosetanimation.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport AnimatedObject from './animatedobject';\n\n/**\n * A geoset animation.\n */\nexport default class GeosetAnimation extends AnimatedObject {\n  alpha = 1;\n  flags = 0;\n  color = new Float32Array([1, 1, 1]);\n  geosetId = -1;\n\n  readMdx(stream: BinaryStream): void {\n    const size = stream.readUint32();\n\n    this.alpha = stream.readFloat32();\n    this.flags = stream.readUint32();\n    stream.readFloat32Array(this.color);\n    this.geosetId = stream.readInt32();\n\n    this.readAnimations(stream, size - 28);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n    stream.writeFloat32(this.alpha);\n    stream.writeUint32(this.flags);\n    stream.writeFloat32Array(this.color);\n    stream.writeInt32(this.geosetId);\n\n    this.writeAnimations(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readAnimatedBlock(stream)) {\n      if (token === 'DropShadow') {\n        this.flags |= 0x1;\n      } else if (token === 'static Alpha') {\n        this.alpha = stream.readFloat();\n      } else if (token === 'Alpha') {\n        this.readAnimation(stream, 'KGAO');\n      } else if (token === 'static Color') {\n        this.flags |= 0x2;\n        stream.readColor(this.color);\n      } else if (token === 'Color') {\n        this.flags |= 0x2;\n        this.readAnimation(stream, 'KGAC');\n      } else if (token === 'GeosetId') {\n        this.geosetId = stream.readInt();\n      } else {\n        throw new Error(`Unknown token in GeosetAnimation: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startBlock('GeosetAnim');\n\n    if (this.flags & 0x1) {\n      stream.writeFlag('DropShadow');\n    }\n\n    if (!this.writeAnimation(stream, 'KGAO')) {\n      stream.writeNumberAttrib('static Alpha', this.alpha);\n    }\n\n    if (this.flags & 0x2) {\n      if (!this.writeAnimation(stream, 'KGAC') && (this.color[0] !== 1 || this.color[1] !== 1 || this.color[2] !== 1)) {\n        stream.writeColor('static Color ', this.color);\n      }\n    }\n\n    stream.writeNumberAttrib('GeosetId', this.geosetId);\n\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 28 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/helper.ts",
    "content": "import TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\n/**\n * A helper.\n */\nexport default class Helper extends GenericObject {\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      throw new Error(`Unknown token in Helper: \"${token}\"`);\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('Helper', this.name);\n    this.writeGenericHeader(stream);\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/index.ts",
    "content": "import Model from './model';\nimport Sequence from './sequence';\nimport Material from './material';\nimport Layer from './layer';\nimport Texture from './texture';\nimport TextureAnimation from './textureanimation';\nimport Geoset from './geoset';\nimport GeosetAnimation from './geosetanimation';\nimport Bone from './bone';\nimport Light from './light';\nimport Helper from './helper';\nimport Attachment from './attachment';\nimport ParticleEmitter from './particleemitter';\nimport ParticleEmitter2 from './particleemitter2';\nimport ParticleEmitterPopcorn from './particleemitterpopcorn';\nimport RibbonEmitter from './ribbonemitter';\nimport Camera from './camera';\nimport EventObject from './eventobject';\nimport CollisionShape from './collisionshape';\nimport UnknownChunk from './unknownchunk';\nimport TokenStream from './tokenstream';\nimport { isMdx, isMdl } from './isformat';\n\nexport default {\n  Model,\n  Sequence,\n  Material,\n  Layer,\n  Texture,\n  TextureAnimation,\n  Geoset,\n  GeosetAnimation,\n  Bone,\n  Light,\n  Helper,\n  Attachment,\n  ParticleEmitter,\n  ParticleEmitter2,\n  ParticleEmitterPopcorn,\n  RibbonEmitter,\n  Camera,\n  EventObject,\n  CollisionShape,\n  UnknownChunk,\n  TokenStream,\n  isMdx,\n  isMdl,\n};\n"
  },
  {
    "path": "src/parsers/mdlx/isformat.ts",
    "content": "import { isStringInBytes, isStringInString } from '../../common/searches';\n\n/**\n * Detects if the given object is an MDX source.\n */\nexport function isMdx(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array) {\n    if (bytes[0] === 0x4d && bytes[1] === 0x44 && bytes[2] === 0x4c && bytes[3] === 0x58) {\n      return true;\n    }\n  }\n\n  if (typeof bytes === 'string' && bytes.startsWith('MDLX')) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Detects if the given object is an MDL source.\n */\nexport function isMdl(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  // Look for FormatVersion in the first 4KB.\n  if (bytes instanceof Uint8Array && isStringInBytes(bytes, 'FormatVersion', 0, 4096)) {\n    return true;\n  }\n\n  // If the source is a string, look for FormatVersion same as above.\n  if (typeof bytes === 'string' && isStringInString(bytes, 'FormatVersion', 0, 4096)) {\n    return true;\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/parsers/mdlx/layer.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport AnimatedObject from './animatedobject';\n\nexport const enum FilterMode {\n  None = 0,\n  Transparent = 1,\n  Blend = 2,\n  Additive = 3,\n  AddAlpha = 4,\n  Modulate = 5,\n  Modulate2x = 6,\n}\n\nexport const enum Flags {\n  None = 0x0,\n  Unshaded = 0x1,\n  SphereEnvMap = 0x2,\n  TwoSided = 0x10,\n  Unfogged = 0x20,\n  NoDepthTest = 0x40,\n  NoDepthSet = 0x80,\n  Unlit = 0x100,\n}\n\n// These two functions are needed because I am using const enums, which lets TS completely remove them from the output.\n// I think it's worth it for the price of these two functions that effectively were always here either way.\nfunction stringToMode(s: string): FilterMode {\n  if (s === 'None') return FilterMode.None;\n  if (s === 'Transparent') return FilterMode.Transparent;\n  if (s === 'Blend') return FilterMode.Blend;\n  if (s === 'Additive') return FilterMode.Additive;\n  if (s === 'AddAlpha') return FilterMode.AddAlpha;\n  if (s === 'Modulate') return FilterMode.Modulate;\n  if (s === 'Modulate2x') return FilterMode.Modulate2x;\n  return FilterMode.None;\n}\n\nfunction modeToString(m: FilterMode): string {\n  if (m === FilterMode.None) return 'None';\n  if (m === FilterMode.Transparent) return 'Transparent';\n  if (m === FilterMode.Blend) return 'Blend';\n  if (m === FilterMode.Additive) return 'Additive';\n  if (m === FilterMode.AddAlpha) return 'AddAlpha';\n  if (m === FilterMode.Modulate) return 'Modulate';\n  if (m === FilterMode.Modulate2x) return 'Modulate2x';\n  return 'None';\n}\n\n/**\n * A layer.\n */\nexport default class Layer extends AnimatedObject {\n  filterMode = FilterMode.None;\n  flags = Flags.None;\n  textureId = -1;\n  textureAnimationId = -1;\n  coordId = 0;\n  alpha = 1;\n  /** \n   * @since 900\n   */\n  emissiveGain = 1;\n  /** \n   * @since 1000\n   */\n  fresnelColor = new Float32Array([1, 1, 1]);\n  /** \n   * @since 1000\n   */\n  fresnelOpacity = 0;\n  /** \n   * @since 1000\n   */\n  fresnelTeamColor = 0;\n\n  readMdx(stream: BinaryStream, version: number): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    this.filterMode = stream.readUint32();\n    this.flags = stream.readUint32();\n    this.textureId = stream.readInt32();\n    this.textureAnimationId = stream.readInt32();\n    this.coordId = stream.readUint32();\n    this.alpha = stream.readFloat32();\n\n    // Note that even though these fields were introduced in versions 900 and 1000 separately, the game does not offer backwards compatibility.\n    if (version > 800) {\n      this.emissiveGain = stream.readFloat32();\n      stream.readFloat32Array(this.fresnelColor);\n      this.fresnelOpacity = stream.readFloat32();\n      this.fresnelTeamColor = stream.readFloat32();\n    }\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  writeMdx(stream: BinaryStream, version: number): void {\n    stream.writeUint32(this.getByteLength(version));\n    stream.writeUint32(this.filterMode);\n    stream.writeUint32(this.flags);\n    stream.writeInt32(this.textureId);\n    stream.writeInt32(this.textureAnimationId);\n    stream.writeUint32(this.coordId);\n    stream.writeFloat32(this.alpha);\n\n    // See note above in readMdx.\n    if (version > 800) {\n      stream.writeFloat32(this.emissiveGain);\n      stream.writeFloat32Array(this.fresnelColor);\n      stream.writeFloat32(this.fresnelOpacity);\n      stream.writeFloat32(this.fresnelTeamColor);\n    }\n\n    this.writeAnimations(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readAnimatedBlock(stream)) {\n      if (token === 'FilterMode') {\n        this.filterMode = stringToMode(stream.read());\n      } else if (token === 'Unshaded') {\n        this.flags |= Flags.Unshaded;\n      } else if (token === 'SphereEnvMap') {\n        this.flags |= Flags.SphereEnvMap;\n      } else if (token === 'TwoSided') {\n        this.flags |= Flags.TwoSided;\n      } else if (token === 'Unfogged') {\n        this.flags |= Flags.Unfogged;\n      } else if (token === 'NoDepthTest') {\n        this.flags |= Flags.NoDepthTest;\n      } else if (token === 'NoDepthSet') {\n        this.flags |= Flags.NoDepthSet;\n      } else if (token === 'Unlit') {\n        this.flags |= Flags.Unlit;\n      } else if (token === 'static TextureID') {\n        this.textureId = stream.readInt();\n      } else if (token === 'TextureID') {\n        this.readAnimation(stream, 'KMTF');\n      } else if (token === 'TVertexAnimId') {\n        this.textureAnimationId = stream.readInt();\n      } else if (token === 'CoordId') {\n        this.coordId = stream.readInt();\n      } else if (token === 'static Alpha') {\n        this.alpha = stream.readFloat();\n      } else if (token === 'Alpha') {\n        this.readAnimation(stream, 'KMTA');\n      } else if (token === 'static EmissiveGain') {\n        this.emissiveGain = stream.readFloat();\n      } else if (token === 'EmissiveGain') {\n        this.readAnimation(stream, 'KMTE');\n      } else if (token === 'static FresnelColor') {\n        stream.readVector(this.fresnelColor);\n      } else if (token === 'FresnelColor') {\n        this.readAnimation(stream, 'KFC3');\n      } else if (token === 'static FresnelOpacity') {\n        this.fresnelOpacity = stream.readFloat();\n      } else if (token === 'FresnelOpacity') {\n        this.readAnimation(stream, 'KFCA');\n      } else if (token === 'static FresnelTeamColor') {\n        this.fresnelTeamColor = stream.readFloat();\n      } else if (token === 'FresnelTeamColor') {\n        this.readAnimation(stream, 'KFTC');\n      } else {\n        throw new Error(`Unknown token in Layer: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream, version: number): void {\n    stream.startBlock('Layer');\n\n    stream.writeFlagAttrib('FilterMode', modeToString(this.filterMode));\n\n    if (this.flags & Flags.Unshaded) {\n      stream.writeFlag('Unshaded');\n    }\n\n    if (this.flags & Flags.SphereEnvMap) {\n      stream.writeFlag('SphereEnvMap');\n    }\n\n    if (this.flags & Flags.TwoSided) {\n      stream.writeFlag('TwoSided');\n    }\n\n    if (this.flags & Flags.Unfogged) {\n      stream.writeFlag('Unfogged');\n    }\n\n    if (this.flags & Flags.NoDepthTest) {\n      stream.writeFlag('NoDepthTest');\n    }\n\n    if (this.flags & Flags.NoDepthSet) {\n      stream.writeFlag('NoDepthSet');\n    }\n\n    if (version > 800) {\n      if (this.flags & Flags.Unlit) {\n        stream.writeFlag('Unlit');\n      }\n    }\n\n    if (!this.writeAnimation(stream, 'KMTF')) {\n      stream.writeNumberAttrib('static TextureID', this.textureId);\n    }\n\n    if (this.textureAnimationId !== -1) {\n      stream.writeNumberAttrib('TVertexAnimId', this.textureAnimationId);\n    }\n\n    if (this.coordId !== 0) {\n      stream.writeNumberAttrib('CoordId', this.coordId);\n    }\n\n    if (!this.writeAnimation(stream, 'KMTA') && this.alpha !== 1) {\n      stream.writeNumberAttrib('static Alpha', this.alpha);\n    }\n\n    if (version > 800) {\n      if (!this.writeAnimation(stream, 'KMTE') && this.emissiveGain !== 1) {\n        stream.writeNumberAttrib('static EmissiveGain', this.emissiveGain);\n      }\n\n      if (!this.writeAnimation(stream, 'KFC3') && (this.fresnelColor[0] !== 1 || this.fresnelColor[1] !== 1 || this.fresnelColor[2] !== 1)) {\n        stream.writeVectorAttrib('static FresnelColor', this.fresnelColor);\n      }\n\n      if (!this.writeAnimation(stream, 'KFCA') && this.fresnelOpacity !== 0) {\n        stream.writeNumberAttrib('static FresnelOpacity', this.fresnelOpacity);\n      }\n\n      if (!this.writeAnimation(stream, 'KFTC') && this.fresnelTeamColor !== 0) {\n        stream.writeNumberAttrib('static FresnelTeamColor', this.fresnelTeamColor);\n      }\n    }\n\n    stream.endBlock();\n  }\n\n  override getByteLength(version: number): number {\n    let size = 28 + super.getByteLength();\n\n    // See note above in readMdx.\n    if (version > 800) {\n      size += 24;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/light.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\nexport const enum LightType {\n  None = -1,\n  Omnidirectional = 0,\n  Directional = 1,\n  Ambient = 2,\n}\n\n/**\n * A light.\n */\nexport default class Light extends GenericObject {\n  type = LightType.None;\n  attenuation = new Float32Array(2);\n  color = new Float32Array(3);\n  intensity = 0;\n  ambientColor = new Float32Array(3);\n  ambientIntensity = 0;\n\n  constructor() {\n    super(0x200);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    super.readMdx(stream);\n\n    this.type = stream.readUint32();\n    stream.readFloat32Array(this.attenuation);\n    stream.readFloat32Array(this.color);\n    this.intensity = stream.readFloat32();\n    stream.readFloat32Array(this.ambientColor);\n    this.ambientIntensity = stream.readFloat32();\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n\n    super.writeMdx(stream);\n\n    stream.writeUint32(this.type);\n    stream.writeFloat32Array(this.attenuation);\n    stream.writeFloat32Array(this.color);\n    stream.writeFloat32(this.intensity);\n    stream.writeFloat32Array(this.ambientColor);\n    stream.writeFloat32(this.ambientIntensity);\n\n    this.writeNonGenericAnimationChunks(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'Omnidirectional') {\n        this.type = LightType.Omnidirectional;\n      } else if (token === 'Directional') {\n        this.type = LightType.Directional;\n      } else if (token === 'Ambient') {\n        this.type = LightType.Ambient;\n      } else if (token === 'static AttenuationStart') {\n        this.attenuation[0] = stream.readFloat();\n      } else if (token === 'AttenuationStart') {\n        this.readAnimation(stream, 'KLAS');\n      } else if (token === 'static AttenuationEnd') {\n        this.attenuation[1] = stream.readFloat();\n      } else if (token === 'AttenuationEnd') {\n        this.readAnimation(stream, 'KLAE');\n      } else if (token === 'static Intensity') {\n        this.intensity = stream.readFloat();\n      } else if (token === 'Intensity') {\n        this.readAnimation(stream, 'KLAI');\n      } else if (token === 'static Color') {\n        stream.readColor(this.color);\n      } else if (token === 'Color') {\n        this.readAnimation(stream, 'KLAC');\n      } else if (token === 'static AmbIntensity') {\n        this.ambientIntensity = stream.readFloat();\n      } else if (token === 'AmbIntensity') {\n        this.readAnimation(stream, 'KLBI');\n      } else if (token === 'static AmbColor') {\n        stream.readColor(this.ambientColor);\n      } else if (token === 'AmbColor') {\n        this.readAnimation(stream, 'KLBC');\n      } else if (token === 'Visibility') {\n        this.readAnimation(stream, 'KLAV');\n      } else {\n        throw new Error(`Unknown token in Light: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('Light', this.name);\n    this.writeGenericHeader(stream);\n\n    if (this.type === LightType.Omnidirectional) {\n      stream.writeFlag('Omnidirectional');\n    } else if (this.type === LightType.Directional) {\n      stream.writeFlag('Directional');\n    } else if (this.type === LightType.Ambient) {\n      stream.writeFlag('Ambient');\n    }\n\n    if (!this.writeAnimation(stream, 'KLAS')) {\n      stream.writeNumberAttrib('static AttenuationStart', this.attenuation[0]);\n    }\n\n    if (!this.writeAnimation(stream, 'KLAE')) {\n      stream.writeNumberAttrib('static AttenuationEnd', this.attenuation[1]);\n    }\n\n    if (!this.writeAnimation(stream, 'KLAI')) {\n      stream.writeNumberAttrib('static Intensity', this.intensity);\n    }\n\n    if (!this.writeAnimation(stream, 'KLAC')) {\n      stream.writeColor('static Color', this.color);\n    }\n\n    if (!this.writeAnimation(stream, 'KLBI')) {\n      stream.writeNumberAttrib('static AmbIntensity', this.ambientIntensity);\n    }\n\n    if (!this.writeAnimation(stream, 'KLBC')) {\n      stream.writeColor('static AmbColor', this.ambientColor);\n    }\n\n    this.writeAnimation(stream, 'KLAV');\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 48 + super.getByteLength();\n  }\n}\n\n"
  },
  {
    "path": "src/parsers/mdlx/material.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport Layer from './layer';\n\nexport const enum Flags {\n  None = 0x0,\n  ConstantColor = 0x1,\n  TwoSided = 0x2,\n  SortPrimsNearZ = 0x8,\n  SortPrimsFarZ = 0x10,\n  FullResolution = 0x20,\n}\n\n/**\n * A material.\n */\nexport default class Material {\n  priorityPlane = 0;\n  flags = Flags.None;\n  /** \n   * @since 900\n   */\n  shader = '';\n  layers: Layer[] = [];\n\n  readMdx(stream: BinaryStream, version: number): void {\n    stream.readUint32(); // Don't care about the size.\n\n    this.priorityPlane = stream.readInt32();\n    this.flags = stream.readUint32();\n\n    if (version > 800) {\n      this.shader = stream.read(80);\n    }\n\n    stream.skip(4); // LAYS\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const layer = new Layer();\n\n      layer.readMdx(stream, version);\n\n      this.layers.push(layer);\n    }\n  }\n\n  writeMdx(stream: BinaryStream, version: number): void {\n    stream.writeUint32(this.getByteLength(version));\n    stream.writeInt32(this.priorityPlane);\n    stream.writeUint32(this.flags);\n\n    if (version > 800) {\n      stream.skip(80 - stream.write(this.shader));\n    }\n\n    stream.writeBinary('LAYS');\n    stream.writeUint32(this.layers.length);\n\n    for (const layer of this.layers) {\n      layer.writeMdx(stream, version);\n    }\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of stream.readBlock()) {\n      if (token === 'ConstantColor') {\n        this.flags |= Flags.ConstantColor;\n      } else if (token === 'TwoSided') {\n        this.flags |= Flags.TwoSided;\n      } else if (token === 'SortPrimsNearZ') {\n        this.flags |= Flags.SortPrimsNearZ;\n      } else if (token === 'SortPrimsFarZ') {\n        this.flags |= Flags.SortPrimsFarZ;\n      } else if (token === 'FullResolution') {\n        this.flags |= Flags.FullResolution;\n      } else if (token === 'PriorityPlane') {\n        this.priorityPlane = stream.readInt();\n      } else if (token === 'Shader') {\n        this.shader = stream.read();\n      } else if (token === 'Layer') {\n        const layer = new Layer();\n\n        layer.readMdl(stream);\n\n        this.layers.push(layer);\n      } else {\n        throw new Error(`Unknown token in Material: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream, version: number): void {\n    stream.startBlock('Material');\n\n    if (this.flags & Flags.ConstantColor) {\n      stream.writeFlag('ConstantColor');\n    }\n\n    if (version > 800) {\n      if (this.flags & Flags.TwoSided) {\n        stream.writeFlag('TwoSided');\n      }\n    }\n\n    if (this.flags & Flags.SortPrimsNearZ) {\n      stream.writeFlag('SortPrimsNearZ');\n    }\n\n    if (this.flags & Flags.SortPrimsFarZ) {\n      stream.writeFlag('SortPrimsFarZ');\n    }\n\n    if (this.flags & Flags.FullResolution) {\n      stream.writeFlag('FullResolution');\n    }\n\n    if (this.priorityPlane !== 0) {\n      stream.writeNumberAttrib('PriorityPlane', this.priorityPlane);\n    }\n\n    if (version > 800) {\n      stream.writeStringAttrib('Shader', this.shader);\n    }\n\n    for (const layer of this.layers) {\n      layer.writeMdl(stream, version);\n    }\n\n    stream.endBlock();\n  }\n\n  getByteLength(version: number): number {\n    let size = 20;\n\n    if (version > 800) {\n      size += 80;\n    }\n\n    for (const layer of this.layers) {\n      size += layer.getByteLength(version);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/model.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport { decodeUtf8, encodeUtf8 } from '../../common/utf8';\nimport TokenStream from './tokenstream';\nimport Extent from './extent';\nimport Sequence from './sequence';\nimport Material from './material';\nimport Texture from './texture';\nimport TextureAnimation from './textureanimation';\nimport Geoset from './geoset';\nimport GeosetAnimation from './geosetanimation';\nimport GenericObject from './genericobject';\nimport Bone from './bone';\nimport Light from './light';\nimport Helper from './helper';\nimport Attachment from './attachment';\nimport ParticleEmitter from './particleemitter';\nimport ParticleEmitter2 from './particleemitter2';\nimport ParticleEmitterPopcorn from './particleemitterpopcorn';\nimport RibbonEmitter from './ribbonemitter';\nimport Camera from './camera';\nimport EventObject from './eventobject';\nimport CollisionShape from './collisionshape';\nimport FaceEffect from './faceeffect';\nimport UnknownChunk from './unknownchunk';\nimport { isMdl, isMdx } from './isformat';\n\n// Used below to get proper typings for the generic methods.\ntype MdxStaticObject = Sequence | Texture | FaceEffect;\ntype MdxDynamicObject = Material | TextureAnimation | Geoset | GeosetAnimation | Bone | Light | Helper | Attachment | ParticleEmitter | ParticleEmitter2 | RibbonEmitter | Camera | EventObject | CollisionShape | ParticleEmitterPopcorn;\ntype MdlNumberedObject = Sequence | Texture | Material | TextureAnimation;\ntype MdlObject = Geoset | GeosetAnimation | Bone | Light | Helper | Attachment | ParticleEmitter | ParticleEmitter2 | RibbonEmitter | Camera | EventObject | CollisionShape | FaceEffect;\n\n/**\n * A Warcraft 3 model.\n * Supports loading from and saving to both the binary MDX and text MDL file formats.\n */\nexport default class Model {\n  /**\n   * 800 for Warcraft 3: RoC and TFT.\n   * >800 for Warcraft 3: Reforged.\n   */\n  version = 800;\n  name = '';\n  /**\n   * To the best of my knowledge, this should always be left empty.\n   */\n  animationFile = '';\n  extent = new Extent();\n  /**\n   * This is only used by the now-defunct previewer that came with Art Tools.\n   */\n  blendTime = 0;\n  sequences: Sequence[] = [];\n  globalSequences: number[] = [];\n  materials: Material[] = [];\n  textures: Texture[] = [];\n  textureAnimations: TextureAnimation[] = [];\n  geosets: Geoset[] = [];\n  geosetAnimations: GeosetAnimation[] = [];\n  bones: Bone[] = [];\n  lights: Light[] = [];\n  helpers: Helper[] = [];\n  attachments: Attachment[] = [];\n  pivotPoints: Float32Array[] = [];\n  particleEmitters: ParticleEmitter[] = [];\n  particleEmitters2: ParticleEmitter2[] = [];\n  /**\n   * @since 900\n   */\n  particleEmittersPopcorn: ParticleEmitterPopcorn[] = [];\n  ribbonEmitters: RibbonEmitter[] = [];\n  cameras: Camera[] = [];\n  eventObjects: EventObject[] = [];\n  collisionShapes: CollisionShape[] = [];\n  /**\n   * @since 900\n   */\n  faceEffects: FaceEffect[] = [];\n  /**\n   * @since 900\n   */\n  bindPose: Float32Array[] = [];\n  /**\n   * The MDX format is chunk based, and Warcraft 3 does not mind there being unknown chunks in there.\n   * Some 3rd party tools use this to attach metadata to models.\n   * When an unknown chunk is encountered, it will be added here.\n   * These chunks will be saved when saving as MDX.\n   */\n  unknownChunks: UnknownChunk[] = [];\n\n  /**\n   * Load the model from MDX or MDL.\n   * The format is detected automatically.\n   */\n  load(buffer: ArrayBuffer | Uint8Array | string): void {\n    if (isMdx(buffer)) {\n      if (typeof buffer === 'string') {\n        buffer = encodeUtf8(buffer);\n      }\n\n      this.loadMdx(buffer);\n    } else if (isMdl(buffer)) {\n      if (typeof buffer !== 'string') {\n        buffer = decodeUtf8(buffer);\n      }\n\n      this.loadMdl(buffer);\n    } else {\n      throw new Error('Not a valid MDX/MDL buffer');\n    }\n  }\n\n  /**\n   * Load the model from MDX.\n   */\n  loadMdx(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n    let tag;\n    let size;\n\n    stream.skip(4); // MDLX\n\n    while (stream.remaining > 0) {\n      tag = stream.readBinary(4);\n      size = stream.readUint32();\n\n      if (tag === 'VERS') {\n        this.loadVersionChunk(stream);\n      } else if (tag === 'MODL') {\n        this.loadModelChunk(stream);\n      } else if (tag === 'SEQS') {\n        this.loadStaticObjects(this.sequences, Sequence, stream, size / 132);\n      } else if (tag === 'GLBS') {\n        this.loadGlobalSequenceChunk(stream, size);\n      } else if (tag === 'MTLS') {\n        this.loadDynamicObjects(this.materials, Material, stream, size);\n      } else if (tag === 'TEXS') {\n        this.loadStaticObjects(this.textures, Texture, stream, size / 268);\n      } else if (tag === 'TXAN') {\n        this.loadDynamicObjects(this.textureAnimations, TextureAnimation, stream, size);\n      } else if (tag === 'GEOS') {\n        this.loadDynamicObjects(this.geosets, Geoset, stream, size);\n      } else if (tag === 'GEOA') {\n        this.loadDynamicObjects(this.geosetAnimations, GeosetAnimation, stream, size);\n      } else if (tag === 'BONE') {\n        this.loadDynamicObjects(this.bones, Bone, stream, size);\n      } else if (tag === 'LITE') {\n        this.loadDynamicObjects(this.lights, Light, stream, size);\n      } else if (tag === 'HELP') {\n        this.loadDynamicObjects(this.helpers, Helper, stream, size);\n      } else if (tag === 'ATCH') {\n        this.loadDynamicObjects(this.attachments, Attachment, stream, size);\n      } else if (tag === 'PIVT') {\n        this.loadPivotPointChunk(stream, size);\n      } else if (tag === 'PREM') {\n        this.loadDynamicObjects(this.particleEmitters, ParticleEmitter, stream, size);\n      } else if (tag === 'PRE2') {\n        this.loadDynamicObjects(this.particleEmitters2, ParticleEmitter2, stream, size);\n      } else if (tag === 'CORN') {\n        this.loadDynamicObjects(this.particleEmittersPopcorn, ParticleEmitterPopcorn, stream, size);\n      } else if (tag === 'RIBB') {\n        this.loadDynamicObjects(this.ribbonEmitters, RibbonEmitter, stream, size);\n      } else if (tag === 'CAMS') {\n        this.loadDynamicObjects(this.cameras, Camera, stream, size);\n      } else if (tag === 'EVTS') {\n        this.loadDynamicObjects(this.eventObjects, EventObject, stream, size);\n      } else if (tag === 'CLID') {\n        this.loadDynamicObjects(this.collisionShapes, CollisionShape, stream, size);\n      } else if (tag === 'FAFX') {\n        this.loadStaticObjects(this.faceEffects, FaceEffect, stream, size / 340);\n      } else if (tag === 'BPOS') {\n        this.loadBindPoseChunk(stream, size);\n      } else {\n        this.unknownChunks.push(new UnknownChunk(stream, size, tag));\n      }\n    }\n  }\n\n  loadVersionChunk(stream: BinaryStream): void {\n    this.version = stream.readUint32();\n  }\n\n  loadModelChunk(stream: BinaryStream): void {\n    this.name = stream.read(80);\n    this.animationFile = stream.read(260);\n    this.extent.readMdx(stream);\n    this.blendTime = stream.readUint32();\n  }\n\n  loadStaticObjects<T extends MdxStaticObject>(out: T[], constructor: new () => T, stream: BinaryStream, count: number): void {\n    for (let i = 0; i < count; i++) {\n      const object = new constructor();\n\n      object.readMdx(stream);\n\n      out.push(object);\n    }\n  }\n\n  loadGlobalSequenceChunk(stream: BinaryStream, size: number): void {\n    for (let i = 0, l = size / 4; i < l; i++) {\n      this.globalSequences.push(stream.readUint32());\n    }\n  }\n\n  loadDynamicObjects<T extends MdxDynamicObject>(out: T[], constructor: new () => T, stream: BinaryStream, size: number): void {\n    const end = stream.index + size;\n\n    while (stream.index < end) {\n      const object = new constructor();\n\n      object.readMdx(stream, this.version);\n\n      out.push(object);\n    }\n  }\n\n  loadPivotPointChunk(stream: BinaryStream, size: number): void {\n    for (let i = 0, l = size / 12; i < l; i++) {\n      this.pivotPoints.push(stream.readFloat32Array(3));\n    }\n  }\n\n  loadBindPoseChunk(stream: BinaryStream, _size: number): void {\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      this.bindPose[i] = stream.readFloat32Array(12);\n    }\n  }\n\n  /**\n   * Save the model as MDX.\n   */\n  saveMdx(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeBinary('MDLX');\n    this.saveVersionChunk(stream);\n    this.saveModelChunk(stream);\n    this.saveStaticObjectChunk(stream, 'SEQS', this.sequences, 132);\n    this.saveGlobalSequenceChunk(stream);\n    this.saveDynamicObjectChunk(stream, 'MTLS', this.materials);\n    this.saveStaticObjectChunk(stream, 'TEXS', this.textures, 268);\n    this.saveDynamicObjectChunk(stream, 'TXAN', this.textureAnimations);\n    this.saveDynamicObjectChunk(stream, 'GEOS', this.geosets);\n    this.saveDynamicObjectChunk(stream, 'GEOA', this.geosetAnimations);\n    this.saveDynamicObjectChunk(stream, 'BONE', this.bones);\n    this.saveDynamicObjectChunk(stream, 'LITE', this.lights);\n    this.saveDynamicObjectChunk(stream, 'HELP', this.helpers);\n    this.saveDynamicObjectChunk(stream, 'ATCH', this.attachments);\n    this.savePivotPointChunk(stream);\n    this.saveDynamicObjectChunk(stream, 'PREM', this.particleEmitters);\n    this.saveDynamicObjectChunk(stream, 'PRE2', this.particleEmitters2);\n\n    if (this.version > 800) {\n      this.saveDynamicObjectChunk(stream, 'CORN', this.particleEmittersPopcorn);\n    }\n\n    this.saveDynamicObjectChunk(stream, 'RIBB', this.ribbonEmitters);\n    this.saveDynamicObjectChunk(stream, 'CAMS', this.cameras);\n    this.saveDynamicObjectChunk(stream, 'EVTS', this.eventObjects);\n    this.saveDynamicObjectChunk(stream, 'CLID', this.collisionShapes);\n\n    if (this.version > 800) {\n      this.saveStaticObjectChunk(stream, 'FAFX', this.faceEffects, 340);\n      this.saveBindPoseChunk(stream);\n    }\n\n    for (const chunk of this.unknownChunks) {\n      chunk.writeMdx(stream);\n    }\n\n    return stream.uint8array;\n  }\n\n  saveVersionChunk(stream: BinaryStream): void {\n    stream.writeBinary('VERS');\n    stream.writeUint32(4);\n    stream.writeUint32(this.version);\n  }\n\n  saveModelChunk(stream: BinaryStream): void {\n    stream.writeBinary('MODL');\n    stream.writeUint32(372);\n    stream.skip(80 - stream.write(this.name));\n    stream.skip(260 - stream.write(this.animationFile));\n    this.extent.writeMdx(stream);\n    stream.writeUint32(this.blendTime);\n  }\n\n  saveStaticObjectChunk(stream: BinaryStream, name: string, objects: (Sequence | Texture | FaceEffect)[], size: number): void {\n    if (objects.length) {\n      stream.writeBinary(name);\n      stream.writeUint32(objects.length * size);\n\n      for (const object of objects) {\n        object.writeMdx(stream);\n      }\n    }\n  }\n\n  saveGlobalSequenceChunk(stream: BinaryStream): void {\n    if (this.globalSequences.length) {\n      stream.writeBinary('GLBS');\n      stream.writeUint32(this.globalSequences.length * 4);\n\n      for (const globalSequence of this.globalSequences) {\n        stream.writeUint32(globalSequence);\n      }\n    }\n  }\n\n  saveDynamicObjectChunk(stream: BinaryStream, name: string, objects: (Material | TextureAnimation | Geoset | GeosetAnimation | GenericObject | Camera)[]): void {\n    if (objects.length) {\n      stream.writeBinary(name);\n      stream.writeUint32(this.getObjectsByteLength(objects));\n\n      for (const object of objects) {\n        object.writeMdx(stream, this.version);\n      }\n    }\n  }\n\n  savePivotPointChunk(stream: BinaryStream): void {\n    if (this.pivotPoints.length) {\n      stream.writeBinary('PIVT');\n      stream.writeUint32(this.pivotPoints.length * 12);\n\n      for (const pivotPoint of this.pivotPoints) {\n        stream.writeFloat32Array(pivotPoint);\n      }\n    }\n  }\n\n  saveBindPoseChunk(stream: BinaryStream): void {\n    if (this.bindPose.length) {\n      stream.writeBinary('BPOS');\n      stream.writeUint32(4 + this.bindPose.length * 48);\n      stream.writeUint32(this.bindPose.length);\n\n      for (const matrix of this.bindPose) {\n        stream.writeFloat32Array(matrix);\n      }\n    }\n  }\n\n  /**\n   * Load the model from MDL.\n   */\n  loadMdl(buffer: string): void {\n    let token: string;\n    const stream = new TokenStream(buffer);\n\n    while ((token = <string>stream.readToken())) {\n      if (token === 'Version') {\n        this.loadVersionBlock(stream);\n      } else if (token === 'Model') {\n        this.loadModelBlock(stream);\n      } else if (token === 'Sequences') {\n        this.loadNumberedObjectBlock(this.sequences, Sequence, 'Anim', stream);\n      } else if (token === 'GlobalSequences') {\n        this.loadGlobalSequenceBlock(stream);\n      } else if (token === 'Textures') {\n        this.loadNumberedObjectBlock(this.textures, Texture, 'Bitmap', stream);\n      } else if (token === 'Materials') {\n        this.loadNumberedObjectBlock(this.materials, Material, 'Material', stream);\n      } else if (token === 'TextureAnims') {\n        this.loadNumberedObjectBlock(this.textureAnimations, TextureAnimation, 'TVertexAnim', stream);\n      } else if (token === 'Geoset') {\n        this.loadObject(this.geosets, Geoset, stream);\n      } else if (token === 'GeosetAnim') {\n        this.loadObject(this.geosetAnimations, GeosetAnimation, stream);\n      } else if (token === 'Bone') {\n        this.loadObject(this.bones, Bone, stream);\n      } else if (token === 'Light') {\n        this.loadObject(this.lights, Light, stream);\n      } else if (token === 'Helper') {\n        this.loadObject(this.helpers, Helper, stream);\n      } else if (token === 'Attachment') {\n        this.loadObject(this.attachments, Attachment, stream);\n      } else if (token === 'PivotPoints') {\n        this.loadPivotPointBlock(stream);\n      } else if (token === 'ParticleEmitter') {\n        this.loadObject(this.particleEmitters, ParticleEmitter, stream);\n      } else if (token === 'ParticleEmitter2') {\n        this.loadObject(this.particleEmitters2, ParticleEmitter2, stream);\n      } else if (token === 'ParticleEmitterPopcorn') {\n        this.loadObject(this.particleEmittersPopcorn, ParticleEmitterPopcorn, stream);\n      } else if (token === 'RibbonEmitter') {\n        this.loadObject(this.ribbonEmitters, RibbonEmitter, stream);\n      } else if (token === 'Camera') {\n        this.loadObject(this.cameras, Camera, stream);\n      } else if (token === 'EventObject') {\n        this.loadObject(this.eventObjects, EventObject, stream);\n      } else if (token === 'CollisionShape') {\n        this.loadObject(this.collisionShapes, CollisionShape, stream);\n      } else if (token === 'FaceFX') {\n        this.loadObject(this.faceEffects, FaceEffect, stream);\n      } else if (token === 'BindPose') {\n        this.loadBindPoseBlock(stream);\n      } else {\n        throw new Error(`Unsupported block: ${token}`);\n      }\n    }\n  }\n\n  loadVersionBlock(stream: TokenStream): void {\n    for (const token of stream.readBlock()) {\n      if (token === 'FormatVersion') {\n        this.version = stream.readInt();\n      } else {\n        throw new Error(`Unknown token in Version: \"${token}\"`);\n      }\n    }\n  }\n\n  loadModelBlock(stream: TokenStream): void {\n    this.name = stream.read();\n\n    for (const token of stream.readBlock()) {\n      if (token.startsWith('Num')) {\n        // Don't care about the number of things, the arrays will grow as they wish.\n        // This includes:\n        //      NumGeosets\n        //      NumGeosetAnims\n        //      NumHelpers\n        //      NumLights\n        //      NumBones\n        //      NumSoundEmitters (deprecated)\n        //      NumAttachments\n        //      NumParticleEmitters\n        //      NumParticleEmitters2\n        //      NumParticleEmittersPopcorn (>800)\n        //      NumRibbonEmitters\n        //      NumEvents\n        //      NumFaceFX (>800)\n        stream.read();\n      } else if (token === 'BlendTime') {\n        this.blendTime = stream.readInt();\n      } else if (token === 'MinimumExtent') {\n        stream.readVector(this.extent.min);\n      } else if (token === 'MaximumExtent') {\n        stream.readVector(this.extent.max);\n      } else if (token === 'BoundsRadius') {\n        this.extent.boundsRadius = stream.readFloat();\n      } else if (token === 'AnimationFile') {\n        this.animationFile = stream.read();\n      } else {\n        throw new Error(`Unknown token in Model: \"${token}\"`);\n      }\n    }\n  }\n\n  loadNumberedObjectBlock<T extends MdlNumberedObject>(out: T[], constructor: new () => T, name: string, stream: TokenStream): void {\n    stream.read(); // Don't care about the number, the array will grow.\n\n    for (const token of stream.readBlock()) {\n      if (token === name) {\n        const object = new constructor();\n\n        object.readMdl(stream);\n\n        out.push(object);\n      } else {\n        throw new Error(`Unknown token in ${name}: \"${token}\"`);\n      }\n    }\n  }\n\n  loadGlobalSequenceBlock(stream: TokenStream): void {\n    stream.read(); // Don't care about the number, the array will grow.\n\n    for (const token of stream.readBlock()) {\n      if (token === 'Duration') {\n        this.globalSequences.push(stream.readInt());\n      } else {\n        throw new Error(`Unknown token in GlobalSequences: \"${token}\"`);\n      }\n    }\n  }\n\n  loadObject<T extends MdlObject>(out: T[], constructor: new () => T, stream: TokenStream): void {\n    const object = new constructor();\n\n    object.readMdl(stream);\n\n    out.push(object);\n  }\n\n  loadPivotPointBlock(stream: TokenStream): void {\n    const count = stream.readInt();\n\n    stream.read(); // {\n\n    for (let i = 0; i < count; i++) {\n      this.pivotPoints.push(stream.readVector(new Float32Array(3)));\n    }\n\n    stream.read(); // }\n  }\n\n  loadBindPoseBlock(stream: TokenStream): void {\n    for (const token of stream.readBlock()) {\n      if (token === 'Matrices') {\n        const matrices = stream.readInt();\n\n        stream.read(); // {\n\n        for (let i = 0; i < matrices; i++) {\n          this.bindPose[i] = stream.readVector(new Float32Array(12));\n        }\n\n        stream.read(); // }\n      } else {\n        throw new Error(`Unknown token in BindPose: \"${token}\"`);\n      }\n    }\n  }\n\n  /**\n   * Save the model as MDL.\n   */\n  saveMdl(): string {\n    const stream = new TokenStream();\n\n    this.saveVersionBlock(stream);\n    this.saveModelBlock(stream);\n    this.saveStaticObjectsBlock(stream, 'Sequences', this.sequences);\n    this.saveGlobalSequenceBlock(stream);\n    this.saveStaticObjectsBlock(stream, 'Textures', this.textures);\n    this.saveStaticObjectsBlock(stream, 'Materials', this.materials);\n    this.saveStaticObjectsBlock(stream, 'TextureAnims', this.textureAnimations);\n    this.saveObjects(stream, this.geosets);\n    this.saveObjects(stream, this.geosetAnimations);\n    this.saveObjects(stream, this.bones);\n    this.saveObjects(stream, this.lights);\n    this.saveObjects(stream, this.helpers);\n    this.saveObjects(stream, this.attachments);\n    this.savePivotPointBlock(stream);\n    this.saveObjects(stream, this.particleEmitters);\n    this.saveObjects(stream, this.particleEmitters2);\n\n    if (this.version > 800) {\n      this.saveObjects(stream, this.particleEmittersPopcorn);\n    }\n\n    this.saveObjects(stream, this.ribbonEmitters);\n    this.saveObjects(stream, this.cameras);\n    this.saveObjects(stream, this.eventObjects);\n    this.saveObjects(stream, this.collisionShapes);\n\n    if (this.version > 800) {\n      this.saveObjects(stream, this.faceEffects);\n      this.saveBindPoseBlock(stream);\n    }\n\n    return stream.buffer;\n  }\n\n  saveVersionBlock(stream: TokenStream): void {\n    stream.startBlock('Version');\n    stream.writeNumberAttrib('FormatVersion', this.version);\n    stream.endBlock();\n  }\n\n  saveModelBlock(stream: TokenStream): void {\n    stream.startObjectBlock('Model', this.name);\n    stream.writeNumberAttrib('BlendTime', this.blendTime);\n\n    this.extent.writeMdl(stream);\n\n    if (this.animationFile.length) {\n      stream.writeStringAttrib('AnimationFile', this.animationFile);\n    }\n\n    stream.endBlock();\n  }\n\n  saveStaticObjectsBlock(stream: TokenStream, name: string, objects: (Sequence | Texture | Material | TextureAnimation)[]): void {\n    if (objects.length) {\n      stream.startBlock(name, objects.length);\n\n      for (const object of objects) {\n        object.writeMdl(stream, this.version);\n      }\n\n      stream.endBlock();\n    }\n  }\n\n  saveGlobalSequenceBlock(stream: TokenStream): void {\n    if (this.globalSequences.length) {\n      stream.startBlock('GlobalSequences', this.globalSequences.length);\n\n      for (const globalSequence of this.globalSequences) {\n        stream.writeNumberAttrib('Duration', globalSequence);\n      }\n\n      stream.endBlock();\n    }\n  }\n\n  saveObjects(stream: TokenStream, objects: (Geoset | GeosetAnimation | Bone | Light | Helper | Attachment | ParticleEmitter | ParticleEmitter2 | RibbonEmitter | Camera | EventObject | CollisionShape | FaceEffect)[]): void {\n    for (const object of objects) {\n      object.writeMdl(stream, this.version);\n    }\n  }\n\n  savePivotPointBlock(stream: TokenStream): void {\n    if (this.pivotPoints.length) {\n      stream.startBlock('PivotPoints', this.pivotPoints.length);\n\n      for (const pivotPoint of this.pivotPoints) {\n        stream.writeVector(pivotPoint);\n      }\n\n      stream.endBlock();\n    }\n  }\n\n  saveBindPoseBlock(stream: TokenStream): void {\n    if (this.bindPose.length) {\n      stream.startBlock('BindPose');\n\n      stream.startBlock('Matrices', this.bindPose.length);\n\n      for (const matrix of this.bindPose) {\n        stream.writeVector(matrix);\n      }\n\n      stream.endBlock();\n\n      stream.endBlock();\n    }\n  }\n\n  /**\n   * Calculate the size of the model as MDX.\n   */\n  getByteLength(): number {\n    let size = 396;\n\n    size += this.getStaticObjectsChunkByteLength(this.sequences, 132);\n    size += this.getStaticObjectsChunkByteLength(this.globalSequences, 4);\n    size += this.getDynamicObjectsChunkByteLength(this.materials);\n    size += this.getStaticObjectsChunkByteLength(this.textures, 268);\n    size += this.getDynamicObjectsChunkByteLength(this.textureAnimations);\n    size += this.getDynamicObjectsChunkByteLength(this.geosets);\n    size += this.getDynamicObjectsChunkByteLength(this.geosetAnimations);\n    size += this.getDynamicObjectsChunkByteLength(this.bones);\n    size += this.getDynamicObjectsChunkByteLength(this.lights);\n    size += this.getDynamicObjectsChunkByteLength(this.helpers);\n    size += this.getDynamicObjectsChunkByteLength(this.attachments);\n    size += this.getStaticObjectsChunkByteLength(this.pivotPoints, 12);\n    size += this.getDynamicObjectsChunkByteLength(this.particleEmitters);\n    size += this.getDynamicObjectsChunkByteLength(this.particleEmitters2);\n\n    if (this.version > 800) {\n      size += this.getDynamicObjectsChunkByteLength(this.particleEmittersPopcorn);\n    }\n\n    size += this.getDynamicObjectsChunkByteLength(this.ribbonEmitters);\n    size += this.getDynamicObjectsChunkByteLength(this.cameras);\n    size += this.getDynamicObjectsChunkByteLength(this.eventObjects);\n    size += this.getDynamicObjectsChunkByteLength(this.collisionShapes);\n\n    if (this.version > 800) {\n      size += this.getStaticObjectsChunkByteLength(this.faceEffects, 340);\n      size += this.getBindPoseChunkByteLength();\n    }\n\n    size += this.getObjectsByteLength(this.unknownChunks);\n\n    return size;\n  }\n\n  getObjectsByteLength(objects: (Material | TextureAnimation | Geoset | GeosetAnimation | GenericObject | Camera | UnknownChunk)[]): number {\n    let size = 0;\n\n    for (const object of objects) {\n      size += object.getByteLength(this.version);\n    }\n\n    return size;\n  }\n\n  getDynamicObjectsChunkByteLength(objects: (Material | TextureAnimation | Geoset | GeosetAnimation | GenericObject | Camera | UnknownChunk)[]): number {\n    if (objects.length) {\n      return 8 + this.getObjectsByteLength(objects);\n    }\n\n    return 0;\n  }\n\n  getStaticObjectsChunkByteLength(objects: (Sequence | number | Texture | Float32Array | FaceEffect)[], size: number): number {\n    if (objects.length) {\n      return 8 + objects.length * size;\n    }\n\n    return 0;\n  }\n\n  getBindPoseChunkByteLength(): number {\n    if (this.bindPose.length) {\n      return 12 + this.bindPose.length * 48;\n    }\n\n    return 0;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/particleemitter.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\nexport const enum Flags {\n  EmitterUsesMDL = 0x8000,\n  EmitterUsesTGA = 0x10000,\n}\n\n/**\n * A particle emitter.\n */\nexport default class ParticleEmitter extends GenericObject {\n  emissionRate = 0;\n  gravity = 0;\n  longitude = 0;\n  latitude = 0;\n  path = '';\n  lifeSpan = 0;\n  speed = 0;\n\n  constructor() {\n    super(0x1000);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    super.readMdx(stream);\n\n    this.emissionRate = stream.readFloat32();\n    this.gravity = stream.readFloat32();\n    this.longitude = stream.readFloat32();\n    this.latitude = stream.readFloat32();\n    this.path = stream.read(260);\n    this.lifeSpan = stream.readFloat32();\n    this.speed = stream.readFloat32();\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n\n    super.writeMdx(stream);\n\n    stream.writeFloat32(this.emissionRate);\n    stream.writeFloat32(this.gravity);\n    stream.writeFloat32(this.longitude);\n    stream.writeFloat32(this.latitude);\n    stream.skip(260 - stream.write(this.path));\n    stream.writeFloat32(this.lifeSpan);\n    stream.writeFloat32(this.speed);\n\n    this.writeNonGenericAnimationChunks(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (let token of super.readGenericBlock(stream)) {\n      if (token === 'EmitterUsesMDL') {\n        this.flags |= Flags.EmitterUsesMDL;\n      } else if (token === 'EmitterUsesTGA') {\n        this.flags |= Flags.EmitterUsesTGA;\n      } else if (token === 'static EmissionRate') {\n        this.emissionRate = stream.readFloat();\n      } else if (token === 'EmissionRate') {\n        this.readAnimation(stream, 'KPEE');\n      } else if (token === 'static Gravity') {\n        this.gravity = stream.readFloat();\n      } else if (token === 'Gravity') {\n        this.readAnimation(stream, 'KPEG');\n      } else if (token === 'static Longitude') {\n        this.longitude = stream.readFloat();\n      } else if (token === 'Longitude') {\n        this.readAnimation(stream, 'KPLN');\n      } else if (token === 'static Latitude') {\n        this.latitude = stream.readFloat();\n      } else if (token === 'Latitude') {\n        this.readAnimation(stream, 'KPLT');\n      } else if (token === 'Visibility') {\n        this.readAnimation(stream, 'KPEV');\n      } else if (token === 'Particle') {\n        for (token of this.readAnimatedBlock(stream)) {\n          if (token === 'static LifeSpan') {\n            this.lifeSpan = stream.readFloat();\n          } else if (token === 'LifeSpan') {\n            this.readAnimation(stream, 'KPEL');\n          } else if (token === 'static InitVelocity') {\n            this.speed = stream.readFloat();\n          } else if (token === 'InitVelocity') {\n            this.readAnimation(stream, 'KPES');\n          } else if (token === 'Path') {\n            this.path = stream.read();\n          }\n        }\n      } else {\n        throw new Error(`Unknown token in ParticleEmitter: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('ParticleEmitter', this.name);\n    this.writeGenericHeader(stream);\n\n    if (this.flags & Flags.EmitterUsesMDL) {\n      stream.writeFlag('EmitterUsesMDL');\n    }\n\n    if (this.flags & Flags.EmitterUsesTGA) {\n      stream.writeFlag('EmitterUsesTGA');\n    }\n\n    if (!this.writeAnimation(stream, 'KPEE')) {\n      stream.writeNumberAttrib('static EmissionRate', this.emissionRate);\n    }\n\n    if (!this.writeAnimation(stream, 'KPEG')) {\n      stream.writeNumberAttrib('static Gravity', this.gravity);\n    }\n\n    if (!this.writeAnimation(stream, 'KPLN')) {\n      stream.writeNumberAttrib('static Longitude', this.longitude);\n    }\n\n    if (!this.writeAnimation(stream, 'KPLT')) {\n      stream.writeNumberAttrib('static Latitude', this.latitude);\n    }\n\n    this.writeAnimation(stream, 'KPEV');\n\n    stream.startBlock('Particle');\n\n    if (!this.writeAnimation(stream, 'KPEL')) {\n      stream.writeNumberAttrib('static LifeSpan', this.lifeSpan);\n    }\n\n    if (!this.writeAnimation(stream, 'KPES')) {\n      stream.writeNumberAttrib('static InitVelocity', this.speed);\n    }\n\n    if ((this.flags & Flags.EmitterUsesMDL) || (this.flags & Flags.EmitterUsesTGA)) {\n      stream.writeStringAttrib('Path', this.path);\n    }\n\n    stream.endBlock();\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 288 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/particleemitter2.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\nexport const enum Flags {\n  Unshaded = 0x8000,\n  SortPrimsFarZ = 0x10000,\n  LineEmitter = 0x20000,\n  Unfogged = 0x40000,\n  ModelSpace = 0x80000,\n  XYQuad = 0x100000,\n}\n\nexport const enum FilterMode {\n  Blend = 0,\n  Additive = 1,\n  Modulate = 2,\n  Modulate2x = 3,\n  AlphaKey = 4,\n}\n\nexport const enum HeadOrTail {\n  Head = 0,\n  Tail = 1,\n  Both = 2,\n}\n\n/**\n * A particle emitter type 2.\n */\nexport default class ParticleEmitter2 extends GenericObject {\n  speed = 0;\n  variation = 0;\n  latitude = 0;\n  gravity = 0;\n  lifeSpan = 0;\n  emissionRate = 0;\n  width = 0;\n  length = 0;\n  filterMode = FilterMode.Blend;\n  rows = 0;\n  columns = 0;\n  headOrTail = HeadOrTail.Head;\n  tailLength = 0;\n  timeMiddle = 0;\n  segmentColors: Float32Array[] = [new Float32Array(3), new Float32Array(3), new Float32Array(3)];\n  segmentAlphas = new Uint8Array(3);\n  segmentScaling = new Float32Array(3);\n  headIntervals: Uint32Array[] = [new Uint32Array(3), new Uint32Array(3)];\n  tailIntervals: Uint32Array[] = [new Uint32Array(3), new Uint32Array(3)];\n  textureId = -1;\n  squirt = 0;\n  priorityPlane = 0;\n  replaceableId = 0;\n\n  override readMdx(stream: BinaryStream): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    super.readMdx(stream);\n\n    this.speed = stream.readFloat32();\n    this.variation = stream.readFloat32();\n    this.latitude = stream.readFloat32();\n    this.gravity = stream.readFloat32();\n    this.lifeSpan = stream.readFloat32();\n    this.emissionRate = stream.readFloat32();\n    this.width = stream.readFloat32();\n    this.length = stream.readFloat32();\n    this.filterMode = stream.readUint32();\n    this.rows = stream.readUint32();\n    this.columns = stream.readUint32();\n    this.headOrTail = stream.readUint32();\n    this.tailLength = stream.readFloat32();\n    this.timeMiddle = stream.readFloat32();\n    stream.readFloat32Array(this.segmentColors[0]);\n    stream.readFloat32Array(this.segmentColors[1]);\n    stream.readFloat32Array(this.segmentColors[2]);\n    stream.readUint8Array(this.segmentAlphas);\n    stream.readFloat32Array(this.segmentScaling);\n    stream.readUint32Array(this.headIntervals[0]);\n    stream.readUint32Array(this.headIntervals[1]);\n    stream.readUint32Array(this.tailIntervals[0]);\n    stream.readUint32Array(this.tailIntervals[1]);\n    this.textureId = stream.readInt32();\n    this.squirt = stream.readUint32();\n    this.priorityPlane = stream.readInt32();\n    this.replaceableId = stream.readUint32();\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n\n    super.writeMdx(stream);\n\n    stream.writeFloat32(this.speed);\n    stream.writeFloat32(this.variation);\n    stream.writeFloat32(this.latitude);\n    stream.writeFloat32(this.gravity);\n    stream.writeFloat32(this.lifeSpan);\n    stream.writeFloat32(this.emissionRate);\n    stream.writeFloat32(this.width);\n    stream.writeFloat32(this.length);\n    stream.writeUint32(this.filterMode);\n    stream.writeUint32(this.rows);\n    stream.writeUint32(this.columns);\n    stream.writeUint32(this.headOrTail);\n    stream.writeFloat32(this.tailLength);\n    stream.writeFloat32(this.timeMiddle);\n    stream.writeFloat32Array(this.segmentColors[0]);\n    stream.writeFloat32Array(this.segmentColors[1]);\n    stream.writeFloat32Array(this.segmentColors[2]);\n    stream.writeUint8Array(this.segmentAlphas);\n    stream.writeFloat32Array(this.segmentScaling);\n    stream.writeUint32Array(this.headIntervals[0]);\n    stream.writeUint32Array(this.headIntervals[1]);\n    stream.writeUint32Array(this.tailIntervals[0]);\n    stream.writeUint32Array(this.tailIntervals[1]);\n    stream.writeInt32(this.textureId);\n    stream.writeUint32(this.squirt);\n    stream.writeInt32(this.priorityPlane);\n    stream.writeUint32(this.replaceableId);\n\n    this.writeNonGenericAnimationChunks(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'SortPrimsFarZ') {\n        this.flags |= Flags.SortPrimsFarZ;\n      } else if (token === 'Unshaded') {\n        this.flags |= Flags.Unshaded;\n      } else if (token === 'LineEmitter') {\n        this.flags |= Flags.LineEmitter;\n      } else if (token === 'Unfogged') {\n        this.flags |= Flags.Unfogged;\n      } else if (token === 'ModelSpace') {\n        this.flags |= Flags.ModelSpace;\n      } else if (token === 'XYQuad') {\n        this.flags |= Flags.XYQuad;\n      } else if (token === 'static Speed') {\n        this.speed = stream.readFloat();\n      } else if (token === 'Speed') {\n        this.readAnimation(stream, 'KP2S');\n      } else if (token === 'static Variation') {\n        this.variation = stream.readFloat();\n      } else if (token === 'Variation') {\n        this.readAnimation(stream, 'KP2R');\n      } else if (token === 'static Latitude') {\n        this.latitude = stream.readFloat();\n      } else if (token === 'Latitude') {\n        this.readAnimation(stream, 'KP2L');\n      } else if (token === 'static Gravity') {\n        this.gravity = stream.readFloat();\n      } else if (token === 'Gravity') {\n        this.readAnimation(stream, 'KP2G');\n      } else if (token === 'Visibility') {\n        this.readAnimation(stream, 'KP2V');\n      } else if (token === 'Squirt') {\n        this.squirt = 1;\n      } else if (token === 'LifeSpan') {\n        this.lifeSpan = stream.readFloat();\n      } else if (token === 'static EmissionRate') {\n        this.emissionRate = stream.readFloat();\n      } else if (token === 'EmissionRate') {\n        this.readAnimation(stream, 'KP2E');\n      } else if (token === 'static Width') {\n        this.width = stream.readFloat();\n      } else if (token === 'Width') {\n        this.readAnimation(stream, 'KP2N');\n      } else if (token === 'static Length') {\n        this.length = stream.readFloat();\n      } else if (token === 'Length') {\n        this.readAnimation(stream, 'KP2W');\n      } else if (token === 'Blend') {\n        this.filterMode = FilterMode.Blend;\n      } else if (token === 'Additive') {\n        this.filterMode = FilterMode.Additive;\n      } else if (token === 'Modulate') {\n        this.filterMode = FilterMode.Modulate;\n      } else if (token === 'Modulate2x') {\n        this.filterMode = FilterMode.Modulate2x;\n      } else if (token === 'AlphaKey') {\n        this.filterMode = FilterMode.AlphaKey;\n      } else if (token === 'Rows') {\n        this.rows = stream.readInt();\n      } else if (token === 'Columns') {\n        this.columns = stream.readInt();\n      } else if (token === 'Head') {\n        this.headOrTail = HeadOrTail.Head;\n      } else if (token === 'Tail') {\n        this.headOrTail = HeadOrTail.Tail;\n      } else if (token === 'Both') {\n        this.headOrTail = HeadOrTail.Both;\n      } else if (token === 'TailLength') {\n        this.tailLength = stream.readFloat();\n      } else if (token === 'Time') {\n        this.timeMiddle = stream.readFloat();\n      } else if (token === 'SegmentColor') {\n        stream.read(); // {\n\n        for (let i = 0; i < 3; i++) {\n          stream.read(); // Color\n          stream.readColor(this.segmentColors[i]);\n        }\n\n        stream.read(); // }\n      } else if (token === 'Alpha') {\n        stream.readVector(this.segmentAlphas);\n      } else if (token === 'ParticleScaling') {\n        stream.readVector(this.segmentScaling);\n      } else if (token === 'LifeSpanUVAnim') {\n        stream.readVector(this.headIntervals[0]);\n      } else if (token === 'DecayUVAnim') {\n        stream.readVector(this.headIntervals[1]);\n      } else if (token === 'TailUVAnim') {\n        stream.readVector(this.tailIntervals[0]);\n      } else if (token === 'TailDecayUVAnim') {\n        stream.readVector(this.tailIntervals[1]);\n      } else if (token === 'TextureID') {\n        this.textureId = stream.readInt();\n      } else if (token === 'ReplaceableId') {\n        this.replaceableId = stream.readInt();\n      } else if (token === 'PriorityPlane') {\n        this.priorityPlane = stream.readInt();\n      } else {\n        throw new Error(`Unknown token in ParticleEmitter2: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('ParticleEmitter2', this.name);\n    this.writeGenericHeader(stream);\n\n    if (this.flags & Flags.SortPrimsFarZ) {\n      stream.writeFlag('SortPrimsFarZ');\n    }\n\n    if (this.flags & Flags.Unshaded) {\n      stream.writeFlag('Unshaded');\n    }\n\n    if (this.flags & Flags.LineEmitter) {\n      stream.writeFlag('LineEmitter');\n    }\n\n    if (this.flags & Flags.Unfogged) {\n      stream.writeFlag('Unfogged');\n    }\n\n    if (this.flags & Flags.ModelSpace) {\n      stream.writeFlag('ModelSpace');\n    }\n\n    if (this.flags & Flags.XYQuad) {\n      stream.writeFlag('XYQuad');\n    }\n\n    if (!this.writeAnimation(stream, 'KP2S')) {\n      stream.writeNumberAttrib('static Speed', this.speed);\n    }\n\n    if (!this.writeAnimation(stream, 'KP2R')) {\n      stream.writeNumberAttrib('static Variation', this.variation);\n    }\n\n    if (!this.writeAnimation(stream, 'KP2L')) {\n      stream.writeNumberAttrib('static Latitude', this.latitude);\n    }\n\n    if (!this.writeAnimation(stream, 'KP2G')) {\n      stream.writeNumberAttrib('static Gravity', this.gravity);\n    }\n\n    this.writeAnimation(stream, 'KP2V');\n\n    if (this.squirt) {\n      stream.writeFlag('Squirt');\n    }\n\n    stream.writeNumberAttrib('LifeSpan', this.lifeSpan);\n\n    if (!this.writeAnimation(stream, 'KP2E')) {\n      stream.writeNumberAttrib('static EmissionRate', this.emissionRate);\n    }\n\n    if (!this.writeAnimation(stream, 'KP2N')) {\n      stream.writeNumberAttrib('static Width', this.width);\n    }\n\n    if (!this.writeAnimation(stream, 'KP2W')) {\n      stream.writeNumberAttrib('static Length', this.length);\n    }\n\n    if (this.filterMode === FilterMode.Blend) {\n      stream.writeFlag('Blend');\n    } else if (this.filterMode === FilterMode.Additive) {\n      stream.writeFlag('Additive');\n    } else if (this.filterMode === FilterMode.Modulate) {\n      stream.writeFlag('Modulate');\n    } else if (this.filterMode === FilterMode.Modulate2x) {\n      stream.writeFlag('Modulate2x');\n    } else if (this.filterMode === FilterMode.AlphaKey) {\n      stream.writeFlag('AlphaKey');\n    }\n\n    stream.writeNumberAttrib('Rows', this.rows);\n    stream.writeNumberAttrib('Columns', this.columns);\n\n    if (this.headOrTail === HeadOrTail.Head) {\n      stream.writeFlag('Head');\n    } else if (this.headOrTail === HeadOrTail.Tail) {\n      stream.writeFlag('Tail');\n    } else if (this.headOrTail === HeadOrTail.Both) {\n      stream.writeFlag('Both');\n    }\n\n    stream.writeNumberAttrib('TailLength', this.tailLength);\n    stream.writeNumberAttrib('Time', this.timeMiddle);\n\n    stream.startBlock('SegmentColor');\n    stream.writeColor('Color', this.segmentColors[0]);\n    stream.writeColor('Color', this.segmentColors[1]);\n    stream.writeColor('Color', this.segmentColors[2]);\n    stream.endBlockComma();\n\n    stream.writeVectorAttrib('Alpha', this.segmentAlphas);\n    stream.writeVectorAttrib('ParticleScaling', this.segmentScaling);\n    stream.writeVectorAttrib('LifeSpanUVAnim', this.headIntervals[0]);\n    stream.writeVectorAttrib('DecayUVAnim', this.headIntervals[1]);\n    stream.writeVectorAttrib('TailUVAnim', this.tailIntervals[0]);\n    stream.writeVectorAttrib('TailDecayUVAnim', this.tailIntervals[1]);\n    stream.writeNumberAttrib('TextureID', this.textureId);\n\n    if (this.replaceableId !== 0) {\n      stream.writeNumberAttrib('ReplaceableId', this.replaceableId);\n    }\n\n    if (this.priorityPlane !== 0) {\n      stream.writeNumberAttrib('PriorityPlane', this.priorityPlane);\n    }\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 175 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/particleemitterpopcorn.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\nexport const enum Flags {\n  Unshaded = 0x8000,\n  SortPrimsFarZ = 0x10000,\n  Unfogged = 0x40000,\n}\n\n/**\n * A popcorn particle emitter.\n * References a pkfx file, which is used by the PopcornFX runtime.\n *\n * @since 900\n */\nexport default class ParticleEmitterPopcorn extends GenericObject {\n  lifeSpan = 0;\n  emissionRate = 0;\n  speed = 0;\n  color = new Float32Array(3);\n  alpha = 1;\n  replaceableId = 0;\n  path = '';\n  animationVisiblityGuide = '';\n\n  override readMdx(stream: BinaryStream): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    super.readMdx(stream);\n\n    this.lifeSpan = stream.readFloat32();\n    this.emissionRate = stream.readFloat32();\n    this.speed = stream.readFloat32();\n    stream.readFloat32Array(this.color);\n    this.alpha = stream.readFloat32();\n    this.replaceableId = stream.readUint32();\n    this.path = stream.read(260);\n    this.animationVisiblityGuide = stream.read(260);\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n\n    super.writeMdx(stream);\n\n    stream.writeFloat32(this.lifeSpan);\n    stream.writeFloat32(this.emissionRate);\n    stream.writeFloat32(this.speed);\n    stream.writeFloat32Array(this.color);\n    stream.writeFloat32(this.alpha);\n    stream.writeUint32(this.replaceableId);\n    stream.skip(260 - stream.write(this.path));\n    stream.skip(260 - stream.write(this.animationVisiblityGuide));\n\n    this.writeNonGenericAnimationChunks(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'SortPrimsFarZ') {\n        this.flags |= Flags.SortPrimsFarZ;\n      } else if (token === 'Unshaded') {\n        this.flags |= Flags.Unshaded;\n      } else if (token === 'Unfogged') {\n        this.flags |= Flags.Unfogged;\n      } else if (token === 'static LifeSpan') {\n        this.lifeSpan = stream.readFloat();\n      } else if (token === 'LifeSpan') {\n        this.readAnimation(stream, 'KPPL');\n      } else if (token === 'static EmissionRate') {\n        this.emissionRate = stream.readFloat();\n      } else if (token === 'EmissionRate') {\n        this.readAnimation(stream, 'KPPE');\n      } else if (token === 'static Speed') {\n        this.speed = stream.readFloat();\n      } else if (token === 'Speed') {\n        this.readAnimation(stream, 'KPPS');\n      } else if (token === 'static Color') {\n        stream.readVector(this.color);\n      } else if (token === 'Color') {\n        this.readAnimation(stream, 'KPPC');\n      } else if (token === 'static Alpha') {\n        this.alpha = stream.readFloat();\n      } else if (token === 'Alpha') {\n        this.readAnimation(stream, 'KPPA');\n      } else if (token === 'Visibility') {\n        this.readAnimation(stream, 'KPPV');\n      } else if (token === 'ReplaceableId') {\n        this.replaceableId = stream.readInt();\n      } else if (token === 'Path') {\n        this.path = stream.read();\n      } else if (token === 'AnimVisibilityGuide') {\n        this.animationVisiblityGuide = stream.read();\n      } else {\n        throw new Error(`Unknown token in ParticleEmitterPopcorn: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('ParticleEmitterPopcorn', this.name);\n    this.writeGenericHeader(stream);\n\n    if (this.flags & Flags.SortPrimsFarZ) {\n      stream.writeFlag('SortPrimsFarZ');\n    }\n\n    if (this.flags & Flags.Unshaded) {\n      stream.writeFlag('Unshaded');\n    }\n\n    if (this.flags & Flags.Unfogged) {\n      stream.writeFlag('Unfogged');\n    }\n\n    if (!this.writeAnimation(stream, 'KPPL')) {\n      stream.writeNumberAttrib('static LifeSpan', this.lifeSpan);\n    }\n\n    if (!this.writeAnimation(stream, 'KPPE')) {\n      stream.writeNumberAttrib('static EmissionRate', this.emissionRate);\n    }\n\n    if (!this.writeAnimation(stream, 'KPPS')) {\n      stream.writeNumberAttrib('static Speed', this.speed);\n    }\n\n    if (!this.writeAnimation(stream, 'KPPC')) {\n      stream.writeVectorAttrib('static Color', this.color);\n    }\n\n    if (!this.writeAnimation(stream, 'KPPA')) {\n      stream.writeNumberAttrib('static Alpha', this.alpha);\n    }\n\n    this.writeAnimation(stream, 'KPPV');\n\n    if (this.replaceableId !== 0) {\n      stream.writeNumberAttrib('ReplaceableId', this.replaceableId);\n    }\n\n    if (this.path.length) {\n      stream.writeStringAttrib('Path', this.path);\n    }\n\n    if (this.animationVisiblityGuide.length) {\n      stream.writeStringAttrib('AnimVisibilityGuide', this.animationVisiblityGuide);\n    }\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 556 + super.getByteLength();\n  }\n}\n\n"
  },
  {
    "path": "src/parsers/mdlx/ribbonemitter.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport GenericObject from './genericobject';\n\n/**\n * A ribbon emitter.\n */\nexport default class RibbonEmitter extends GenericObject {\n  heightAbove = 0;\n  heightBelow = 0;\n  alpha = 0;\n  color = new Float32Array(3);\n  lifeSpan = 0;\n  textureSlot = 0;\n  emissionRate = 0;\n  rows = 0;\n  columns = 0;\n  materialId = 0;\n  gravity = 0;\n\n  constructor() {\n    super(0x4000);\n  }\n\n  override readMdx(stream: BinaryStream): void {\n    const start = stream.index;\n    const size = stream.readUint32();\n\n    super.readMdx(stream);\n\n    this.heightAbove = stream.readFloat32();\n    this.heightBelow = stream.readFloat32();\n    this.alpha = stream.readFloat32();\n    stream.readFloat32Array(this.color);\n    this.lifeSpan = stream.readFloat32();\n    this.textureSlot = stream.readUint32();\n    this.emissionRate = stream.readUint32();\n    this.rows = stream.readUint32();\n    this.columns = stream.readUint32();\n    this.materialId = stream.readInt32();\n    this.gravity = stream.readFloat32();\n\n    this.readAnimations(stream, size - (stream.index - start));\n  }\n\n  override writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n\n    super.writeMdx(stream);\n\n    stream.writeFloat32(this.heightAbove);\n    stream.writeFloat32(this.heightBelow);\n    stream.writeFloat32(this.alpha);\n    stream.writeFloat32Array(this.color);\n    stream.writeFloat32(this.lifeSpan);\n    stream.writeUint32(this.textureSlot);\n    stream.writeUint32(this.emissionRate);\n    stream.writeUint32(this.rows);\n    stream.writeUint32(this.columns);\n    stream.writeInt32(this.materialId);\n    stream.writeFloat32(this.gravity);\n\n    this.writeNonGenericAnimationChunks(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of super.readGenericBlock(stream)) {\n      if (token === 'static HeightAbove') {\n        this.heightAbove = stream.readFloat();\n      } else if (token === 'HeightAbove') {\n        this.readAnimation(stream, 'KRHA');\n      } else if (token === 'static HeightBelow') {\n        this.heightBelow = stream.readFloat();\n      } else if (token === 'HeightBelow') {\n        this.readAnimation(stream, 'KRHB');\n      } else if (token === 'static Alpha') {\n        this.alpha = stream.readFloat();\n      } else if (token === 'Alpha') {\n        this.readAnimation(stream, 'KRAL');\n      } else if (token === 'static Color') {\n        stream.readColor(this.color);\n      } else if (token === 'Color') {\n        this.readAnimation(stream, 'KRCO');\n      } else if (token === 'static TextureSlot') {\n        this.textureSlot = stream.readInt();\n      } else if (token === 'TextureSlot') {\n        this.readAnimation(stream, 'KRTX');\n      } else if (token === 'Visibility') {\n        this.readAnimation(stream, 'KRVS');\n      } else if (token === 'EmissionRate') {\n        this.emissionRate = stream.readInt();\n      } else if (token === 'LifeSpan') {\n        this.lifeSpan = stream.readFloat();\n      } else if (token === 'Gravity') {\n        this.gravity = stream.readFloat();\n      } else if (token === 'Rows') {\n        this.rows = stream.readInt();\n      } else if (token === 'Columns') {\n        this.columns = stream.readInt();\n      } else if (token === 'MaterialID') {\n        this.materialId = stream.readInt();\n      } else {\n        throw new Error(`Unknown token in RibbonEmitter: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('RibbonEmitter', this.name);\n    this.writeGenericHeader(stream);\n\n    if (!this.writeAnimation(stream, 'KRHA')) {\n      stream.writeNumberAttrib('static HeightAbove', this.heightAbove);\n    }\n\n    if (!this.writeAnimation(stream, 'KRHB')) {\n      stream.writeNumberAttrib('static HeightBelow', this.heightBelow);\n    }\n\n    if (!this.writeAnimation(stream, 'KRAL')) {\n      stream.writeNumberAttrib('static Alpha', this.alpha);\n    }\n\n    if (!this.writeAnimation(stream, 'KRCO')) {\n      stream.writeColor('static Color', this.color);\n    }\n\n    if (!this.writeAnimation(stream, 'KRTX')) {\n      stream.writeNumberAttrib('static TextureSlot', this.textureSlot);\n    }\n\n    this.writeAnimation(stream, 'KRVS');\n\n    stream.writeNumberAttrib('EmissionRate', this.emissionRate);\n    stream.writeNumberAttrib('LifeSpan', this.lifeSpan);\n\n    if (this.gravity !== 0) {\n      stream.writeNumberAttrib('Gravity', this.gravity);\n    }\n\n    stream.writeNumberAttrib('Rows', this.rows);\n    stream.writeNumberAttrib('Columns', this.columns);\n    stream.writeNumberAttrib('MaterialID', this.materialId);\n\n    this.writeGenericAnimations(stream);\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 56 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/sequence.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport Extent from './extent';\n\n/**\n * A sequence.\n */\nexport default class Sequence {\n  name = '';\n  interval = new Uint32Array(2);\n  moveSpeed = 0;\n  nonLooping = 0;\n  rarity = 0;\n  syncPoint = 0;\n  extent = new Extent();\n\n  readMdx(stream: BinaryStream): void {\n    this.name = stream.read(80);\n    stream.readUint32Array(this.interval);\n    this.moveSpeed = stream.readFloat32();\n    this.nonLooping = stream.readUint32();\n    this.rarity = stream.readFloat32();\n    this.syncPoint = stream.readUint32();\n    this.extent.readMdx(stream);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.skip(80 - stream.write(this.name));\n    stream.writeUint32Array(this.interval);\n    stream.writeFloat32(this.moveSpeed);\n    stream.writeUint32(this.nonLooping);\n    stream.writeFloat32(this.rarity);\n    stream.writeUint32(this.syncPoint);\n    this.extent.writeMdx(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    this.name = stream.read();\n\n    for (const token of stream.readBlock()) {\n      if (token === 'Interval') {\n        stream.readVector(this.interval);\n      } else if (token === 'NonLooping') {\n        this.nonLooping = 1;\n      } else if (token === 'MoveSpeed') {\n        this.moveSpeed = stream.readFloat();\n      } else if (token === 'Rarity') {\n        this.rarity = stream.readFloat();\n      } else if (token === 'MinimumExtent') {\n        stream.readVector(this.extent.min);\n      } else if (token === 'MaximumExtent') {\n        stream.readVector(this.extent.max);\n      } else if (token === 'BoundsRadius') {\n        this.extent.boundsRadius = stream.readFloat();\n      } else {\n        throw new Error(`Unknown token in Sequence: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startObjectBlock('Anim', this.name);\n    stream.writeVectorAttrib('Interval', this.interval);\n\n    if (this.nonLooping === 1) {\n      stream.writeFlag('NonLooping');\n    }\n\n    if (this.moveSpeed !== 0) {\n      stream.writeNumberAttrib('MoveSpeed', this.moveSpeed);\n    }\n\n    if (this.rarity !== 0) {\n      stream.writeNumberAttrib('Rarity', this.rarity);\n    }\n\n    this.extent.writeMdl(stream);\n    stream.endBlock();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/texture.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\n\nexport const enum WrapMode {\n  RepeatBoth = 0,\n  WrapWidth = 1,\n  WrapHeight = 2,\n  WrapBoth = 3,\n}\n\n/**\n * A texture.\n */\nexport default class Texture {\n  replaceableId = 0;\n  path = '';\n  wrapMode = WrapMode.RepeatBoth;\n\n  readMdx(stream: BinaryStream): void {\n    this.replaceableId = stream.readUint32();\n    this.path = stream.read(260);\n    this.wrapMode = stream.readUint32();\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.replaceableId);\n    stream.skip(260 - stream.write(this.path));\n    stream.writeUint32(this.wrapMode);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of stream.readBlock()) {\n      if (token === 'Image') {\n        this.path = stream.read();\n      } else if (token === 'ReplaceableId') {\n        this.replaceableId = stream.readInt();\n      } else if (token === 'WrapWidth') {\n        this.wrapMode |= WrapMode.WrapWidth;\n      } else if (token === 'WrapHeight') {\n        this.wrapMode |= WrapMode.WrapHeight;\n      } else {\n        throw new Error(`Unknown token in Texture: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startBlock('Bitmap');\n\n    if (this.path.length) {\n      stream.writeStringAttrib('Image', this.path);\n    }\n\n    if (this.replaceableId !== 0) {\n      stream.writeNumberAttrib('ReplaceableId', this.replaceableId);\n    }\n\n    if (this.wrapMode & WrapMode.WrapWidth) {\n      stream.writeFlag(`WrapWidth`);\n    }\n\n    if (this.wrapMode & WrapMode.WrapHeight) {\n      stream.writeFlag(`WrapHeight`);\n    }\n\n    stream.endBlock();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/textureanimation.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport TokenStream from './tokenstream';\nimport AnimatedObject from './animatedobject';\n\n/**\n * A texture animation.\n */\nexport default class TextureAnimation extends AnimatedObject {\n  readMdx(stream: BinaryStream): void {\n    const size = stream.readUint32();\n\n    this.readAnimations(stream, size - 4);\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeUint32(this.getByteLength());\n    this.writeAnimations(stream);\n  }\n\n  readMdl(stream: TokenStream): void {\n    for (const token of stream.readBlock()) {\n      if (token === 'Translation') {\n        this.readAnimation(stream, 'KTAT');\n      } else if (token === 'Rotation') {\n        this.readAnimation(stream, 'KTAR');\n      } else if (token === 'Scaling') {\n        this.readAnimation(stream, 'KTAS');\n      } else {\n        throw new Error(`Unknown token in TextureAnimation: \"${token}\"`);\n      }\n    }\n  }\n\n  writeMdl(stream: TokenStream): void {\n    stream.startBlock('TVertexAnim ');\n    this.writeAnimation(stream, 'KTAT');\n    this.writeAnimation(stream, 'KTAR');\n    this.writeAnimation(stream, 'KTAS');\n    stream.endBlock();\n  }\n\n  override getByteLength(): number {\n    return 4 + super.getByteLength();\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/tokenstream.ts",
    "content": "/**\n * Used to read and write MDL tokens.\n */\nexport default class TokenStream {\n  buffer: string;\n  index = 0;\n  ident = 0;\n  indentSpaces = 4;\n  precision = 1000000; // 6 digits after the decimal point.\n\n  constructor(buffer?: string) {\n    this.buffer = buffer || '';\n  }\n\n  /**\n   * Clear the stream from whatever buffer it had.\n   */\n  clear(): void {\n    this.buffer = '';\n    this.index = 0;\n    this.ident = 0;\n  }\n\n  /**\n   * Reads the next token in the stream.\n   * Whitespaces are ignored outside of strings in the form of \"\".\n   * Comments in the form of // are ignored.\n   * Commas and colons are ignored as well.\n   * Curly braces are used as separators, generally to denote text blocks.\n   *\n   * For example, given the following string:\n   *\n   *     Header \"A String\" {\n   *         Name Value, // A Comment\n   *     }\n   *\n   * Read will return the values in order:\n   *\n   *     Header\n   *     \"A String\"\n   *     {\n   *     Name\n   *     Value\n   *     }\n   *\n   * There are wrappers around read, below, that help to read structured code, check them out!\n   */\n  readToken(): string | undefined {\n    const buffer = this.buffer;\n    const length = buffer.length;\n    let inComment = false;\n    let inString = false;\n    let token = '';\n\n    while (this.index < length) {\n      const c = buffer[this.index++];\n\n      if (inComment) {\n        if (c === '\\n') {\n          inComment = false;\n        }\n      } else if (inString) {\n        if (c === '\\\\') {\n          token += c + buffer[this.index++];\n        } else if (c === '\\n') {\n          token += '\\\\n';\n        } else if (c === '\\r') {\n          token += '\\\\r';\n        } else if (c === '\"') {\n          return token;\n        } else {\n          token += c;\n        }\n      } else if (c === ' ' || c === ',' || c === '\\t' || c === '\\n' || c === ':' || c === '\\r') {\n        if (token.length) {\n          return token;\n        }\n      } else if (c === '{' || c === '}') {\n        if (token.length) {\n          this.index--;\n          return token;\n        } else {\n          return c;\n        }\n      } else if (c === '/' && buffer[this.index] === '/') {\n        if (token.length) {\n          this.index--;\n          return token;\n        } else {\n          inComment = true;\n        }\n      } else if (c === '\"') {\n        if (token.length) {\n          this.index--;\n          return token;\n        } else {\n          inString = true;\n        }\n      } else {\n        token += c;\n      }\n    }\n\n    return;\n  }\n\n  /**\n   * Same as readToken, but if the end of the stream was encountered, an exception will be thrown.\n   */\n  read(): string {\n    const value = this.readToken();\n\n    if (value === undefined) {\n      throw new Error('End of stream reached prematurely');\n    }\n\n    return value;\n  }\n\n  /**\n   * Reads the next token without advancing the stream.\n   */\n  peek(): string {\n    const index = this.index;\n    const value = this.read();\n\n    this.index = index;\n\n    return value;\n  }\n\n  /**\n   * Reads the next token, and parses it as an integer.\n   */\n  readInt(): number {\n    return parseInt(this.read());\n  }\n\n  /**\n   * Reads the next token, and parses it as a float.\n   */\n  readFloat(): number {\n    return parseFloat(this.read());\n  }\n\n  /**\n   * { Number0, Number1, ..., NumberN }\n   */\n  readVector<T extends Uint8Array | Uint16Array | Uint32Array | Float32Array>(view: T): T {\n    this.read(); // {\n\n    for (let i = 0, l = view.length; i < l; i++) {\n      view[i] = this.readFloat();\n    }\n\n    this.read(); // }\n\n    return view;\n  }\n\n  /**\n   * {\n   *     { Value1, Value2, ..., ValueSize },\n   *     { Value1, Value2, ..., ValueSize },\n   *     ...\n   * }\n   */\n  readVectorsBlock<T extends Uint16Array | Float32Array>(view: T, size: number): T {\n    this.read(); // {\n\n    for (let i = 0, l = view.length; i < l; i += size) {\n      this.readVector(view.subarray(i, i + size));\n    }\n\n    this.read(); // }\n\n    return view;\n  }\n\n  /**\n   * Reads a color in the form:\n   *\n   *      { R, G, B }\n   *\n   * The color is sizzled to BGR.\n   */\n  readColor(view: Float32Array): Float32Array {\n    this.read(); // {\n\n    view[2] = this.readFloat();\n    view[1] = this.readFloat();\n    view[0] = this.readFloat();\n\n    this.read(); // }\n\n    return view;\n  }\n\n  /**\n   * Helper generator for block reading.\n   * Let's say we have a block like so:\n   * \n   *     {\n   *         Key1 Value1\n   *         Key2 Value2\n   *         ...\n   *         KeyN ValueN\n   *     }\n   * \n   * The generator yields the keys one by one, and the caller needs to read the values based on the keys.\n   * It is used for most MDL blocks.\n   */\n  * readBlock(): Generator<string> {\n    this.read(); // {\n\n    let token = this.read();\n\n    while (token !== '}') {\n      yield token;\n\n      token = this.read();\n    }\n  }\n\n  /**\n   * Adds the given string to the buffer.\n   * The current indentation level is prepended, and the stream goes to the next line after the write.\n   */\n  writeLine(line: string): void {\n    this.buffer += `${' '.repeat(this.ident * this.indentSpaces)}${line}\\n`;\n  }\n\n  /**\n   * Flag,\n   */\n  writeFlag(flag: string): void {\n    this.writeLine(`${flag},`);\n  }\n\n  /**\n   * Name Flag,\n   */\n  writeFlagAttrib(name: string, flag: string): void {\n    this.writeLine(`${name} ${flag},`);\n  }\n\n  /**\n   * Name Value,\n   */\n  writeNumberAttrib(name: string, value: number): void {\n    this.writeLine(`${name} ${this.floatDecimals(value)},`);\n  }\n\n  /**\n   * Name \"Value\",\n   */\n  writeStringAttrib(name: string, value: string): void {\n    this.writeLine(`${name} \"${value}\",`);\n  }\n\n  /**\n   * Name { Value0, Value1, ..., ValueN }\n   */\n  writeVectorAttrib(name: string, value: Uint8Array | Uint32Array | Float32Array): void {\n    this.writeLine(`${name} { ${this.floatArrayDecimals(value)} },`);\n  }\n\n  /**\n   * Writes a color in the form:\n   *\n   *      { B, G, R }\n   *\n   * The color is sizzled to RGB.\n   * The name can be either \"Color\" or \"static Color\", depending on the context.\n   */\n  writeColor(name: string, value: Float32Array): void {\n    const b = this.floatDecimals(value[0]);\n    const g = this.floatDecimals(value[1]);\n    const r = this.floatDecimals(value[2]);\n\n    this.writeLine(`${name} { ${r}, ${g}, ${b} },`);\n  }\n\n  /**\n   * { Value0, Value1, ..., ValueN },\n   */\n  writeVector(value: Uint16Array | Float32Array): void {\n    this.writeLine(`{ ${this.floatArrayDecimals(value)} },`);\n  }\n\n  /**\n   * Name Vectors {\n   *     { Value1, Value2, ..., ValueSize },\n   *     { Value1, Value2, ..., ValueSize },\n   *     ...\n   * }\n   */\n  writeVectorArrayBlock(name: string, view: Float32Array, size: number): void {\n    this.startBlock(name, view.length / size);\n\n    for (let i = 0, l = view.length; i < l; i += size) {\n      this.writeVector(view.subarray(i, i + size));\n    }\n\n    this.endBlock();\n  }\n\n  /**\n   * Starts a new block in the form:\n   *\n   *      Header1 Header2 ... HeaderN {\n   *          ...\n   *      }\n   */\n  startBlock(name: string, ...headers: (string | number)[]): void {\n    if (headers.length) {\n      name = `${name} ${headers.join(' ')}`;\n    }\n\n    this.writeLine(`${name} {`);\n    this.ident += 1;\n  }\n\n  /**\n   * Starts a new block in the form:\n   *\n   *      Header \"Name\" {\n   *          ...\n   *      }\n   */\n  startObjectBlock(header: string, name: string): void {\n    // Turns out you can have quotation marks in object names.\n    this.writeLine(`${header} \"${name.replace(/\"/g, '\\\\\"')}\" {`);\n    this.ident += 1;\n  }\n\n  /**\n   * Ends a previously started block, and handles the indentation.\n   */\n  endBlock(): void {\n    this.ident -= 1;\n    this.writeLine('}');\n  }\n\n  /**\n   * Ends a previously started block, and handles the indentation.\n   * Adds a comma after the block end.\n   */\n  endBlockComma(): void {\n    this.ident -= 1;\n    this.writeLine('},');\n  }\n\n  /**\n   * Increases the indentation level for following line writes.\n   */\n  indent(): void {\n    this.ident += 1;\n  }\n\n  /**\n   * Decreases the indentation level for following line writes.\n   */\n  unindent(): void {\n    this.ident -= 1;\n  }\n\n  /**\n * Given a number, truncates digits after the decimal point.\n * The given precision should be in base 10.\n * E.g. for a precision of two digits after the decimal point, the precision should be 100.\n * The result is returned as a string.\n */\n  floatDecimals(value: number): string {\n    return `${Math.trunc(value * this.precision) / this.precision}`;\n  }\n\n  /**\n   * Uses floatDecimals on a typed array, and returns its string representation. \n   */\n  floatArrayDecimals(value: Uint8Array | Uint16Array | Uint32Array | Float32Array): string {\n    if (value instanceof Float32Array) {\n      const array = [];\n\n      for (let i = 0, l = value.length; i < l; i++) {\n        array[i] = this.floatDecimals(value[i]);\n      }\n\n      return array.join(', ');\n    } else {\n      return value.join(', ');\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/mdlx/unknownchunk.ts",
    "content": "import BinaryStream from '../../common/binarystream';\n\n/**\n * An unknown chunk.\n */\nexport default class UnknownChunk {\n  tag: string;\n  chunk: Uint8Array;\n\n  constructor(stream: BinaryStream, size: number, tag: string) {\n    this.tag = tag;\n    this.chunk = stream.readUint8Array(new Uint8Array(size));\n  }\n\n  writeMdx(stream: BinaryStream): void {\n    stream.writeBinary(this.tag);\n    stream.writeUint32(this.chunk.byteLength);\n    stream.writeUint8Array(this.chunk);\n  }\n\n  getByteLength(): number {\n    return 8 + this.chunk.byteLength;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/adpcm.ts",
    "content": "import BinaryStream from '../../common/binarystream';\n\nconst MAX_ADPCM_CHANNEL_COUNT = 2;\nconst INITIAL_ADPCM_STEP_INDEX = 0x2C;\n\nconst NextStepTable = new Int32Array([\n  -1, 0, -1, 4, -1, 2, -1, 6,\n  -1, 1, -1, 5, -1, 3, -1, 7,\n  -1, 1, -1, 5, -1, 3, -1, 7,\n  -1, 2, -1, 4, -1, 6, -1, 8,\n]);\n\nconst StepSizeTable = new Int32Array([\n  7, 8, 9, 10, 11, 12, 13, 14,\n  16, 17, 19, 21, 23, 25, 28, 31,\n  34, 37, 41, 45, 50, 55, 60, 66,\n  73, 80, 88, 97, 107, 118, 130, 143,\n  157, 173, 190, 209, 230, 253, 279, 307,\n  337, 371, 408, 449, 494, 544, 598, 658,\n  724, 796, 876, 963, 1060, 1166, 1282, 1411,\n  1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,\n  3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,\n  7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,\n  15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,\n  32767,\n]);\n\nfunction GetNextStepIndex(StepIndex: number, EncodedSample: number): number {\n  StepIndex = StepIndex + NextStepTable[EncodedSample & 0x1F];\n\n  if (StepIndex < 0) {\n    StepIndex = 0;\n  } else if (StepIndex > 88) {\n    StepIndex = 88;\n  }\n\n  return StepIndex;\n}\n\nfunction UpdatePredictedSample(PredictedSample: number, EncodedSample: number, Difference: number): number {\n  if (EncodedSample & 0x40) {\n    PredictedSample -= Difference;\n\n    if (PredictedSample <= -32768) {\n      PredictedSample = -32768;\n    }\n  } else {\n    PredictedSample += Difference;\n\n    if (PredictedSample >= 32767) {\n      PredictedSample = 32767;\n    }\n  }\n\n  return PredictedSample;\n}\n\nfunction DecodeSample(PredictedSample: number, EncodedSample: number, StepSize: number, Difference: number): number {\n  if (EncodedSample & 0x01) {\n    Difference += (StepSize >> 0);\n  }\n\n  if (EncodedSample & 0x02) {\n    Difference += (StepSize >> 1);\n  }\n\n  if (EncodedSample & 0x04) {\n    Difference += (StepSize >> 2);\n  }\n\n  if (EncodedSample & 0x08) {\n    Difference += (StepSize >> 3);\n  }\n\n  if (EncodedSample & 0x10) {\n    Difference += (StepSize >> 4);\n  }\n\n  if (EncodedSample & 0x20) {\n    Difference += (StepSize >> 5);\n  }\n\n  return UpdatePredictedSample(PredictedSample, EncodedSample, Difference);\n}\n\nexport default function DecompressADPCM(pvInBuffer: Uint8Array, ChannelCount: number): Uint8Array {\n  const is = new BinaryStream(pvInBuffer);\n  const os = <number[]>[];\n  let EncodedSample;\n  const PredictedSamples = new Uint16Array(MAX_ADPCM_CHANNEL_COUNT);\n  const StepIndexes = new Uint16Array([INITIAL_ADPCM_STEP_INDEX, INITIAL_ADPCM_STEP_INDEX]);\n  let ChannelIndex;\n\n  is.readUint8();\n  const BitShift = is.readUint8();\n\n  for (let i = 0; i < ChannelCount; i++) {\n    const InitialSample = is.readUint16();\n\n    PredictedSamples[i] = InitialSample;\n\n    os.push(InitialSample);\n  }\n\n  ChannelIndex = ChannelCount - 1;\n\n  while (is.remaining) {\n    EncodedSample = is.readUint8();\n\n    ChannelIndex = (ChannelIndex + 1) % ChannelCount;\n\n    if (EncodedSample == 0x80) {\n      if (StepIndexes[ChannelIndex] != 0) {\n        StepIndexes[ChannelIndex]--;\n      }\n\n      os.push(PredictedSamples[ChannelIndex]);\n    } else if (EncodedSample == 0x81) {\n      StepIndexes[ChannelIndex] += 8;\n\n      if (StepIndexes[ChannelIndex] > 0x58) {\n        StepIndexes[ChannelIndex] = 0x58;\n      }\n\n      ChannelIndex = (ChannelIndex + 1) % ChannelCount;\n    } else {\n      const StepIndex = StepIndexes[ChannelIndex];\n      const StepSize = StepSizeTable[StepIndex];\n\n      PredictedSamples[ChannelIndex] = DecodeSample(PredictedSamples[ChannelIndex], EncodedSample, StepSize, StepSize >> BitShift);\n\n      os.push(PredictedSamples[ChannelIndex]);\n\n      StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndex, EncodedSample);\n    }\n  }\n\n  return new Uint8Array(new Uint16Array(os).buffer);\n}\n"
  },
  {
    "path": "src/parsers/mpq/archive.ts",
    "content": "import { bytesOf } from '../../common/bytesof';\nimport { powerOfTwo } from '../../common/math';\nimport { numberToUint32 } from '../../common/typecast';\nimport MpqBlockTable from './blocktable';\nimport { HASH_ENTRY_DELETED, HASH_ENTRY_EMPTY, MAGIC } from './constants';\nimport MpqCrypto from './crypto';\nimport MpqFile from './file';\nimport MpqHashTable from './hashtable';\nimport { searchHeader } from './isarchive';\n\n/**\n * MoPaQ archive (MPQ) version 0.\n */\nexport default class MpqArchive {\n  headerOffset: number;\n  sectorSize: number;\n  c: MpqCrypto;\n  hashTable: MpqHashTable;\n  blockTable: MpqBlockTable;\n  files: MpqFile[];\n  readonly = false;\n\n  constructor() {\n    this.headerOffset = 0;\n    this.sectorSize = 4096;\n    this.c = new MpqCrypto();\n    this.hashTable = new MpqHashTable(this.c);\n    this.blockTable = new MpqBlockTable(this.c);\n    this.files = [];\n  }\n\n  /**\n   * Load an existing archive.\n   * \n   * Note that this clears the archive from whatever it had in it before.\n   */\n  load(buffer: ArrayBuffer | Uint8Array, readonly = false): void {\n    const bytes = bytesOf(buffer);\n\n    this.readonly = readonly;\n\n    // let fileSize = buffer.byteLength;\n    const headerOffset = searchHeader(bytes);\n\n    if (headerOffset === -1) {\n      throw new Error('No MPQ header');\n    }\n\n    // Read the header.\n    const uint32array = new Uint32Array(bytes.buffer, headerOffset, 8);\n    // let headerSize = uint32array[1];\n    // let archiveSize = uint32array[2];\n    const formatVersionSectorSize = uint32array[3];\n    // let formatVersion = formatVersionSectorSize & 0x0000FFFF;\n    const hashPos = numberToUint32(uint32array[4] + headerOffset); // Whoever thought of MoonLight, clever!\n    const blockPos = numberToUint32(uint32array[5] + headerOffset);\n    const hashSize = uint32array[6];\n    let blockSize = uint32array[7];\n\n    // There can only be as many or less blocks as there are hashes.\n    // Therefore, if the file is reporting too many blocks, cap the actual blocks read to the amount of hashes.\n    if (blockSize > hashSize) {\n      blockSize = hashSize;\n    }\n\n    this.headerOffset = headerOffset;\n    this.sectorSize = 512 * (1 << (formatVersionSectorSize >>> 16)); // Generally 4096\n\n    // Read the hash table.\n    // Also clears any existing entries.\n    // Have to copy the data, because hashPos is not guaranteed to be a multiple of 4.\n    this.hashTable.load(bytes.slice(hashPos, hashPos + hashSize * 16));\n\n    // Read the block table.\n    // Also clears any existing entries.\n    // Have to copy the data, because blockPos is not guaranteed to be a multiple of 4.\n    this.blockTable.load(bytes.slice(blockPos, blockPos + blockSize * 16));\n\n    // Clear any existing files.\n    this.files.length = 0;\n\n    // Read the files.\n    for (const hash of this.hashTable.entries) {\n      const blockIndex = hash.blockIndex;\n\n      // If the block index is valid, load a file.\n      // This isn't the case when the block is marked as deleted with HASH_ENTRY_DELETED.\n      // This also isn't the case for archives with fake block indices.\n      if (blockIndex < this.blockTable.entries.length) {\n        this.files[blockIndex] = new MpqFile(this, hash, this.blockTable.entries[blockIndex], bytes, null);\n      }\n    }\n\n    // If there is a listfile, use all of the file names in it.\n    const listfile = this.get('(listfile)');\n    if (listfile) {\n      const list = listfile.text();\n\n      if (list) {\n        for (const name of list.split('\\r\\n')) {\n          // get() internally also sets the file's name to the given one.\n          this.get(name);\n        }\n      }\n    }\n  }\n\n  /**\n   * Save this archive.\n   * \n   * Returns null when...\n   * \n   *     1) The archive is in readonly mode.\n   *     2) The offset of a file encrypted with FILE_OFFSET_ADJUSTED_KEY changed, and the file name is unknown.\n   */\n  save(): Uint8Array | null {\n    if (this.readonly) {\n      return null;\n    }\n\n    const headerSize = 32;\n\n    // Delete the internal attributes file.\n    // The attributes might (and do in the case of World Editor generated maps) contain CRC checksums for the internal files.\n    // If any of these files is edited in any way, the map will be considered corrupted.\n    // Therefore, delete the file, and nothing will be corrupted.\n    // As far as I can tell, there is no real reason to keep (and update) any of the file attributes.\n    // It's not like Warcraft 3 has some database of checksums that it checks against.\n    // I assume it does have a database for the Battle.net ladder maps.\n    // If at any point it becomes known to me that it is indeed needed, I will add support for (attributes).\n    this.delete('(attributes)');\n\n    // Some archives have empty blocks in them.\n    // That is, blocks that take up memory, but have no actual valid data in them (as far as the archive is concerned).\n    // I am not sure why they exist - maybe someone deleted a file's entry and was too lazy to rebuild the archive.\n    // This removes such blocks of memory from the archive.\n    this.saveMemory();\n\n    // Set the listfile.\n    this.set('(listfile)', this.getFileNames().join('\\r\\n'));\n\n    // Reset the file offsets.\n    let offset = headerSize;\n\n    for (const file of this.files) {\n      // There can be holes in the files array.\n      if (file) {\n        // If the file's offset changed, and it is encrypted with a key that depends on its offset,\n        // it needs to be decryped with it's current key, and encryped with the new key.\n        if (!file.offsetChanged(offset)) {\n          return null;\n        }\n\n        // If the file needs to be encoded, do it.\n        file.encode();\n\n        offset += file.block.compressedSize;\n      }\n    }\n\n    const hashTable = this.hashTable;\n    const blockTable = this.blockTable;\n    const hashes = hashTable.entries.length;\n    const blocks = blockTable.entries.length;\n    const filesSize = offset - headerSize;\n    const archiveSize = headerSize + filesSize + hashes * 16 + blocks * 16;\n    const hashPos = headerSize + filesSize;\n    const blockPos = hashPos + hashes * 16;\n    const bytes = new Uint8Array(archiveSize);\n    const uint32array = new Uint32Array(bytes.buffer, 0, 8);\n\n    // Write the header.\n    uint32array[0] = MAGIC;\n    uint32array[1] = headerSize;\n    uint32array[2] = archiveSize;\n    uint32array[3] = Math.log2(this.sectorSize / 512) << 16; // The version is always 0, so ignore it.\n    uint32array[4] = hashPos;\n    uint32array[5] = blockPos;\n    uint32array[6] = hashes;\n    uint32array[7] = blocks;\n\n    offset = headerSize;\n\n    // Write the files.\n    for (const file of this.files) {\n      // There can be holes in the files array.\n      if (file) {\n        if (file.rawBuffer) {\n          bytes.set(file.rawBuffer, offset);\n        }\n\n        offset += file.block.compressedSize;\n      }\n    }\n\n    // Write the hash table.\n    hashTable.save(bytes.subarray(offset, offset + hashTable.entries.length * 16));\n\n    offset += hashTable.entries.length * 16;\n\n    // Write the block table.\n    blockTable.save(bytes.subarray(offset, offset + blockTable.entries.length * 16));\n\n    return bytes;\n  }\n\n  /**\n   * Some MPQs have empty memory chunks in them, left over from files that were deleted.\n   * This function searches for such chunks, and removes them.\n   * \n   * Note that it is called automatically by save().\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  saveMemory(): number {\n    if (this.readonly) {\n      return 0;\n    }\n\n    const blocks = this.blockTable.entries;\n    const hashes = this.hashTable.entries;\n    let i = blocks.length;\n    let saved = 0;\n\n    while (i--) {\n      const block = blocks[i];\n\n      // Remove blocks with no data.\n      if (block.normalSize === 0) {\n        this.removeBlock(i);\n\n        saved += block.compressedSize;\n      } else {\n        let used = false;\n\n        for (const hash of hashes) {\n          if (hash.blockIndex === i) {\n            used = true;\n            break;\n          }\n        }\n\n        // Remove blocks that are not used.\n        if (!used) {\n          this.removeBlock(i);\n\n          saved += block.compressedSize;\n        }\n      }\n    }\n\n    return saved;\n  }\n\n  removeBlock(blockIndex: number): void {\n    for (const hash of this.hashTable.entries) {\n      if (hash.blockIndex < HASH_ENTRY_DELETED && hash.blockIndex > blockIndex) {\n        hash.blockIndex -= 1;\n      }\n    }\n\n    this.blockTable.entries.splice(blockIndex, 1);\n  }\n\n  /**\n   * Gets a list of the file names in the archive.\n   * \n   * Note that files loaded from an existing archive, without resolved names, will be named FileXXXXXXXX.\n   */\n  getFileNames(): string[] {\n    const names = [];\n\n    for (const file of this.files) {\n      if (file && file.name !== '') {\n        names.push(file.name);\n      }\n    }\n\n    return names;\n  }\n\n  /**\n   * Count the files with unresolved names.\n   */\n  countUnresolved(): number {\n    let unresolved = 0;\n\n    for (const file of this.files) {\n      if (!file.nameResolved) {\n        unresolved++;\n      }\n    }\n\n    return unresolved;\n  }\n\n  /**\n   * Given an iterable of file names, attempt to resolve the archive files with them.\n   */\n  applyListfile(listfile: Iterable<string>): void {\n    for (const file of listfile) {\n      this.get(file);\n    }\n  }\n\n  /**\n   * Adds a file to this archive.\n   * If the file already exists, its buffer will be set.\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  set(name: string, buffer: ArrayBuffer | Uint8Array | string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    const bytes = bytesOf(buffer);\n    let file = this.get(name);\n\n    // If the file already exists, change the data.\n    if (file) {\n      file.set(bytes);\n    } else {\n      const blockIndex = this.blockTable.entries.length;\n      const hash = this.hashTable.add(name, blockIndex);\n\n      if (!hash) {\n        return false;\n      }\n\n      const block = this.blockTable.add(bytes);\n\n      file = new MpqFile(this, hash, block, null, bytes);\n      file.name = name;\n      file.nameResolved = true;\n\n      this.files[blockIndex] = file;\n    }\n\n    return true;\n  }\n\n  /**\n   * Gets a file from this archive.\n   * If the file doesn't exist, null is returned.\n   */\n  get(name: string): MpqFile | null {\n    const hash = this.hashTable.get(name);\n\n    if (hash) {\n      const blockIndex = hash.blockIndex;\n\n      // Check if the block exists.\n      if (blockIndex < HASH_ENTRY_DELETED) {\n        const file = this.files[blockIndex];\n\n        if (file) {\n          // Save the name in case it wasn't already resolved.\n          file.name = name;\n          file.nameResolved = true;\n\n          return file;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  /**\n   * Checks if a file exists.\n   * \n   * Prefer to use get() if you are going to use get() afterwards anyway.\n   */\n  has(name: string): boolean {\n    return !!this.get(name);\n  }\n\n  /**\n   * Deletes a file from this archive.\n   * \n   * Does nothing if...\n   * \n   *     1) The archive is in readonly mode.\n   *     2) The file does not exist.\n   */\n  delete(name: string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    const file = this.get(name);\n\n    if (!file) {\n      return false;\n    }\n\n    file.delete();\n\n    return true;\n  }\n\n  /**\n   * Renames a file.\n   * \n   * Does nothing if...\n   * \n   *     1) The archive is in readonly mode.\n   *     2) The file does not exist.\n   * \n   * Note that this sets the current file's hash's status to being deleted, rather than removing it.\n   * This is due to the way the search algorithm works.\n   */\n  rename(name: string, newName: string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    const file = this.get(name);\n\n    if (!file) {\n      return false;\n    }\n\n    file.rename(newName);\n\n    return true;\n  }\n\n  /**\n   * Resizes the hashtable to the nearest power of two equal to or bigger than the given size.\n   * \n   * Generally speaking, the bigger the hashtable is, the quicker insertions/searches are, at the cost of added memory.\n   * \n   * Does nothing if...\n   * \n   *     1) The archive is in readonly mode.\n   *     2) The calculated size is smaller than the amount of files in the archive.\n   *     3) Not all of the file names in the archive are resolved.\n   */\n  resizeHashtable(size: number): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    size = Math.max(4, powerOfTwo(size));\n\n    const files = this.files;\n\n    // Can't resize to a size smaller than the existing files.\n    if (files.length > size) {\n      return false;\n    }\n\n    // If not all file names are known, don't resize.\n    // The insertion algorithm depends on the names.\n    for (const file of files) {\n      if (!file.nameResolved) {\n        return false;\n      }\n    }\n\n    const hashTable = this.hashTable;\n    const entries = hashTable.entries;\n    const oldEntries = entries.slice();\n\n    // Clear the entries.\n    hashTable.clear();\n\n    // Add empty entries.\n    hashTable.addEmpties(size);\n\n    // Go over all of the old entries, and copy them into the new entries.\n    for (const hash of oldEntries) {\n      if (hash.blockIndex !== HASH_ENTRY_EMPTY) {\n        const file = files[hash.blockIndex];\n        const insertionIndex = hashTable.getInsertionIndex(file.name);\n\n        entries[insertionIndex].copy(hash);\n      }\n    }\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/block.ts",
    "content": "/**\n * A block.\n */\nexport default class Block {\n  offset = 0;\n  compressedSize = 0;\n  normalSize = 0;\n  flags = 0;\n\n  load(bytes: Uint32Array): void {\n    this.offset = bytes[0];\n    this.compressedSize = bytes[1];\n    this.normalSize = bytes[2];\n    this.flags = bytes[3];\n  }\n\n  save(bytes: Uint32Array): void {\n    bytes[0] = this.offset;\n    bytes[1] = this.compressedSize;\n    bytes[2] = this.normalSize;\n    bytes[3] = this.flags;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/blocktable.ts",
    "content": "import MpqCrypto from './crypto';\nimport MpqBlock from './block';\nimport { BLOCK_TABLE_KEY } from './constants';\n\n/**\n * A block table.\n */\nexport default class BlockTable {\n  c: MpqCrypto;\n  entries: MpqBlock[];\n\n  constructor(c: MpqCrypto) {\n    this.c = c;\n    this.entries = [];\n  }\n\n  add(buffer: ArrayBuffer): MpqBlock {\n    const block = new MpqBlock();\n\n    block.normalSize = buffer.byteLength;\n\n    this.entries.push(block);\n\n    return block;\n  }\n\n  clear(): void {\n    this.entries.length = 0;\n  }\n\n  addEmpties(howMany: number): void {\n    for (let i = 0; i < howMany; i++) {\n      this.entries.push(new MpqBlock());\n    }\n  }\n\n  load(bytes: Uint8Array): void {\n    const entriesCount = bytes.byteLength / 16;\n    const uint32array = new Uint32Array(this.c.decryptBlock(bytes, BLOCK_TABLE_KEY).buffer);\n    let offset = 0;\n\n    // Clear the table and add the needed empties.\n    this.clear();\n    this.addEmpties(entriesCount);\n\n    for (const block of this.entries) {\n      block.load(uint32array.subarray(offset, offset + 4));\n\n      offset += 4;\n    }\n  }\n\n  save(bytes: Uint8Array): void {\n    const uint32array = new Uint32Array(this.entries.length * 4);\n    let offset = 0;\n\n    for (const block of this.entries) {\n      block.save(uint32array.subarray(offset, offset + 4));\n\n      offset += 4;\n    }\n\n    const uint8array = new Uint8Array(uint32array.buffer);\n\n    this.c.encryptBlock(uint8array, BLOCK_TABLE_KEY);\n\n    bytes.set(uint8array);\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/constants.ts",
    "content": "export const MAGIC = 0x1A51504D; // MPQ\\x1A reversed\nexport const HASH_TABLE_KEY = 0xC3AF3770; // Hash of (hashtable)\nexport const HASH_TABLE_INDEX = 0;\nexport const HASH_NAME_A = 1;\nexport const HASH_NAME_B = 2;\nexport const HASH_FILE_KEY = 3;\nexport const HASH_ENTRY_DELETED = 0xFFFFFFFE;\nexport const HASH_ENTRY_EMPTY = 0xFFFFFFFF;\nexport const BLOCK_TABLE_KEY = 0xEC83B3A3; // Hash of (blocktable)\nexport const FILE_IMPLODE = 0x00000100;\nexport const FILE_COMPRESSED = 0x00000200;\nexport const FILE_ENCRYPTED = 0x00010000;\nexport const FILE_OFFSET_ADJUSTED_KEY = 0x00020000;\nexport const FILE_PATCH_FILE = 0x00100000;\nexport const FILE_SINGLE_UNIT = 0x01000000;\nexport const FILE_DELETE_MARKER = 0x02000000;\nexport const FILE_SECTOR_CRC = 0x04000000;\nexport const FILE_EXISTS = 0x80000000;\nexport const COMPRESSION_HUFFMAN = 0x01;\nexport const COMPRESSION_DEFLATE = 0x02;\nexport const COMPRESSION_IMPLODE = 0x08;\nexport const COMPRESSION_BZIP2 = 0x10;\nexport const COMPRESSION_ADPCM_MONO = 0x40;\nexport const COMPRESSION_ADPCM_STEREO = 0x80;\n"
  },
  {
    "path": "src/parsers/mpq/crypto.ts",
    "content": "import MpqBlock from './block';\nimport { HASH_FILE_KEY, FILE_OFFSET_ADJUSTED_KEY } from './constants';\n\n// Global variables for this module.\nconst bytesHeap = new Uint8Array(4);\nconst longHeap = new Uint32Array(bytesHeap.buffer);\n\n/**\n * MPQ crypto.\n */\nexport default class MpqCrypto {\n  cryptTable = new Uint32Array(0x500);\n\n  constructor() {\n    let seed = 0x00100001;\n    let temp1 = 0;\n    let temp2 = 0;\n\n    for (let index1 = 0; index1 < 0x100; index1++) {\n      for (let index2 = index1, i = 0; i < 5; i += 1, index2 += 0x100) {\n        seed = (seed * 125 + 3) % 0x2AAAAB;\n        temp1 = (seed & 0xFFFF) << 0x10;\n\n        seed = (seed * 125 + 3) % 0x2AAAAB;\n        temp2 = (seed & 0xFFFF);\n\n        this.cryptTable[index2] = temp1 | temp2;\n      }\n    }\n  }\n\n  hash(name: string, key: number): number {\n    const cryptTable = this.cryptTable;\n    let seed1 = 0x7FED7FED;\n    let seed2 = 0xEEEEEEEE;\n\n    name = name.toUpperCase();\n\n    for (let i = 0; i < name.length; i++) {\n      const ch = name.charCodeAt(i);\n\n      seed1 = cryptTable[(key << 8) + ch] ^ (seed1 + seed2);\n      seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;\n    }\n\n    // Convert the seed to an unsigned integer\n    return seed1 >>> 0;\n  }\n\n  decryptBlock<T extends Uint8Array | Uint32Array>(data: T, key: number): T {\n    const cryptTable = this.cryptTable;\n    let seed = 0xEEEEEEEE;\n    const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\n    for (let i = 0, l = data.byteLength >>> 2; i < l; i++) {\n      // Update the seed.\n      seed += cryptTable[0x400 + (key & 0xFF)];\n\n      // Get 4 encrypted bytes.\n      bytesHeap[0] = bytes[i * 4];\n      bytesHeap[1] = bytes[i * 4 + 1];\n      bytesHeap[2] = bytes[i * 4 + 2];\n      bytesHeap[3] = bytes[i * 4 + 3];\n\n      // Decrypted 32bit integer.\n      longHeap[0] ^= (key + seed);\n\n      // Update the seed.\n      key = ((~key << 0x15) + 0x11111111) | (key >>> 0x0B);\n      seed = longHeap[0] + seed + (seed << 5) + 3;\n\n      // Set 4 decryped bytes.\n      bytes[i * 4] = bytesHeap[0];\n      bytes[i * 4 + 1] = bytesHeap[1];\n      bytes[i * 4 + 2] = bytesHeap[2];\n      bytes[i * 4 + 3] = bytesHeap[3];\n    }\n\n    return data;\n  }\n\n  encryptBlock<T extends Uint8Array | Uint32Array>(data: T, key: number): T {\n    const cryptTable = this.cryptTable;\n    let seed = 0xEEEEEEEE;\n    const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\n    for (let i = 0, l = data.byteLength >>> 2; i < l; i++) {\n      // Update the seed.\n      seed += cryptTable[0x400 + (key & 0xFF)];\n\n      // Get 4 decrypted bytes.\n      bytesHeap[0] = bytes[i * 4];\n      bytesHeap[1] = bytes[i * 4 + 1];\n      bytesHeap[2] = bytes[i * 4 + 2];\n      bytesHeap[3] = bytes[i * 4 + 3];\n\n      // Decrypted 32bit integer.\n      const decrypted = longHeap[0];\n\n      // Encrypted 32bit integer.\n      longHeap[0] ^= (key + seed);\n\n      // Update the seed.\n      key = ((~key << 0x15) + 0x11111111) | (key >>> 0x0B);\n      seed = decrypted + seed + (seed << 5) + 3;\n\n      // Set 4 encrypted bytes.\n      bytes[i * 4] = bytesHeap[0];\n      bytes[i * 4 + 1] = bytesHeap[1];\n      bytes[i * 4 + 2] = bytesHeap[2];\n      bytes[i * 4 + 3] = bytesHeap[3];\n    }\n\n    return data;\n  }\n\n  computeFileKey(name: string, block: MpqBlock): number {\n    const sepIndex = name.lastIndexOf('\\\\');\n    const pathlessName = name.substring(sepIndex + 1);\n    let encryptionKey = this.hash(pathlessName, HASH_FILE_KEY);\n\n    if (block.flags & FILE_OFFSET_ADJUSTED_KEY) {\n      encryptionKey = (encryptionKey + block.offset) ^ block.normalSize;\n    }\n\n    return encryptionKey;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/explode.ts",
    "content": "// A near direct copy of Ladislav Zezula's C implementation.\n// I left the comments out - if you wish to understand the algorithm, please check the C implementation at https://github.com/ladislav-zezula/StormLib/tree/master/src/pklib\n//\n// There are three key differences:\n//   1) It takes in a Uint8Array, and returns a Uint8Array, rather than using abstract read/write functions.\n//   2) The tables are generated once the first time explode() is used.\n//      I am not sure why the C implementation copies all of the data and regenerates the tables on every explode().\n//      Further more, I am not sure why they are generated at all, unlike the rest of data.\n//   3) There is no output circle buffer, the output is a normal JS number array that grows as it will, wrapped at the end with a Uint8Array.\n//      It's simple, and I don't think anything else will perform better in JS either way.\n\nconst CMP_BINARY = 0;\nconst CMP_ASCII = 1;\n\nclass TDcmpStruct {\n  ctype = 0;\n  outputPos = 0;\n  dsize_bits = 0;\n  dsize_mask = 0;\n  bit_buff = 0;\n  extra_bits = 0;\n  in_pos = 0;\n  in_buff: Uint8Array;\n  out_buff: number[] = [];\n\n  constructor(in_buff: Uint8Array) {\n    this.in_buff = in_buff;\n  }\n}\n\nconst PKDCL_OK = 0;\nconst PKDCL_STREAM_END = 1;\n\nconst DistBits = new Uint8Array([\n  0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,\n  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,\n  0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,\n  0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,\n]);\n\nconst DistCode = new Uint8Array([\n  0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,\n  0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,\n  0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,\n  0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00,\n]);\n\nconst ExLenBits = new Uint8Array([\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,\n]);\n\nconst LenBase = new Uint16Array([\n  0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,\n  0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106,\n]);\n\nconst LenBits = new Uint8Array([\n  0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07,\n]);\n\nconst LenCode = new Uint8Array([\n  0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00,\n]);\n\nconst ChBitsAsc = new Uint8Array([\n  0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,\n  0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n  0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,\n  0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,\n  0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,\n  0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,\n  0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,\n  0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,\n  0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,\n  0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,\n  0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,\n  0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n  0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n  0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n  0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,\n  0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,\n]);\n\nconst ChCodeAsc = new Uint16Array([\n  0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,\n  0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,\n  0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,\n  0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,\n  0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,\n  0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,\n  0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,\n  0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,\n  0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,\n  0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,\n  0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,\n  0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,\n  0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,\n  0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,\n  0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,\n  0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,\n  0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,\n  0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,\n  0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,\n  0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,\n  0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,\n  0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,\n  0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,\n  0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,\n  0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,\n  0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,\n  0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,\n  0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,\n  0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,\n  0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,\n  0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,\n  0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000,\n]);\n\n// Generated on the first time explode() is used.\nlet generatedDecodeTabs = false;\nconst DistPosCodes = new Uint8Array(0x100);\nconst LengthCodes = new Uint8Array(0x100);\n\n// Same as above.\nlet generatedAscTabs = false;\nconst offs2C34 = new Uint8Array(0x100);\nconst offs2D34 = new Uint8Array(0x100);\nconst offs2E34 = new Uint8Array(0x80);\nconst offs2EB4 = new Uint8Array(0x100);\n\nfunction GenDecodeTabs(positions: Uint8Array, start_indexes: Uint8Array, length_bits: Uint8Array): void {\n  for (let i = 0, elements = start_indexes.length; i < elements; i++) {\n    const length = 1 << length_bits[i];\n\n    for (let index = start_indexes[i]; index < 0x100; index += length) {\n      positions[index] = i;\n    }\n  }\n}\n\nfunction GenAscTabs(): void {\n  let pChCodeAsc = 0xFF;\n  let acc, add;\n\n  for (let count = 0x00FF; pChCodeAsc >= 0; pChCodeAsc--, count--) {\n    const pChBitsAsc = count;\n    let bits_asc = ChBitsAsc[pChBitsAsc];\n\n    if (bits_asc <= 8) {\n      add = (1 << bits_asc);\n      acc = ChCodeAsc[pChCodeAsc];\n\n      do {\n        offs2C34[acc] = count;\n        acc += add;\n      } while (acc < 0x100);\n    } else if ((acc = (ChCodeAsc[pChCodeAsc] & 0xFF)) != 0) {\n      offs2C34[acc] = 0xFF;\n\n      if (ChCodeAsc[pChCodeAsc] & 0x3F) {\n        bits_asc -= 4;\n        ChBitsAsc[pChBitsAsc] = bits_asc;\n\n        add = (1 << bits_asc);\n        acc = ChCodeAsc[pChCodeAsc] >> 4;\n\n        do {\n          offs2D34[acc] = count;\n          acc += add;\n        } while (acc < 0x100);\n      } else {\n        bits_asc -= 6;\n        ChBitsAsc[pChBitsAsc] = bits_asc;\n\n        add = (1 << bits_asc);\n        acc = ChCodeAsc[pChCodeAsc] >> 6;\n\n        do {\n          offs2E34[acc] = count;\n          acc += add;\n        } while (acc < 0x80);\n      }\n    } else {\n      bits_asc -= 8;\n      ChBitsAsc[pChBitsAsc] = bits_asc;\n\n      add = (1 << bits_asc);\n      acc = ChCodeAsc[pChCodeAsc] >> 8;\n\n      do {\n        offs2EB4[acc] = count;\n        acc += add;\n      } while (acc < 0x100);\n    }\n  }\n}\n\nfunction WasteBits(pWork: TDcmpStruct, nBits: number): number {\n  if (nBits <= pWork.extra_bits) {\n    pWork.extra_bits -= nBits;\n    pWork.bit_buff >>= nBits;\n\n    return PKDCL_OK;\n  }\n\n  pWork.bit_buff >>= pWork.extra_bits;\n\n  if (pWork.in_pos === pWork.in_buff.byteLength) {\n    return PKDCL_STREAM_END;\n  }\n\n  pWork.bit_buff |= (pWork.in_buff[pWork.in_pos++] << 8);\n  pWork.bit_buff >>= (nBits - pWork.extra_bits);\n  pWork.extra_bits = (pWork.extra_bits - nBits) + 8;\n\n  return PKDCL_OK;\n}\n\nfunction DecodeLit(pWork: TDcmpStruct): number {\n  if (pWork.bit_buff & 1) {\n    if (WasteBits(pWork, 1)) {\n      return 0x306;\n    }\n\n    let length_code = LengthCodes[pWork.bit_buff & 0xFF];\n\n    if (WasteBits(pWork, LenBits[length_code])) {\n      return 0x306;\n    }\n\n    let extra_length_bits;\n\n    if ((extra_length_bits = ExLenBits[length_code]) != 0) {\n      const extra_length = pWork.bit_buff & ((1 << extra_length_bits) - 1);\n\n      if (WasteBits(pWork, extra_length_bits)) {\n        if ((length_code + extra_length) != 0x10E) {\n          return 0x306;\n        }\n      }\n\n      length_code = LenBase[length_code] + extra_length;\n    }\n\n    return length_code + 0x100;\n  }\n\n  if (WasteBits(pWork, 1)) {\n    return 0x306;\n  }\n\n  if (pWork.ctype == CMP_BINARY) {\n    const uncompressed_byte = pWork.bit_buff & 0xFF;\n\n    if (WasteBits(pWork, 8)) {\n      return 0x306;\n    }\n\n    return uncompressed_byte;\n  }\n\n  let value;\n\n  if (pWork.bit_buff & 0xFF) {\n    value = offs2C34[pWork.bit_buff & 0xFF];\n\n    if (value == 0xFF) {\n      if (pWork.bit_buff & 0x3F) {\n        if (WasteBits(pWork, 4)) {\n          return 0x306;\n        }\n\n        value = offs2D34[pWork.bit_buff & 0xFF];\n      } else {\n        if (WasteBits(pWork, 6)) {\n          return 0x306;\n        }\n\n        value = offs2E34[pWork.bit_buff & 0x7F];\n      }\n    }\n  } else {\n    if (WasteBits(pWork, 8)) {\n      return 0x306;\n    }\n\n    value = offs2EB4[pWork.bit_buff & 0xFF];\n  }\n\n  return WasteBits(pWork, ChBitsAsc[value]) ? 0x306 : value;\n}\n\nfunction DecodeDist(pWork: TDcmpStruct, rep_length: number): number {\n  const dist_pos_code = DistPosCodes[pWork.bit_buff & 0xFF];\n  const dist_pos_bits = DistBits[dist_pos_code];\n\n  if (WasteBits(pWork, dist_pos_bits)) {\n    return 0;\n  }\n\n  let distance;\n\n  if (rep_length == 2) {\n    distance = (dist_pos_code << 2) | (pWork.bit_buff & 0x03);\n\n    if (WasteBits(pWork, 2)) {\n      return 0;\n    }\n  } else {\n    distance = (dist_pos_code << pWork.dsize_bits) | (pWork.bit_buff & pWork.dsize_mask);\n\n    if (WasteBits(pWork, pWork.dsize_bits)) {\n      return 0;\n    }\n  }\n\n  return distance + 1;\n}\n\nfunction Expand(pWork: TDcmpStruct): number {\n  let next_literal;\n\n  while ((next_literal = DecodeLit(pWork)) < 0x305) {\n    if (next_literal >= 0x100) {\n      let rep_length = next_literal - 0xFE;\n      let minus_dist;\n\n      if ((minus_dist = DecodeDist(pWork, rep_length)) == 0) {\n        return 0x306;\n      }\n\n      let target = pWork.outputPos;\n      let source = target - minus_dist;\n\n      pWork.outputPos += rep_length;\n\n      while (rep_length-- > 0) {\n        pWork.out_buff[target++] = pWork.out_buff[source++];\n      }\n    } else {\n      pWork.out_buff[pWork.outputPos++] = next_literal;\n    }\n  }\n\n  return next_literal;\n}\n\nexport default function explode(bytes: Uint8Array): Uint8Array {\n  const pWork = new TDcmpStruct(bytes);\n\n  if (pWork.in_buff.byteLength <= 4) {\n    throw new Error('Bad data');\n  }\n\n  pWork.ctype = pWork.in_buff[0];\n  pWork.dsize_bits = pWork.in_buff[1];\n  pWork.bit_buff = pWork.in_buff[2];\n  pWork.extra_bits = 0;\n  pWork.in_pos = 3;\n\n  if (4 > pWork.dsize_bits || pWork.dsize_bits > 6) {\n    throw new Error('Invalid dictionary size');\n  }\n\n  pWork.dsize_mask = 0xFFFF >> (0x10 - pWork.dsize_bits);\n\n  if (pWork.ctype !== CMP_BINARY) {\n    if (pWork.ctype !== CMP_ASCII) {\n      throw new Error('Invalid mode');\n    }\n\n    if (!generatedAscTabs) {\n      GenAscTabs();\n\n      generatedAscTabs = true;\n    }\n  }\n\n  if (!generatedDecodeTabs) {\n    GenDecodeTabs(LengthCodes, LenCode, LenBits);\n    GenDecodeTabs(DistPosCodes, DistCode, DistBits);\n\n    generatedDecodeTabs = true;\n  }\n\n  if (Expand(pWork) === 0x306) {\n    throw new Error('Error while expanding');\n  }\n\n  return new Uint8Array(pWork.out_buff);\n}\n"
  },
  {
    "path": "src/parsers/mpq/file.ts",
    "content": "import { deflate, inflate } from 'pako';\nimport { decodeUtf8 } from '../../common/utf8';\nimport MpqArchive from './archive';\nimport MpqBlock from './block';\nimport { COMPRESSION_ADPCM_MONO, COMPRESSION_ADPCM_STEREO, COMPRESSION_BZIP2, COMPRESSION_DEFLATE, COMPRESSION_HUFFMAN, COMPRESSION_IMPLODE, FILE_COMPRESSED, FILE_ENCRYPTED, FILE_EXISTS, FILE_IMPLODE, FILE_OFFSET_ADJUSTED_KEY, FILE_SINGLE_UNIT, HASH_ENTRY_DELETED } from './constants';\nimport MpqCrypto from './crypto';\nimport explode from './explode';\n// import decodeHuffman from './huffman';\nimport MpqHash from './hash';\nimport { isArchive } from './isarchive';\n\n/**\n * A MPQ file.\n */\nexport default class MpqFile {\n  archive: MpqArchive;\n  c: MpqCrypto;\n  name: string;\n  nameResolved: boolean;\n  hash: MpqHash;\n  block: MpqBlock;\n  rawBuffer: Uint8Array | null = null;\n  buffer: Uint8Array | null = null;\n\n  constructor(archive: MpqArchive, hash: MpqHash, block: MpqBlock, rawBuffer: Uint8Array | null, buffer: Uint8Array | null) {\n    const headerOffset = archive.headerOffset;\n\n    this.archive = archive;\n    this.c = archive.c;\n    this.name = `File${`${hash.blockIndex}`.padStart(8, '0')}`;\n    this.nameResolved = false;\n    this.hash = hash;\n    this.block = block;\n\n    if (rawBuffer) {\n      this.rawBuffer = rawBuffer.slice(headerOffset + block.offset, headerOffset + block.offset + block.compressedSize);\n    }\n\n    if (buffer) {\n      this.buffer = buffer;\n    }\n  }\n\n  /**\n   * Gets this file's data as a Uint8Array.\n   * \n   * An exception will be thrown if the file needs to be decoded, and decoding fails.\n   */\n  bytes(): Uint8Array {\n    // Decode if needed\n    if (this.buffer === null) {\n      this.decode();\n    }\n\n    // If decoding failed, an exception would have been thrown, so buffer is known to exist at this point.\n    return <Uint8Array>this.buffer;\n  }\n\n  /**\n   * Gets this file's data as an ArrayBuffer.\n   * \n   * An exception will be thrown if the file needs to be decoded, and decoding fails.\n   */\n  arrayBuffer(): ArrayBuffer {\n    return this.bytes().buffer;\n  }\n\n  /**\n   * Gets this file's data as a UTF8 string.\n   * \n   * An exception will be thrown if the file needs to be decoded, and decoding fails.\n   */\n  text(): string {\n    return decodeUtf8(this.bytes());\n  }\n\n  /**\n   * Changes the buffer of this file.\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  set(buffer: Uint8Array): boolean {\n    if (this.archive.readonly) {\n      return false;\n    }\n\n    const hash = this.hash;\n    const block = this.block;\n\n    // Reset the hash.\n    hash.locale = 0;\n    hash.platform = 0;\n\n    // Reset the block.\n    block.compressedSize = 0;\n    block.normalSize = buffer.byteLength;\n    block.flags = 0;\n\n    this.buffer = buffer;\n    this.rawBuffer = null;\n\n    return true;\n  }\n\n  /**\n   * Deletes this file.\n   * \n   * Using the file after it was deleted will result in undefined behavior.\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  delete(): boolean {\n    if (this.archive.readonly) {\n      return false;\n    }\n\n    const archive = this.archive;\n    const hash = this.hash;\n    const blockIndex = hash.blockIndex;\n\n    hash.delete();\n\n    for (const hash of archive.hashTable.entries) {\n      if (hash.blockIndex < HASH_ENTRY_DELETED && hash.blockIndex > blockIndex) {\n        hash.blockIndex -= 1;\n      }\n    }\n\n    archive.blockTable.entries.splice(blockIndex, 1);\n    archive.files.splice(blockIndex, 1);\n\n    return true;\n  }\n\n  /**\n   * Renames this file.\n   * \n   * Note that this sets the current file's hash's status to being deleted, rather than removing it.\n   * This is due to the way the search algorithm works.\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  rename(newName: string): boolean {\n    if (this.archive.readonly) {\n      return false;\n    }\n\n    const hash = this.hash;\n    const locale = hash.locale;\n    const platform = hash.platform;\n    const blockIndex = hash.blockIndex;\n\n    // First delete the current hash.\n    // This will allow its entry to be reused in case it's the only empty/deleted entry in the hashtable.\n    hash.delete();\n\n    const newHash = <MpqHash>this.archive.hashTable.add(newName, blockIndex);\n\n    newHash.locale = locale;\n    newHash.platform = platform;\n\n    this.name = newName;\n    this.nameResolved = true;\n    this.hash = newHash;\n\n    return true;\n  }\n\n  /**\n   * Decode this file.\n   */\n  decode(): void {\n    if (!this.rawBuffer) {\n      throw new Error(`File ${this.name}: Nothing to decode`);\n    }\n\n    const archive = this.archive;\n    const block = this.block;\n    const c = archive.c;\n    const encryptionKey = c.computeFileKey(this.name, block);\n    const data = this.rawBuffer;\n    const flags = block.flags;\n\n    // One buffer of raw data.\n    // I don't know why having no flags means it's a chunk of memory rather than sectors.\n    // After all, there is no flag to say there are indeed sectors.\n    if (flags === FILE_EXISTS) {\n      this.buffer = data.slice(0, block.normalSize);\n    } else if (flags & FILE_SINGLE_UNIT) {\n      // One buffer of possibly encrypted and/or compressed data.\n      // Read the sector\n      let sector;\n\n      // If this block is encrypted, decrypt the sector.\n      if (flags & FILE_ENCRYPTED) {\n        sector = c.decryptBlock(data.slice(0, block.compressedSize), encryptionKey);\n      } else {\n        sector = data.subarray(0, block.compressedSize);\n      }\n\n      // If this block is compressed, decompress the sector.\n      // Otherwise, copy the sector as-is.\n      if (flags & FILE_COMPRESSED) {\n        sector = this.decompressSector(sector, block.normalSize);\n      } else {\n        sector = sector.slice();\n      }\n\n      this.buffer = sector;\n    } else {\n      // One or more sectors of possibly encrypted and/or compressed data.\n      const sectorCount = Math.ceil(block.normalSize / archive.sectorSize);\n\n      // Alocate a buffer for the uncompressed block size\n      const buffer = new Uint8Array(block.normalSize);\n\n      // Get the sector offsets\n      let sectorOffsets = new Uint32Array(data.buffer, 0, sectorCount + 1);\n\n      // If this file is encrypted, copy the sector offsets and decrypt them.\n      if (flags & FILE_ENCRYPTED) {\n        sectorOffsets = c.decryptBlock(sectorOffsets.slice(), encryptionKey - 1);\n      }\n\n      let start = sectorOffsets[0];\n      let end = sectorOffsets[1];\n      let offset = 0;\n\n      for (let i = 0; i < sectorCount; i++) {\n        let sector;\n\n        // If this file is encrypted, copy the sector and decrypt it.\n        // Otherwise a view can be used directly.\n        if (flags & FILE_ENCRYPTED) {\n          sector = c.decryptBlock(data.slice(start, end), encryptionKey + i);\n        } else {\n          sector = data.subarray(start, end);\n        }\n\n        // Decompress the sector\n        if (flags & FILE_COMPRESSED) {\n          let uncompressedSize = archive.sectorSize;\n\n          // If this is the last sector, its uncompressed size might not be the size of a sector.\n          if (block.normalSize - offset < uncompressedSize) {\n            uncompressedSize = block.normalSize - offset;\n          }\n\n          sector = this.decompressSector(sector, uncompressedSize);\n        }\n\n        // Some sectors have this flags instead of the compression flag + algorithm byte.\n        if (flags & FILE_IMPLODE) {\n          sector = explode(sector);\n        }\n\n        // Add the sector bytes to the buffer\n        buffer.set(sector, offset);\n        offset += sector.byteLength;\n\n        // Prepare for the next sector\n        if (i < sectorCount) {\n          start = end;\n          end = sectorOffsets[i + 2];\n        }\n      }\n\n      this.buffer = buffer;\n    }\n\n    // If the archive is in read-only mode, the raw buffer isn't needed anymore, so free the memory.\n    if (archive.readonly) {\n      this.rawBuffer = null;\n    }\n  }\n\n  decompressSector(bytes: Uint8Array, decompressedSize: number): Uint8Array {\n    // If the size of the data is the same as its decompressed size, it's not compressed.\n    if (bytes.byteLength === decompressedSize) {\n      return bytes;\n    } else {\n      const compressionMask = bytes[0];\n\n      if (compressionMask & COMPRESSION_BZIP2) {\n        throw new Error(`File ${this.name}: compression type 'bzip2' not supported`);\n      }\n\n      if (compressionMask & COMPRESSION_IMPLODE) {\n        try {\n          bytes = explode(bytes.subarray(1));\n        } catch (e) {\n          throw new Error(`File ${this.name}: failed to decompress with 'explode': ${e}`);\n        }\n      }\n\n      if (compressionMask & COMPRESSION_DEFLATE) {\n        try {\n          bytes = inflate(bytes.subarray(1));\n        } catch (e) {\n          throw new Error(`File ${this.name}: failed to decompress with 'zlib': ${e}`);\n        }\n      }\n\n      if (compressionMask & COMPRESSION_HUFFMAN) {\n        // try {\n        //   bytes = decodeHuffman(bytes.subarray(1));\n        // } catch (e) {\n        //   throw new Error(`File ${this.name}: failed to decompress with 'huffman': ${e}`);\n        // }\n        throw new Error(`File ${this.name}: compression type 'huffman' not supported`);\n      }\n\n      if (compressionMask & COMPRESSION_ADPCM_STEREO) {\n        throw new Error(`File ${this.name}: compression type 'adpcm stereo' not supported`);\n      }\n\n      if (compressionMask & COMPRESSION_ADPCM_MONO) {\n        throw new Error(`File ${this.name}: compression type 'adpcm mono' not supported`);\n      }\n\n      return bytes;\n    }\n  }\n\n  /**\n   * Encode this file.\n   * Archives (maps or generic MPQs) are stored uncompressed in one chunk.\n   * Other files are always stored in sectors, except when a file is smaller than a sector.\n   * Sectors themselves are always compressed, except when the result is smaller than the uncompressed data.\n   */\n  encode(): void {\n    if (this.buffer !== null && this.rawBuffer === null) {\n      const data = this.buffer;\n\n      if (isArchive(data)) {\n        this.rawBuffer = this.buffer;\n        this.block.compressedSize = this.buffer.byteLength;\n        this.block.flags = FILE_EXISTS;\n      } else {\n        const sectorSize = this.archive.sectorSize;\n        const sectorCount = Math.ceil(data.byteLength / sectorSize);\n        const offsets = new Uint32Array(sectorCount + 1);\n        let offset = offsets.byteLength;\n        const sectors = [];\n        const compression = [];\n\n        // First offset is right after the offsets list.\n        offsets[0] = offset;\n\n        for (let i = 0; i < sectorCount; i++) {\n          const sectorOffset = i * sectorSize;\n          let sector = data.subarray(sectorOffset, sectorOffset + sectorSize);\n          let size = sector.byteLength;\n          const compressed = deflate(sector);\n          let isCompressed = false;\n\n          // If the compressed size of the sector is smaller than the uncompressed, use the compressed data.\n          // +1 because of the compression mask byte.\n          if (compressed.byteLength + 1 < size) {\n            sector = compressed;\n            size = compressed.byteLength + 1;\n            isCompressed = true;\n          }\n\n          offset += size;\n          offsets[i + 1] = offset;\n          sectors[i] = sector;\n          compression[i] = isCompressed;\n        }\n\n        // Only use the compressed data if it's actually smaller than the uncompressed data.\n        if (offset < data.byteLength) {\n          const rawBuffer = new Uint8Array(offset);\n\n          // Write the offsets list.\n          rawBuffer.set(new Uint8Array(offsets.buffer));\n\n          offset = offsets.byteLength;\n\n          for (let i = 0; i < sectorCount; i++) {\n            // If this sector is compressed, set it to zlib.\n            if (compression[i]) {\n              rawBuffer[offset] = 2;\n              offset += 1;\n            }\n\n            // Write the sector.\n            const sector = sectors[i];\n\n            rawBuffer.set(sector, offset);\n            offset += sector.byteLength;\n          }\n\n          this.rawBuffer = rawBuffer;\n          this.block.compressedSize = rawBuffer.byteLength;\n          this.block.flags = (FILE_EXISTS | FILE_COMPRESSED) >>> 0;\n        } else {\n          this.rawBuffer = this.buffer;\n          this.block.compressedSize = this.buffer.byteLength;\n          this.block.flags = FILE_EXISTS;\n        }\n      }\n    }\n  }\n\n  /**\n   * Decrypt this file and encrypt it back, with a new offset in the archive.\n   * This is used for files that use FILE_OFFSET_ADJUSTED_KEY, which are encrypted with a key that depends on their offset.\n   */\n  reEncrypt(offset: number): boolean {\n    if (!this.rawBuffer) {\n      return false;\n    }\n\n    const archive = this.archive;\n    const block = this.block;\n    const c = archive.c;\n    const bytes = this.rawBuffer;\n    const flags = block.flags;\n    const encryptionKey = c.computeFileKey(this.name, block);\n\n    block.offset = offset;\n\n    const newEncryptionKey = c.computeFileKey(this.name, block);\n\n    if (flags & FILE_SINGLE_UNIT) {\n      // Decrypt the chunk with the old key.\n      c.decryptBlock(bytes, encryptionKey);\n\n      // Encrypt the chunk with the new key.\n      c.encryptBlock(bytes, newEncryptionKey);\n    } else {\n      const sectorCount = Math.ceil(block.normalSize / archive.sectorSize);\n\n      // Get the sector offsets\n      const sectorOffsets = new Uint32Array(bytes.buffer, 0, sectorCount + 1);\n\n      // Decrypt the sector offsets with the old key.\n      c.decryptBlock(sectorOffsets, encryptionKey - 1);\n\n      let start = sectorOffsets[0];\n      let end = sectorOffsets[1];\n\n      for (let i = 0; i < sectorCount; i++) {\n        const sector = bytes.subarray(start, end);\n\n        // Decrypt the chunk with the old key.\n        c.decryptBlock(sector, encryptionKey + i);\n\n        // Encrypt the chunk with the new key.\n        c.encryptBlock(sector, newEncryptionKey + i);\n\n        // Prepare for the next sector\n        if (i < sectorCount) {\n          start = end;\n          end = sectorOffsets[i + 2];\n        }\n      }\n\n      // Encrypt the sector offsets with the new key.\n      c.encryptBlock(sectorOffsets, newEncryptionKey - 1);\n    }\n\n    return true;\n  }\n\n  /**\n   * The offset of the file has been recalculated.\n   * If the offset is different, and this file uses FILE_OFFSET_ADJUSTED_KEY encryption, it must be re-encrypted with the new offset.\n   */\n  offsetChanged(offset: number): boolean {\n    const block = this.block;\n\n    if (block.offset !== offset && block.flags & FILE_OFFSET_ADJUSTED_KEY) {\n      if (this.nameResolved) {\n        return this.reEncrypt(offset);\n      }\n\n      return false;\n    }\n\n    block.offset = offset;\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/hash.ts",
    "content": "import { HASH_ENTRY_DELETED, HASH_ENTRY_EMPTY } from './constants';\n\n/**\n * A MPQ hash.\n */\nexport default class MpqHash {\n  nameA = 0xFFFFFFFF;\n  nameB = 0xFFFFFFFF;\n  locale = 0xFFFF;\n  platform = 0xFFFF;\n  blockIndex = HASH_ENTRY_EMPTY;\n\n  load(bytes: Uint32Array): void {\n    const localePlatform = bytes[2];\n\n    this.nameA = bytes[0];\n    this.nameB = bytes[1];\n    this.locale = localePlatform & 0x0000FFFF;\n    this.platform = localePlatform >>> 16;\n    this.blockIndex = bytes[3];\n  }\n\n  copy(hash: MpqHash): void {\n    this.nameA = hash.nameA;\n    this.nameB = hash.nameB;\n    this.locale = hash.locale;\n    this.platform = hash.platform;\n    this.blockIndex = hash.blockIndex;\n  }\n\n  save(bytes: Uint32Array): void {\n    bytes[0] = this.nameA;\n    bytes[1] = this.nameB;\n    bytes[2] = (this.locale << 16) | this.platform;\n    bytes[3] = this.blockIndex;\n  }\n\n  delete(): void {\n    this.nameA = 0xFFFFFFFF;\n    this.nameB = 0xFFFFFFFF;\n    this.locale = 0xFFFF;\n    this.platform = 0xFFFF;\n    this.blockIndex = HASH_ENTRY_DELETED;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/hashtable.ts",
    "content": "import MpqCrypto from './crypto';\nimport MpqHash from './hash';\nimport { HASH_TABLE_KEY, HASH_TABLE_INDEX, HASH_NAME_A, HASH_NAME_B } from './constants';\n\n/**\n * A MPQ hash table.\n */\nexport default class MpqHashTable {\n  c: MpqCrypto;\n  entries: MpqHash[];\n\n  constructor(c: MpqCrypto) {\n    this.c = c;\n    this.entries = [];\n\n    // Minimum size\n    this.addEmpties(4);\n  }\n\n  clear(): void {\n    this.entries.length = 0;\n  }\n\n  addEmpties(howMany: number): void {\n    for (let i = 0; i < howMany; i++) {\n      this.entries.push(new MpqHash());\n    }\n  }\n\n  getInsertionIndex(name: string): number {\n    const entries = this.entries;\n    const offset = this.c.hash(name, HASH_TABLE_INDEX) & (entries.length - 1);\n\n    for (let i = 0, l = entries.length; i < l; i++) {\n      const index = (i + offset) % l;\n      const hash = entries[index];\n\n      if (hash.platform === 0xFFFF) {\n        return index;\n      }\n    }\n\n    return -1;\n  }\n\n  add(name: string, blockIndex: number): MpqHash | undefined {\n    const insertionIndex = this.getInsertionIndex(name);\n\n    if (insertionIndex !== -1) {\n      const hash = this.entries[insertionIndex];\n\n      hash.nameA = this.c.hash(name, HASH_NAME_A);\n      hash.nameB = this.c.hash(name, HASH_NAME_B);\n      hash.locale = 0;\n      hash.platform = 0;\n      hash.blockIndex = blockIndex;\n\n      return hash;\n    }\n\n    return;\n  }\n\n  load(bytes: Uint8Array): void {\n    const entriesCount = bytes.byteLength / 16;\n    const uint32array = new Uint32Array(this.c.decryptBlock(bytes, HASH_TABLE_KEY).buffer);\n    let offset = 0;\n\n    // Clear the table and add the needed empties.\n    this.clear();\n    this.addEmpties(entriesCount);\n\n    for (const hash of this.entries) {\n      hash.load(uint32array.subarray(offset, offset + 4));\n\n      offset += 4;\n    }\n  }\n\n  save(bytes: Uint8Array): void {\n    const uint32array = new Uint32Array(this.entries.length * 4);\n    let offset = 0;\n\n    for (const hash of this.entries) {\n      hash.save(uint32array.subarray(offset, offset + 4));\n\n      offset += 4;\n    }\n\n    const uint8array = new Uint8Array(uint32array.buffer);\n\n    this.c.encryptBlock(uint8array, HASH_TABLE_KEY);\n\n    bytes.set(uint8array);\n  }\n\n  get(name: string): MpqHash | null {\n    const c = this.c;\n    const entries = this.entries;\n    const offset = c.hash(name, HASH_TABLE_INDEX) & (entries.length - 1);\n    const nameA = c.hash(name, HASH_NAME_A);\n    const nameB = c.hash(name, HASH_NAME_B);\n\n    for (let i = 0, l = entries.length; i < l; i++) {\n      const hash = entries[(i + offset) % l];\n\n      if (nameA === hash.nameA && nameB === hash.nameB) {\n        return hash;\n      } else if (hash.blockIndex === 0xFFFFFFFF) {\n        return null;\n      }\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "src/parsers/mpq/index.ts",
    "content": "import Archive from './archive';\nimport Crypto from './crypto';\nimport HashTable from './hashtable';\nimport Hash from './hash';\nimport BlockTable from './blocktable';\nimport Block from './block';\nimport File from './file';\nimport { isArchive } from './isarchive';\n\nexport default {\n  Archive,\n  Crypto,\n  HashTable,\n  Hash,\n  BlockTable,\n  Block,\n  File,\n  isArchive,\n};\n"
  },
  {
    "path": "src/parsers/mpq/isarchive.ts",
    "content": "/**\n * Search for the MPQ header - MPQ\\x1A.\n * The header can be on any 512 bytes boundry offset.\n */\nexport function searchHeader(bytes: Uint8Array): number {\n  let offset = -1;\n\n  for (let i = 0, l = Math.ceil(bytes.byteLength / 512); i < l; i++) {\n    const base = i * 512;\n\n    // Test 'MPQ\\x1A'.\n    if (bytes[base] === 77 && bytes[base + 1] === 80 && bytes[base + 2] === 81 && bytes[base + 3] === 26) {\n      offset = base;\n    }\n  }\n\n  return offset;\n}\n\n/**\n * Checks whether the given buffer is either a Warcraft 3 map or otherwise a generic MPQ archive.\n */\nexport function isArchive(bytes: Uint8Array): boolean {\n  // Check for the map identifier - HM3W\n  if (bytes[0] === 72 && bytes[1] === 77 && bytes[2] === 51 && bytes[3] === 87) {\n    return true;\n  }\n\n  // Look for an MPQ header.\n  return searchHeader(bytes) !== -1;\n}\n"
  },
  {
    "path": "src/parsers/slk/file.ts",
    "content": "/**\n * A SLK table file.\n */\nexport default class SlkFile {\n  rows: string[][] = [];\n\n  load(buffer: string): void {\n    if (!buffer.startsWith('ID')) {\n      throw new Error('WrongMagicNumber');\n    }\n\n    const rows = this.rows;\n    let x = 0;\n    let y = 0;\n\n    for (const line of buffer.split('\\n')) {\n      // The B command is supposed to define the total number of columns and rows, however in UbetSplatData.slk it gives wrong information\n      // Therefore, just ignore it, since JavaScript arrays grow as they want either way\n      if (line[0] !== 'B') {\n        for (const token of line.split(';')) {\n          const op = token[0];\n          const valueString = token.substring(1).trim();\n          let value;\n\n          if (op === 'X') {\n            x = parseInt(valueString, 10) - 1;\n          } else if (op === 'Y') {\n            y = parseInt(valueString, 10) - 1;\n          } else if (op === 'K') {\n            if (!rows[y]) {\n              rows[y] = [];\n            }\n\n            if (valueString[0] === '\"') {\n              value = valueString.slice(1, -1);\n            } else {\n              value = valueString;\n            }\n\n            rows[y][x] = value;\n          }\n        }\n      }\n    }\n  }\n\n  save(): string {\n    const rows = this.rows;\n    const rowCount = rows.length;\n    const lines = [];\n    let biggestColumn = 0;\n\n    for (let y = 0; y < rowCount; y++) {\n      const row = rows[y];\n      const columnCount = row.length;\n\n      if (columnCount > biggestColumn) {\n        biggestColumn = columnCount;\n      }\n\n      let firstOfRow = true;\n\n      for (let x = 0; x < columnCount; x++) {\n        const value = row[x];\n\n        if (value !== undefined) {\n          let encoded;\n\n          if (typeof value === 'string') {\n            encoded = `\"${value}\"`;\n          } else if (typeof value === 'boolean') {\n            if (value) {\n              encoded = 'TRUE';\n            } else {\n              encoded = 'FALSE';\n            }\n          } else {\n            encoded = `${value}`;\n          }\n\n          if (firstOfRow) {\n            firstOfRow = false;\n\n            lines.push(`C;X${x + 1};Y${y + 1};K${encoded}`);\n          } else {\n            lines.push(`C;X${x + 1};K${encoded}`);\n          }\n        }\n      }\n    }\n\n    return `ID;P\\r\\nB;X${biggestColumn};Y${rowCount}\\r\\n${lines.join('\\r\\n')}\\r\\nE`;\n  }\n}\n"
  },
  {
    "path": "src/parsers/slk/index.ts",
    "content": "import File from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/parsers/tga/image.ts",
    "content": "import TgaLoader from 'tga-js';\nimport { bytesOf } from '../../common/bytesof';\n\n/**\n * A TGA image.\n */\nexport default class TgaImage {\n  width = 0;\n  height = 0;\n  data: ImageData | null = null;\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const bytes = bytesOf(buffer);\n    const tga = new TgaLoader();\n\n    tga.load(bytes);\n\n    const header = tga.header;\n\n    this.width = header.width;\n    this.height = header.height;\n    this.data = new ImageData(header.width, header.height);\n\n    tga.getImageData(this.data);\n  }\n}\n"
  },
  {
    "path": "src/parsers/tga/index.ts",
    "content": "import Image from './image';\nimport isTga from './isformat';\n\nexport default {\n  Image,\n  isTga,\n};\n"
  },
  {
    "path": "src/parsers/tga/isformat.ts",
    "content": "import { isStringInBytes } from '../../common/searches';\n\n/**\n * Detects if the given object is a TGA source.\n */\nexport default function isTga(bytes: unknown): boolean {\n  if (bytes instanceof ArrayBuffer) {\n    bytes = new Uint8Array(bytes);\n  }\n\n  if (bytes instanceof Uint8Array && isStringInBytes(bytes, 'TRUEVISION-XFILE.\\0', bytes.length - 18)) {\n    return true;\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/parsers/w3x/doo/doodad.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport RandomItemSet from './randomitemset';\n\n/**\n * A doodad.\n */\nexport default class Doodad {\n  id = '\\0\\0\\0\\0';\n  variation = 0;\n  location = new Float32Array(3);\n  angle = 0;\n  scale = new Float32Array([1, 1, 1]);\n  /**\n   * @since Game version 1.32\n   */\n  skin = '\\0\\0\\0\\0';\n  flags = 0;\n  life = 0;\n  itemTable = -1;\n  itemSets: RandomItemSet[] = [];\n  editorId = 0;\n  u1 = new Uint8Array(8);\n\n  load(stream: BinaryStream, version: number, buildVersion: number): void {\n    this.id = stream.readBinary(4);\n    this.variation = stream.readInt32();\n    stream.readFloat32Array(this.location);\n    this.angle = stream.readFloat32();\n    stream.readFloat32Array(this.scale);\n\n    if (buildVersion > 131) {\n      this.skin = stream.readBinary(4);\n    }\n\n    this.flags = stream.readUint8();\n    this.life = stream.readUint8();\n\n    if (version > 7) {\n      this.itemTable = stream.readUint32();\n\n      for (let i = 0, l = stream.readUint32(); i < l; i++) {\n        const itemSet = new RandomItemSet();\n\n        itemSet.load(stream);\n\n        this.itemSets.push(itemSet);\n      }\n    }\n\n    this.editorId = stream.readInt32();\n  }\n\n  save(stream: BinaryStream, version: number, buildVersion: number): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.variation);\n    stream.writeFloat32Array(this.location);\n    stream.writeFloat32(this.angle);\n    stream.writeFloat32Array(this.scale);\n\n    if (buildVersion > 131) {\n      stream.writeBinary(this.skin);\n    }\n\n    stream.writeUint8(this.flags);\n    stream.writeUint8(this.life);\n\n    if (version > 7) {\n      stream.writeUint32(this.itemTable);\n      stream.writeUint32(this.itemSets.length);\n\n      for (const itemSet of this.itemSets) {\n        itemSet.save(stream);\n      }\n    }\n\n    stream.writeInt32(this.editorId);\n  }\n\n  getByteLength(version: number, buildVersion: number): number {\n    let size = 42;\n\n    if (buildVersion > 131) {\n      size += 4;\n    }\n\n    if (version > 7) {\n      size += 8;\n\n      for (const itemSet of this.itemSets) {\n        size += itemSet.getByteLength();\n      }\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/doo/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Doodad from './doodad';\nimport TerrainDoodad from './terraindoodad';\n\n/**\n * war3map.doo - the doodad and destructible file.\n */\nexport default class War3MapDoo {\n  version = 0;\n  u1 = new Uint8Array(4);\n  doodads: Doodad[] = [];\n  u2 = new Uint8Array(4);\n  terrainDoodads: TerrainDoodad[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array, buildVersion: number): void {\n    const stream = new BinaryStream(buffer);\n\n    if (stream.readBinary(4) !== 'W3do') {\n      throw new Error('Not a valid war3map.doo buffer');\n    }\n\n    this.version = stream.readInt32();\n    stream.readUint8Array(this.u1);\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const doodad = new Doodad();\n\n      doodad.load(stream, this.version, buildVersion);\n\n      this.doodads.push(doodad);\n    }\n\n    stream.readUint8Array(this.u2);\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const terrainDoodad = new TerrainDoodad();\n\n      terrainDoodad.load(stream, this.version);\n\n      this.terrainDoodads.push(terrainDoodad);\n    }\n  }\n\n  save(buildVersion: number): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength(buildVersion)));\n\n    stream.writeBinary('W3do');\n    stream.writeInt32(this.version);\n    stream.writeUint8Array(this.u1);\n    stream.writeUint32(this.doodads.length);\n\n    for (const doodad of this.doodads) {\n      doodad.save(stream, this.version, buildVersion);\n    }\n\n    stream.writeUint8Array(this.u2);\n    stream.writeUint32(this.terrainDoodads.length);\n\n    for (const terrainDoodad of this.terrainDoodads) {\n      terrainDoodad.save(stream, this.version);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(buildVersion: number): number {\n    let size = 24 + this.terrainDoodads.length * 16;\n\n    for (const doodad of this.doodads) {\n      size += doodad.getByteLength(this.version, buildVersion);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/doo/index.ts",
    "content": "import File from './file';\nimport Doodad from './doodad';\nimport RandomItemSet from './randomitemset';\nimport RandomItem from './randomitem';\nimport TerrainDoodad from './terraindoodad';\n\nexport default {\n  File,\n  Doodad,\n  RandomItemSet,\n  RandomItem,\n  TerrainDoodad,\n};\n"
  },
  {
    "path": "src/parsers/w3x/doo/randomitem.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A random item.\n */\nexport default class RandomItem {\n  id = '\\0\\0\\0\\0';\n  chance = 0;\n\n  load(stream: BinaryStream): void {\n    this.id = stream.readBinary(4);\n    this.chance = stream.readInt32();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.chance);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/doo/randomitemset.ts",
    "content": "import RandomItem from './randomitem';\nimport BinaryStream from '../../../common/binarystream';\n\n/**\n * A random item set.\n */\nexport default class RandomItemSet {\n  items: RandomItem[] = [];\n\n  load(stream: BinaryStream): void {\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const item = new RandomItem();\n\n      item.load(stream);\n\n      this.items.push(item);\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeUint32(this.items.length);\n\n    for (const item of this.items) {\n      item.save(stream);\n    }\n  }\n\n  getByteLength(): number {\n    return 4 + this.items.length * 8;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/doo/terraindoodad.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A terrain doodad.\n *\n * This type of doodad works much like cliffs.\n * It uses the height of the terrain, and gets affected by the ground heightmap.\n * It cannot be manipulated in any way in the World Editor once placed.\n * Indeed, the only way to change it is to remove it by changing cliffs around it.\n */\nexport default class TerrainDoodad {\n  id = '\\0\\0\\0\\0';\n  u1 = 0;\n  location = new Uint32Array(2);\n\n  load(stream: BinaryStream, _version: number): void {\n    this.id = stream.readBinary(4);\n    this.u1 = stream.readUint32();\n    stream.readUint32Array(this.location);\n  }\n\n  save(stream: BinaryStream, _version: number): void {\n    stream.writeBinary(this.id);\n    stream.writeUint32(this.u1);\n    stream.writeUint32Array(this.location);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/imp/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Import from './import';\n\n/**\n * war3map.imp - the import file.\n */\nexport default class War3MapImp {\n  version = 1;\n  entries: Map<string, Import> = new Map();\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readUint32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const entry = new Import();\n\n      entry.load(stream);\n\n      if (entry.isCustom) {\n        this.entries.set(entry.path, entry);\n      } else {\n        this.entries.set(`war3mapimported\\\\${entry.path}`, entry);\n      }\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeUint32(this.version);\n    stream.writeUint32(this.entries.size);\n\n    for (const entry of this.entries.values()) {\n      entry.save(stream);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 8;\n\n    for (const entry of this.entries.values()) {\n      size += entry.getByteLength();\n    }\n\n    return size;\n  }\n\n  set(path: string): boolean {\n    if (!this.entries.has(path)) {\n      const entry = new Import();\n\n      entry.isCustom = 10;\n      entry.path = path;\n\n      this.entries.set(path, entry);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  has(path: string): boolean {\n    return this.entries.has(path);\n  }\n\n  delete(path: string): boolean {\n    return this.entries.delete(path);\n  }\n\n  rename(path: string, newPath: string): boolean {\n    const entry = this.entries.get(path);\n\n    if (entry) {\n      entry.isCustom = 10;\n      entry.path = newPath;\n\n      return true;\n    }\n\n    return false;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/imp/import.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * An import.\n */\nexport default class Import {\n  isCustom = 0;\n  path = '';\n\n  load(stream: BinaryStream): void {\n    this.isCustom = stream.readUint8();\n    this.path = stream.readNull();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeUint8(this.isCustom);\n    stream.writeNull(this.path);\n  }\n\n  getByteLength(): number {\n    return 2 + byteLengthUtf8(this.path);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/imp/index.ts",
    "content": "import File from './file';\nimport Import from './import';\n\nexport default {\n  File,\n  Import,\n};\n"
  },
  {
    "path": "src/parsers/w3x/index.ts",
    "content": "import Map from './map';\nimport doo from './doo';\nimport imp from './imp';\nimport mmp from './mmp';\nimport shd from './shd';\nimport w3c from './w3c';\nimport w3d from './w3d';\nimport w3e from './w3e';\nimport w3i from './w3i';\nimport w3o from './w3o';\nimport w3r from './w3r';\nimport w3s from './w3s';\nimport w3u from './w3u';\nimport wct from './wct';\nimport wpm from './wpm';\nimport wtg from './wtg';\nimport wts from './wts';\nimport unitsdoo from './unitsdoo';\nimport w3f from './w3f';\n\nexport default {\n  Map,\n  doo,\n  imp,\n  mmp,\n  shd,\n  w3c,\n  w3d,\n  w3e,\n  w3i,\n  w3o,\n  w3r,\n  w3s,\n  w3u,\n  wct,\n  wpm,\n  wtg,\n  wts,\n  unitsdoo,\n  w3f,\n};\n"
  },
  {
    "path": "src/parsers/w3x/map.ts",
    "content": "import BinaryStream from '../../common/binarystream';\nimport MpqArchive from '../mpq/archive';\nimport War3MapImp from './imp/file';\nimport War3MapW3d from './w3d/file';\nimport War3MapW3u from './w3u/file';\nimport War3MapWct from './wct/file';\nimport War3MapWtg from './wtg/file';\nimport War3MapWts from './wts/file';\nimport { TriggerData } from './wtg/triggerdata';\nimport War3MapW3i from './w3i/file';\nimport MpqFile from '../mpq/file';\n\ntype War3MapModificationNames = 'w3a' | 'w3b' | 'w3d' | 'w3h' | 'w3q' | 'w3t' | 'w3u';\n\ninterface War3MapModifications {\n  w3a?: War3MapW3d;\n  w3b?: War3MapW3u;\n  w3d?: War3MapW3d;\n  w3h?: War3MapW3u;\n  w3q?: War3MapW3d;\n  w3t?: War3MapW3u;\n  w3u?: War3MapW3u;\n}\n\n/**\n * Warcraft 3 map (W3X and W3M).\n */\nexport default class War3Map {\n  u1 = 0;\n  name = '';\n  flags = 0;\n  maxPlayers = 0;\n\n  archive = new MpqArchive();\n  imports = new War3MapImp();\n  readonly = false;\n\n  /**\n   * Load an existing map.\n   * \n   * Note that this clears the map from whatever it had in it before.\n   */\n  load(buffer: ArrayBuffer | Uint8Array, readonly = false): void {\n    const stream = new BinaryStream(buffer);\n\n    // The header no longer exists since some 1.3X.X patch?\n    if (stream.readBinary(4) === 'HM3W') {\n      this.u1 = stream.readUint32();\n      this.name = stream.readNull();\n      this.flags = stream.readUint32();\n      this.maxPlayers = stream.readUint32();\n    }\n\n    this.readonly = readonly;\n\n    // Read the archive.\n    this.archive.load(buffer, readonly);\n\n    // Read in the imports file if there is one.\n    this.readImports();\n  }\n\n  /**\n   * Save this map.\n   * If the archive is in readonly mode, returns null.\n   */\n  save(): Uint8Array {\n    // Update the imports if needed.\n    this.setImportsFile();\n\n    const archiveBuffer = this.archive.save();\n\n    if (!archiveBuffer) {\n      throw Error('Failed to save the map MPQ archive');\n    }\n\n    const information = this.getMapInformation();\n\n    // If this is a pre-1.31 map, or we don't know what the version is, save also the map header.\n    if (!information || information.getBuildVersion() < 131) {\n      const bytes = new Uint8Array(512 + archiveBuffer.byteLength);\n      const stream = new BinaryStream(bytes);\n\n      // Write the header.\n      stream.writeBinary('HM3W');\n      stream.writeUint32(this.u1);\n      stream.writeNull(this.name);\n      stream.writeUint32(this.flags);\n      stream.writeUint32(this.maxPlayers);\n\n      bytes.set(archiveBuffer, 512);\n\n      return bytes;\n    } else {\n      return archiveBuffer;\n    }\n  }\n\n  /**\n   * A shortcut to the internal archive function.\n   */\n  getFileNames(): string[] {\n    return this.archive.getFileNames();\n  }\n\n  /**\n   * Gets a list of the file names imported in this map.\n   */\n  getImportNames(): string[] {\n    const names = [];\n\n    for (const entry of this.imports.entries.values()) {\n      const isCustom = entry.isCustom;\n\n      if (isCustom === 10 || isCustom === 13) {\n        names.push(entry.path);\n      } else {\n        names.push(`war3mapImported\\\\${entry.path}`);\n      }\n    }\n\n    return names;\n  }\n\n  /**\n   * Sets the imports file with all of the imports.\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  setImportsFile(): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    if (this.imports.entries.size > 0) {\n      return this.set('war3map.imp', this.imports.save());\n    }\n\n    return false;\n  }\n\n  /**\n   * Imports a file to this archive.\n   * \n   * If the file already exists, its buffer will be set.\n   * \n   * Files added to the archive but not to the imports list will be deleted by the World Editor automatically.\n   * This of course doesn't apply to internal map files.\n   * \n   * Does nothing if the archive is in readonly mode.\n   */\n  import(name: string, buffer: ArrayBuffer | string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    if (this.archive.set(name, buffer)) {\n      this.imports.set(name);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * A shortcut to the internal archive function.\n   */\n  set(name: string, buffer: ArrayBuffer | string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    return this.archive.set(name, buffer);\n  }\n\n  /**\n   * A shortcut to the internal archive function.\n   */\n  get(name: string): MpqFile | null {\n    return this.archive.get(name);\n  }\n\n  /**\n   * Get the map's script.\n   */\n  getScriptFile(): MpqFile | null {\n    return this.get('war3map.j') || this.get('scripts\\\\war3map.j') || this.get('war3map.lua') || this.get('scripts\\\\war3map.lua');\n  }\n\n  /**\n   * A shortcut to the internal archive function.\n   */\n  has(name: string): boolean {\n    return this.archive.has(name);\n  }\n\n  /**\n   * Deletes a file from the internal archive.\n   * \n   * Note that if the file is in the imports list, it will be removed from it too.\n   * \n   * Use this rather than the internal archive's delete.\n   */\n  delete(name: string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    // If this file is in the import list, remove it.\n    this.imports.delete(name);\n\n    return this.archive.delete(name);\n  }\n\n  /**\n   * A shortcut to the internal archive function.\n   */\n  rename(name: string, newName: string): boolean {\n    if (this.readonly) {\n      return false;\n    }\n\n    if (this.archive.rename(name, newName)) {\n      // If the file was actually renamed, and it is an import, rename also the import entry.\n      this.imports.rename(name, newName);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  getMapInformation(): War3MapW3i {\n    const file = this.archive.get('war3map.w3i');\n\n    if (!file) {\n      throw new Error('File does not exist');\n    }\n\n    const parser = new War3MapW3i();\n\n    parser.load(file.bytes());\n\n    return parser;\n  }\n\n  readImports(): void {\n    const file = this.archive.get('war3map.imp');\n\n    if (file) {\n      const buffer = file.arrayBuffer();\n\n      if (buffer) {\n        this.imports.load(buffer);\n      }\n    }\n  }\n\n  readTriggers(triggerData: TriggerData): War3MapWtg | undefined {\n    const file = this.archive.get('war3map.wtg');\n\n    if (file) {\n      const buffer = file.arrayBuffer();\n\n      if (buffer) {\n        const object = new War3MapWtg();\n\n        object.load(buffer, triggerData);\n\n        return object;\n      }\n    }\n\n    return;\n  }\n\n  /**\n   * Read and parse the custom text trigger file.\n   */\n  readCustomTextTriggers(): War3MapWct | undefined {\n    const file = this.archive.get('war3map.wct');\n\n    if (file) {\n      const buffer = file.arrayBuffer();\n\n      if (buffer) {\n        const object = new War3MapWct();\n\n        object.load(buffer);\n\n        return object;\n      }\n    }\n\n    return;\n  }\n\n  /**\n   * Read and parse the string table file.\n   */\n  readStringTable(): War3MapWts | undefined {\n    const file = this.archive.get('war3map.wts');\n\n    if (file) {\n      const buffer = file.text();\n\n      if (buffer) {\n        const object = new War3MapWts();\n\n        object.load(buffer);\n\n        return object;\n      }\n    }\n\n    return;\n  }\n\n  /**\n   * Read and parse all of the modification tables.\n   */\n  readModifications(): War3MapModifications {\n    const modifications: War3MapModifications = {};\n\n    // useOptionalInts:\n    //      w3u: no (units)\n    //      w3t: no (items)\n    //      w3b: no (destructables)\n    //      w3d: yes (doodads)\n    //      w3a: yes (abilities)\n    //      w3h: no (buffs)\n    //      w3q: yes (upgrades)\n    const fileNames: War3MapModificationNames[] = ['w3u', 'w3t', 'w3b', 'w3d', 'w3a', 'w3h', 'w3q'];\n    const useOptionalInts = [false, false, false, true, true, false, true];\n\n    for (let i = 0, l = fileNames.length; i < l; i++) {\n      const file = this.archive.get(`war3map.${fileNames[i]}`);\n\n      if (file) {\n        const buffer = file.arrayBuffer();\n\n        if (buffer) {\n          let modification;\n\n          if (useOptionalInts[i]) {\n            modification = new War3MapW3d();\n          } else {\n            modification = new War3MapW3u();\n          }\n\n          modification.load(buffer);\n\n          modifications[fileNames[i]] = modification;\n        }\n      }\n    }\n\n    return modifications;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/mmp/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport MinimapIcon from './minimapicon';\n\n/**\n * war3map.mmp - the minimap icon file.\n */\nexport default class War3MapMmp {\n  u1 = 0;\n  icons: MinimapIcon[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.u1 = stream.readInt32();\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const icon = new MinimapIcon();\n\n      icon.load(stream);\n\n      this.icons[i] = icon;\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.u1);\n    stream.writeUint32(this.icons.length);\n\n    for (const icon of this.icons) {\n      icon.save(stream);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    return 8 + this.icons.length * 16;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/mmp/index.ts",
    "content": "import File from './file';\nimport MinimapIcon from './minimapicon';\n\nexport default {\n  File,\n  MinimapIcon,\n};\n"
  },
  {
    "path": "src/parsers/w3x/mmp/minimapicon.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A minimap icon.\n */\nexport default class MinimapIcon {\n  type = 0;\n  location = new Int32Array(2);\n  /**\n   * Stored as BGRA.\n   */\n  color = new Uint8Array(4);\n\n  load(stream: BinaryStream): void {\n    this.type = stream.readInt32();\n    stream.readInt32Array(this.location);\n    stream.readUint8Array(this.color);\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.type);\n    stream.writeInt32Array(this.location);\n    stream.writeUint8Array(this.color);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/shd/file.ts",
    "content": "/**\n * war3map.shd - the shadow file.\n */\nexport default class War3MapShd {\n  shadows = new Uint8Array(0);\n\n  load(buffer: ArrayBuffer | Uint8Array, width: number, height: number): void {\n    this.shadows = new Uint8Array(buffer.slice(0, width * height * 16));\n  }\n\n  save(): Uint8Array {\n    return this.shadows.slice();\n  }\n\n  getByteLength(): number {\n    return this.shadows.length;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/shd/index.ts",
    "content": "import File from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/droppeditem.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A dropped item.\n */\nexport default class DroppedItem {\n  id = '\\0\\0\\0\\0';\n  chance = 0;\n\n  load(stream: BinaryStream): void {\n    this.id = stream.readBinary(4);\n    this.chance = stream.readInt32();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.chance);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/droppeditemset.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport DroppedItem from './droppeditem';\n\n/**\n * A dropped item set.\n */\nexport default class DroppedItemSet {\n  items: DroppedItem[] = [];\n\n  load(stream: BinaryStream): void {\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const item = new DroppedItem();\n\n      item.load(stream);\n\n      this.items[i] = item;\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.items.length);\n\n    for (const item of this.items) {\n      item.save(stream);\n    }\n  }\n\n  getByteLength(): number {\n    return 4 + this.items.length * 8;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Unit from './unit';\n\n/**\n * war3mapUnits.doo - the units and items file.\n */\nexport default class War3MapUnitsDoo {\n  version = 8;\n  subversion = 11;\n  units: Unit[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array, buildVersion: number): void {\n    const stream = new BinaryStream(buffer);\n\n    if (stream.readBinary(4) !== 'W3do') {\n      throw new Error('Not a valid war3mapUnits.doo buffer');\n    }\n\n    this.version = stream.readInt32();\n    this.subversion = stream.readUint32();\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const unit = new Unit();\n\n      unit.load(stream, this.version, this.subversion, buildVersion);\n\n      this.units[i] = unit;\n    }\n  }\n\n  save(buildVersion: number): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength(buildVersion)));\n\n    stream.writeBinary('W3do');\n    stream.writeInt32(this.version);\n    stream.writeUint32(this.subversion);\n    stream.writeInt32(this.units.length);\n\n    for (const unit of this.units) {\n      unit.save(stream, this.version, this.subversion, buildVersion);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(buildVersion: number): number {\n    let size = 16;\n\n    for (const unit of this.units) {\n      size += unit.getByteLength(this.version, this.subversion, buildVersion);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/index.ts",
    "content": "import File from './file';\nimport Unit from './unit';\nimport DroppedItemSet from './droppeditemset';\nimport DroppedItem from './droppeditem';\nimport InventoryItem from './inventoryitem';\nimport ModifiedAbility from './modifiedability';\nimport RandomUnit from './randomunit';\n\nexport default {\n  File,\n  Unit,\n  DroppedItemSet,\n  DroppedItem,\n  InventoryItem,\n  ModifiedAbility,\n  RandomUnit,\n};\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/inventoryitem.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * An inventory item.\n */\nexport default class InventoryItem {\n  slot = 0;\n  id = '\\0\\0\\0\\0';\n\n  load(stream: BinaryStream): void {\n    this.slot = stream.readInt32();\n    this.id = stream.readBinary(4);\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.slot);\n    stream.writeBinary(this.id);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/modifiedability.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A modified ability.\n */\nexport default class ModifiedAbility {\n  id = '\\0\\0\\0\\0';\n  activeForAutocast = 0;\n  heroLevel = 1;\n\n  load(stream: BinaryStream): void {\n    this.id = stream.readBinary(4);\n    this.activeForAutocast = stream.readInt32();\n    this.heroLevel = stream.readInt32();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.activeForAutocast);\n    stream.writeInt32(this.heroLevel);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/randomunit.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A random unit.\n */\nexport default class RandomUnit {\n  id = '\\0\\0\\0\\0';\n  chance = 0;\n\n  load(stream: BinaryStream): void {\n    this.id = stream.readBinary(4);\n    this.chance = stream.readInt32();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.chance);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/unitsdoo/unit.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport DroppedItemSet from './droppeditemset';\nimport InventoryItem from './inventoryitem';\nimport ModifiedAbility from './modifiedability';\nimport RandomUnit from './randomunit';\n\n/**\n * A unit.\n */\nexport default class Unit {\n  id = '\\0\\0\\0\\0';\n  variation = 0;\n  location = new Float32Array(3);\n  angle = 0;\n  scale = new Float32Array([1, 1, 1]);\n  /**\n   * @since Game version 1.32\n   */\n  skin = '\\0\\0\\0\\0';\n  flags = 0;\n  player = 0;\n  unknown = 0;\n  hitpoints = -1;\n  mana = -1;\n  /**\n   * @since 8\n   */\n  droppedItemTable = 0;\n  droppedItemSets: DroppedItemSet[] = [];\n  goldAmount = 0;\n  targetAcquisition = 0;\n  heroLevel = 0;\n  /**\n   * @since 8\n   */\n  heroStrength = 0;\n  /**\n   * @since 8\n   */\n  heroAgility = 0;\n  /**\n   * @since 8\n   */\n  heroIntelligence = 0;\n  itemsInInventory: InventoryItem[] = [];\n  modifiedAbilities: ModifiedAbility[] = [];\n  randomFlag = 0;\n  level = new Uint8Array(3);\n  itemClass = 0;\n  unitGroup = 0;\n  positionInGroup = 0;\n  randomUnitTables: RandomUnit[] = [];\n  customTeamColor = 0;\n  waygate = 0;\n  creationNumber = 0;\n\n  load(stream: BinaryStream, version: number, subversion: number, buildVersion: number): void {\n    this.id = stream.readBinary(4);\n    this.variation = stream.readInt32();\n    stream.readFloat32Array(this.location);\n    this.angle = stream.readFloat32();\n    stream.readFloat32Array(this.scale);\n\n    if (buildVersion > 131) {\n      this.skin = stream.readBinary(4);\n    }\n\n    this.flags = stream.readUint8();\n    this.player = stream.readInt32();\n    this.unknown = stream.readUint16();\n    this.hitpoints = stream.readInt32();\n    this.mana = stream.readInt32();\n\n    if (subversion > 10) {\n      this.droppedItemTable = stream.readInt32();\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const set = new DroppedItemSet();\n\n      set.load(stream);\n\n      this.droppedItemSets[i] = set;\n    }\n\n    this.goldAmount = stream.readInt32();\n    this.targetAcquisition = stream.readFloat32();\n    this.heroLevel = stream.readInt32();\n\n    if (subversion > 10) {\n      this.heroStrength = stream.readInt32();\n      this.heroAgility = stream.readInt32();\n      this.heroIntelligence = stream.readInt32();\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const item = new InventoryItem();\n\n      item.load(stream);\n\n      this.itemsInInventory[i] = item;\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const modifiedAbility = new ModifiedAbility();\n\n      modifiedAbility.load(stream);\n\n      this.modifiedAbilities[i] = modifiedAbility;\n    }\n\n    this.randomFlag = stream.readInt32();\n\n    if (this.randomFlag === 0) {\n      stream.readUint8Array(this.level); // 24bit number\n      this.itemClass = stream.readUint8();\n    } else if (this.randomFlag === 1) {\n      this.unitGroup = stream.readUint32();\n      this.positionInGroup = stream.readUint32();\n    } else if (this.randomFlag === 2) {\n      for (let i = 0, l = stream.readInt32(); i < l; i++) {\n        const randomUnit = new RandomUnit();\n\n        randomUnit.load(stream);\n\n        this.randomUnitTables[i] = randomUnit;\n      }\n    }\n\n    this.customTeamColor = stream.readInt32();\n    this.waygate = stream.readInt32();\n    this.creationNumber = stream.readInt32();\n  }\n\n  save(stream: BinaryStream, version: number, subversion: number, buildVersion: number): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.variation);\n    stream.writeFloat32Array(this.location);\n    stream.writeFloat32(this.angle);\n    stream.writeFloat32Array(this.scale);\n\n    if (buildVersion > 131) {\n      stream.writeBinary(this.skin);\n    }\n\n    stream.writeUint8(this.flags);\n    stream.writeInt32(this.player);\n    stream.writeUint16(this.unknown);\n    stream.writeInt32(this.hitpoints);\n    stream.writeInt32(this.mana);\n\n    if (subversion > 10) {\n      stream.writeInt32(this.droppedItemTable);\n    }\n\n    stream.writeInt32(this.droppedItemSets.length);\n\n    for (const droppedItemSet of this.droppedItemSets) {\n      droppedItemSet.save(stream);\n    }\n\n    stream.writeInt32(this.goldAmount);\n    stream.writeFloat32(this.targetAcquisition);\n    stream.writeInt32(this.heroLevel);\n\n    if (subversion > 10) {\n      stream.writeInt32(this.heroStrength);\n      stream.writeInt32(this.heroAgility);\n      stream.writeInt32(this.heroIntelligence);\n    }\n\n    stream.writeInt32(this.itemsInInventory.length);\n\n    for (const itemInInventory of this.itemsInInventory) {\n      itemInInventory.save(stream);\n    }\n\n    stream.writeInt32(this.modifiedAbilities.length);\n\n    for (const modifiedAbility of this.modifiedAbilities) {\n      modifiedAbility.save(stream);\n    }\n\n    stream.writeInt32(this.randomFlag);\n\n    if (this.randomFlag === 0) {\n      stream.writeUint8Array(this.level);\n      stream.writeUint8(this.itemClass);\n    } else if (this.randomFlag === 1) {\n      stream.writeUint32(this.unitGroup);\n      stream.writeUint32(this.positionInGroup);\n    } else if (this.randomFlag === 2) {\n      stream.writeInt32(this.randomUnitTables.length);\n\n      for (const randomUnitTable of this.randomUnitTables) {\n        randomUnitTable.save(stream);\n      }\n    }\n\n    stream.writeInt32(this.customTeamColor);\n    stream.writeInt32(this.waygate);\n    stream.writeInt32(this.creationNumber);\n  }\n\n  getByteLength(version: number, subversion: number, buildVersion: number): number {\n    let size = 91;\n\n    if (buildVersion > 131) {\n      size += 4;\n    }\n\n    if (subversion > 10) {\n      size += 16;\n    }\n\n    for (const droppedItemSet of this.droppedItemSets) {\n      size += droppedItemSet.getByteLength();\n    }\n\n    size += this.itemsInInventory.length * 8;\n\n    size += this.modifiedAbilities.length * 12;\n\n    if (this.randomFlag === 0) {\n      size += 4;\n    } else if (this.randomFlag === 1) {\n      size += 8;\n    } else if (this.randomFlag === 2) {\n      size += 4 + this.randomUnitTables.length * 8;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3c/camera.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A camera.\n */\nexport default class Camera {\n  targetLocation = new Float32Array(3);\n  rotation = 0;\n  angleOfAttack = 0;\n  distance = 0;\n  roll = 0;\n  fieldOfView = 0;\n  farClippingPlane = 0;\n  nearClippingPlane = 0;\n  cinematicName = '';\n  /**\n   * @since Game version 1.32\n   */\n  localPitch = 0;\n  /**\n   * @since Game version 1.32\n   */\n  localYaw = 0;\n  /**\n   * @since Game version 1.32\n   */\n  localRoll = 0;\n\n  load(stream: BinaryStream, buildVersion: number): void {\n    stream.readFloat32Array(this.targetLocation);\n    this.rotation = stream.readFloat32(); // in degrees\n    this.angleOfAttack = stream.readFloat32(); // in degrees\n    this.distance = stream.readFloat32();\n    this.roll = stream.readFloat32();\n    this.fieldOfView = stream.readFloat32(); // in degrees\n    this.farClippingPlane = stream.readFloat32();\n    this.nearClippingPlane = stream.readFloat32();\n    this.cinematicName = stream.readNull();\n\n    if (buildVersion > 131) {\n      this.localPitch = stream.readFloat32();\n      this.localYaw = stream.readFloat32();\n      this.localRoll = stream.readFloat32();\n    }\n  }\n\n  save(stream: BinaryStream, buildVersion: number): void {\n    stream.writeFloat32Array(this.targetLocation);\n    stream.writeFloat32(this.rotation);\n    stream.writeFloat32(this.angleOfAttack);\n    stream.writeFloat32(this.distance);\n    stream.writeFloat32(this.roll);\n    stream.writeFloat32(this.fieldOfView);\n    stream.writeFloat32(this.farClippingPlane);\n    stream.writeFloat32(this.nearClippingPlane);\n    stream.writeNull(this.cinematicName);\n\n    if (buildVersion > 131) {\n      stream.writeFloat32(this.localPitch);\n      stream.writeFloat32(this.localYaw);\n      stream.writeFloat32(this.localRoll);\n    }\n  }\n\n  getByteLength(buildVersion: number): number {\n    let size = 41 + byteLengthUtf8(this.cinematicName);\n\n    if (buildVersion > 131) {\n      size += 12;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3c/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Camera from './camera';\n\n/**\n * war3map.w3c - the camera file.\n */\nexport default class War3MapW3c {\n  version = 0;\n  cameras: Camera[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array, buildVersion: number): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const camera = new Camera();\n\n      camera.load(stream, buildVersion);\n\n      this.cameras[i] = camera;\n    }\n  }\n\n  save(buildVersion: number): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength(buildVersion)));\n\n    stream.writeInt32(this.version);\n    stream.writeUint32(this.cameras.length);\n\n    for (const camera of this.cameras) {\n      camera.save(stream, buildVersion);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(buildVersion: number): number {\n    let size = 8;\n\n    for (const camera of this.cameras) {\n      size += camera.getByteLength(buildVersion);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3c/index.ts",
    "content": "import File from './file';\nimport Camera from './camera';\n\nexport default {\n  File,\n  Camera,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3d/file.ts",
    "content": "import BinaryStream from \"../../../common/binarystream\";\nimport ModificationTable from \"../w3u/modificationtable\";\n\n/**\n * war3map.w3d - the doodad modification file.\n *\n * Also used for war3map.w3a (abilities), and war3map.w3q (upgrades).\n */\nexport default class War3MapW3d {\n  version = 0;\n  originalTable = new ModificationTable();\n  customTable = new ModificationTable();\n\n  load(bufferOrStream: ArrayBuffer | Uint8Array | BinaryStream): void {\n    let stream;\n\n    if (bufferOrStream instanceof BinaryStream) {\n      stream = bufferOrStream;\n    } else {\n      stream = new BinaryStream(bufferOrStream);\n    }\n\n    this.version = stream.readInt32();\n    this.originalTable.load(stream, true, this.version);\n    this.customTable.load(stream, true, this.version);\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n    this.originalTable.save(stream, true, this.version);\n    this.customTable.save(stream, true, this.version);\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    return (\n      4 +\n      this.originalTable.getByteLength(true, this.version) +\n      this.customTable.getByteLength(true, this.version)\n    );\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3d/index.ts",
    "content": "import File from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3e/corner.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A tile corner.\n */\nexport default class Corner {\n  groundHeight = 0;\n  waterHeight = 0;\n  mapEdge = 0;\n  ramp = 0;\n  blight = 0;\n  water = 0;\n  boundary = 0;\n  groundTexture = 0;\n  cliffVariation = 0;\n  groundVariation = 0;\n  cliffTexture = 0;\n  layerHeight = 0;\n\n  load(stream: BinaryStream): void {\n    this.groundHeight = (stream.readInt16() - 8192) / 512;\n\n    const waterAndEdge = stream.readInt16();\n\n    this.waterHeight = ((waterAndEdge & 0x3FFF) - 8192) / 512;\n    this.mapEdge = waterAndEdge & 0x4000;\n\n    const textureAndFlags = stream.readUint8();\n\n    this.ramp = textureAndFlags & 0b00010000;\n    this.blight = textureAndFlags & 0b00100000;\n    this.water = textureAndFlags & 0b01000000;\n    this.boundary = textureAndFlags & 0b10000000;\n\n    this.groundTexture = textureAndFlags & 0b00001111;\n\n    const variation = stream.readUint8();\n\n    this.cliffVariation = (variation & 0b11100000) >>> 5;\n    this.groundVariation = variation & 0b00011111;\n\n    const cliffTextureAndLayer = stream.readUint8();\n\n    this.cliffTexture = (cliffTextureAndLayer & 0b11110000) >>> 4;\n    this.layerHeight = cliffTextureAndLayer & 0b00001111;\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt16(this.groundHeight * 512 + 8192);\n    stream.writeInt16(this.waterHeight * 512 + 8192 + this.mapEdge << 14);\n    stream.writeUint8((this.ramp << 4) | (this.blight << 5) | (this.water << 6) | (this.boundary << 7) | this.groundTexture);\n    stream.writeUint8((this.cliffVariation << 5) | this.groundVariation);\n    stream.writeUint8((this.cliffTexture << 4) + this.layerHeight);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3e/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Corner from './corner';\n\n/**\n * war3map.w3e - the environment file.\n */\nexport default class War3MapW3e {\n  version = 0;\n  tileset = 'A';\n  haveCustomTileset = 0;\n  groundTilesets: string[] = [];\n  cliffTilesets: string[] = [];\n  mapSize = new Int32Array(2);\n  centerOffset = new Float32Array(2);\n  corners: Corner[][] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    if (stream.readBinary(4) !== 'W3E!') {\n      return;\n    }\n\n    this.version = stream.readInt32();\n    this.tileset = stream.readBinary(1);\n    this.haveCustomTileset = stream.readInt32();\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      this.groundTilesets[i] = stream.readBinary(4);\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      this.cliffTilesets[i] = stream.readBinary(4);\n    }\n\n    stream.readInt32Array(this.mapSize);\n    stream.readFloat32Array(this.centerOffset);\n\n    for (let row = 0, rows = this.mapSize[1]; row < rows; row++) {\n      this.corners[row] = [];\n\n      for (let column = 0, columns = this.mapSize[0]; column < columns; column++) {\n        const corner = new Corner();\n\n        corner.load(stream);\n\n        this.corners[row][column] = corner;\n      }\n    }\n  }\n\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeBinary('W3E!');\n    stream.writeInt32(this.version);\n    stream.writeBinary(this.tileset);\n    stream.writeInt32(this.haveCustomTileset);\n    stream.writeUint32(this.groundTilesets.length);\n\n    for (const groundTileset of this.groundTilesets) {\n      stream.writeBinary(groundTileset);\n    }\n\n    stream.writeUint32(this.cliffTilesets.length);\n\n    for (const cliffTileset of this.cliffTilesets) {\n      stream.writeBinary(cliffTileset);\n    }\n\n    stream.writeInt32Array(this.mapSize);\n    stream.writeFloat32Array(this.centerOffset);\n\n    for (const row of this.corners) {\n      for (const corner of row) {\n        corner.save(stream);\n      }\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    return 37 + (this.groundTilesets.length * 4) + (this.cliffTilesets.length * 4) + (this.mapSize[0] * this.mapSize[1] * 7);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3e/index.ts",
    "content": "import File from './file';\nimport Corner from './corner';\n\nexport default {\n  File,\n  Corner,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3f/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport MapTitle from './maptitle';\nimport MapOrder from './maporder';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * war3campaign.w3f - the campaign information file.\n */\nexport default class War3CampaignW3f {\n  version = 0;\n  campaignVersion = 0;\n  editorVersion = 0;\n  name = '';\n  difficulty = '';\n  author = '';\n  description = '';\n  mode = -1; // 0: fixed difficulty, only w3m maps, 1: variable difficulty, only w3m maps, 1: fixed..., contains w3x maps, 2: variable..., contains w3xm maps.\n  backgroundScreen = -1; // -1 = none or custom path\n  backgroundScreenPath = '';\n  minimapImagePath = '';\n  ambientSound = 0; // -1 = imported, 0 = none, >0 = preset index\n  ambientSoundPath = '';\n  terrainFog = 0; // 0 = not used, >0 = index of terrain fog style\n  fogStartZ = 0;\n  fogEndZ = 0;\n  fogDensity = 0;\n  fogColor = new Uint8Array(4);\n  userInterface = -1; // 0 = human\n  mapTitles: MapTitle[] = [];\n  mapOrders: MapOrder[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n    this.campaignVersion = stream.readInt32();\n    this.editorVersion = stream.readInt32();\n    this.name = stream.readNull();\n    this.difficulty = stream.readNull();\n    this.author = stream.readNull();\n    this.description = stream.readNull();\n    this.mode = stream.readInt32();\n    this.backgroundScreen = stream.readInt32();\n    this.backgroundScreenPath = stream.readNull();\n    this.minimapImagePath = stream.readNull();\n    this.ambientSound = stream.readInt32();\n    this.ambientSoundPath = stream.readNull();\n    this.terrainFog = stream.readInt32();\n    this.fogStartZ = stream.readFloat32();\n    this.fogEndZ = stream.readFloat32();\n    this.fogDensity = stream.readFloat32();\n    stream.readUint8Array(this.fogColor);\n    this.userInterface = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const mapTitle = new MapTitle();\n\n      mapTitle.load(stream);\n\n      this.mapTitles[i] = mapTitle;\n    }\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const mapOrder = new MapOrder();\n\n      mapOrder.load(stream);\n\n      this.mapOrders[i] = mapOrder;\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n    stream.writeInt32(this.campaignVersion);\n    stream.writeInt32(this.editorVersion);\n    stream.writeNull(this.name);\n    stream.writeNull(this.difficulty);\n    stream.writeNull(this.author);\n    stream.writeNull(this.description);\n    stream.writeInt32(this.mode);\n    stream.writeInt32(this.backgroundScreen);\n    stream.writeNull(this.backgroundScreenPath);\n    stream.writeNull(this.minimapImagePath);\n    stream.writeInt32(this.ambientSound);\n    stream.writeNull(this.ambientSoundPath);\n    stream.writeInt32(this.terrainFog);\n    stream.writeFloat32(this.fogStartZ);\n    stream.writeFloat32(this.fogEndZ);\n    stream.writeFloat32(this.fogDensity);\n    stream.writeUint8Array(this.fogColor);\n    stream.writeInt32(this.userInterface);\n    stream.writeUint32(this.mapTitles.length);\n\n    for (const title of this.mapTitles) {\n      title.save(stream);\n    }\n\n    stream.writeUint32(this.mapOrders.length);\n\n    for (const order of this.mapOrders) {\n      order.save(stream);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 63 + byteLengthUtf8(this.name) + byteLengthUtf8(this.difficulty) + byteLengthUtf8(this.author) + byteLengthUtf8(this.description) + byteLengthUtf8(this.backgroundScreenPath) + byteLengthUtf8(this.minimapImagePath) + byteLengthUtf8(this.ambientSoundPath);\n\n    for (const title of this.mapTitles) {\n      size += title.getByteLength();\n    }\n\n    for (const order of this.mapOrders) {\n      size += order.getByteLength();\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3f/index.ts",
    "content": "import File from './file';\nimport MapTitle from './maptitle';\nimport MapOrder from './maporder';\n\nexport default {\n  File,\n  MapTitle,\n  MapOrder,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3f/maporder.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A map order.\n */\nexport default class MapOrder {\n  u1 = 0;\n  path = '';\n\n  load(stream: BinaryStream): void {\n    this.u1 = stream.readInt8();\n    this.path = stream.readNull();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt8(this.u1);\n    stream.writeNull(this.path);\n  }\n\n  getByteLength(): number {\n    return 2 + byteLengthUtf8(this.path);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3f/maptitle.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A map title.\n */\nexport default class MapTitle {\n  visible = 0;\n  chapterTitle = '';\n  mapTitle = '';\n  path = '';\n\n  load(stream: BinaryStream): void {\n    this.visible = stream.readInt32();\n    this.chapterTitle = stream.readNull();\n    this.mapTitle = stream.readNull();\n    this.path = stream.readNull();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.visible);\n    stream.writeNull(this.chapterTitle);\n    stream.writeNull(this.mapTitle);\n    stream.writeNull(this.path);\n  }\n\n  getByteLength(): number {\n    return 7 + byteLengthUtf8(this.chapterTitle) + byteLengthUtf8(this.mapTitle) + byteLengthUtf8(this.path);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport Force from './force';\nimport Player from './player';\nimport RandomItemTable from './randomitemtable';\nimport RandomUnitTable from './randomunittable';\nimport TechAvailabilityChange from './techavailabilitychange';\nimport UpgradeAvailabilityChange from './upgradeavailabilitychange';\n\n/**\n * war3map.w3i - the general information file.\n */\nexport default class War3MapW3i {\n  version = 0;\n  saves = 0;\n  editorVersion = 0;\n  buildVersion = new Uint32Array(4);\n  name = '';\n  author = '';\n  description = '';\n  recommendedPlayers = '';\n  cameraBounds = new Float32Array(8);\n  cameraBoundsComplements = new Int32Array(4);\n  playableSize = new Int32Array(2);\n  flags = 0;\n  tileset = 'A';\n  campaignBackground = 0;\n  loadingScreenModel = '';\n  loadingScreenText = '';\n  loadingScreenTitle = '';\n  loadingScreenSubtitle = '';\n  loadingScreen = 0;\n  prologueScreenModel = '';\n  prologueScreenText = '';\n  prologueScreenTitle = '';\n  prologueScreenSubtitle = '';\n  useTerrainFog = 0;\n  fogHeight = new Float32Array(2);\n  fogDensity = 0;\n  fogColor = new Uint8Array(4);\n  globalWeather = 0;\n  soundEnvironment = '';\n  lightEnvironmentTileset = '\\0';\n  waterVertexColor = new Uint8Array(4);\n  scriptMode = 0;\n  graphicsMode = 0;\n  defaultCameraZoom = 0;\n  maxCameraZoom = 0;\n  minCameraZoom = 0;\n  players: Player[] = [];\n  forces: Force[] = [];\n  upgradeAvailabilityChanges: UpgradeAvailabilityChange[] = [];\n  techAvailabilityChanges: TechAvailabilityChange[] = [];\n  randomUnitTables: RandomUnitTable[] = [];\n  randomItemTables: RandomItemTable[] = [];\n  unknown1 = 0;\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n    this.saves = stream.readInt32();\n    this.editorVersion = stream.readInt32();\n\n    if (this.version > 27) {\n      stream.readUint32Array(this.buildVersion);\n    }\n\n    this.name = stream.readNull();\n    this.author = stream.readNull();\n    this.description = stream.readNull();\n    this.recommendedPlayers = stream.readNull();\n    stream.readFloat32Array(this.cameraBounds);\n    stream.readInt32Array(this.cameraBoundsComplements);\n    stream.readInt32Array(this.playableSize);\n    this.flags = stream.readUint32();\n    this.tileset = stream.readBinary(1);\n    this.campaignBackground = stream.readInt32();\n\n    if (this.version > 24) {\n      this.loadingScreenModel = stream.readNull();\n    }\n\n    this.loadingScreenText = stream.readNull();\n    this.loadingScreenTitle = stream.readNull();\n    this.loadingScreenSubtitle = stream.readNull();\n    this.loadingScreen = stream.readInt32();\n\n    if (this.version > 24) {\n      this.prologueScreenModel = stream.readNull();\n    }\n\n    this.prologueScreenText = stream.readNull();\n    this.prologueScreenTitle = stream.readNull();\n    this.prologueScreenSubtitle = stream.readNull();\n\n    if (this.version > 24) {\n      this.useTerrainFog = stream.readInt32();\n      stream.readFloat32Array(this.fogHeight);\n      this.fogDensity = stream.readFloat32();\n      stream.readUint8Array(this.fogColor);\n      this.globalWeather = stream.readInt32();\n      this.soundEnvironment = stream.readNull();\n      this.lightEnvironmentTileset = stream.readBinary(1);\n      stream.readUint8Array(this.waterVertexColor);\n    }\n\n    if (this.version > 27) {\n      this.scriptMode = stream.readUint32();\n    }\n\n    if (this.version > 30) {\n      this.graphicsMode = stream.readUint32();\n      this.unknown1 = stream.readUint32();\n    }\n\n    if (this.version > 32) {\n      this.defaultCameraZoom = stream.readUint32();\n      this.maxCameraZoom = stream.readUint32();\n      this.minCameraZoom = stream.readUint32();\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const player = new Player();\n\n      player.load(stream, this.version);\n\n      this.players[i] = player;\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const force = new Force();\n\n      force.load(stream);\n\n      this.forces[i] = force;\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const upgradeAvailabilityChange = new UpgradeAvailabilityChange();\n\n      upgradeAvailabilityChange.load(stream);\n\n      this.upgradeAvailabilityChanges[i] = upgradeAvailabilityChange;\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const techAvailabilityChange = new TechAvailabilityChange();\n\n      techAvailabilityChange.load(stream);\n\n      this.techAvailabilityChanges[i] = techAvailabilityChange;\n    }\n\n    for (let i = 0, l = stream.readInt32(); i < l; i++) {\n      const randomUnitTable = new RandomUnitTable();\n\n      randomUnitTable.load(stream);\n\n      this.randomUnitTables[i] = randomUnitTable;\n    }\n\n    if (this.version > 24) {\n      for (let i = 0, l = stream.readInt32(); i < l; i++) {\n        const randomItemTable = new RandomItemTable();\n\n        randomItemTable.load(stream);\n\n        this.randomItemTables[i] = randomItemTable;\n      }\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n    stream.writeInt32(this.saves);\n    stream.writeInt32(this.editorVersion);\n\n    if (this.version > 27) {\n      stream.writeUint32Array(this.buildVersion);\n    }\n\n    stream.writeNull(this.name);\n    stream.writeNull(this.author);\n    stream.writeNull(this.description);\n    stream.writeNull(this.recommendedPlayers);\n    stream.writeFloat32Array(this.cameraBounds);\n    stream.writeInt32Array(this.cameraBoundsComplements);\n    stream.writeInt32Array(this.playableSize);\n    stream.writeUint32(this.flags);\n    stream.writeBinary(this.tileset);\n    stream.writeInt32(this.campaignBackground);\n\n    if (this.version > 24) {\n      stream.writeNull(this.loadingScreenModel);\n    }\n\n    stream.writeNull(this.loadingScreenText);\n    stream.writeNull(this.loadingScreenTitle);\n    stream.writeNull(this.loadingScreenSubtitle);\n    stream.writeInt32(this.loadingScreen);\n\n    if (this.version > 24) {\n      stream.writeNull(this.prologueScreenModel);\n    }\n\n    stream.writeNull(this.prologueScreenText);\n    stream.writeNull(this.prologueScreenTitle);\n    stream.writeNull(this.prologueScreenSubtitle);\n\n    if (this.version > 24) {\n      stream.writeInt32(this.useTerrainFog);\n      stream.writeFloat32Array(this.fogHeight);\n      stream.writeFloat32(this.fogDensity);\n      stream.writeUint8Array(this.fogColor);\n      stream.writeInt32(this.globalWeather);\n      stream.writeNull(this.soundEnvironment);\n      stream.writeBinary(this.lightEnvironmentTileset);\n      stream.writeUint8Array(this.waterVertexColor);\n    }\n\n    if (this.version > 27) {\n      stream.writeUint32(this.scriptMode);\n    }\n\n    if (this.version > 30) {\n      stream.writeUint32(this.graphicsMode);\n      stream.writeUint32(this.unknown1);\n    }\n\n    if (this.version > 32) {\n      stream.writeUint32(this.defaultCameraZoom);\n      stream.writeUint32(this.maxCameraZoom);\n      stream.writeUint32(this.minCameraZoom);\n    }\n\n    stream.writeUint32(this.players.length);\n\n    for (const player of this.players) {\n      player.save(stream, this.version);\n    }\n\n    stream.writeUint32(this.forces.length);\n\n    for (const force of this.forces) {\n      force.save(stream);\n    }\n\n    stream.writeUint32(this.upgradeAvailabilityChanges.length);\n\n    for (const change of this.upgradeAvailabilityChanges) {\n      change.save(stream);\n    }\n\n    stream.writeUint32(this.techAvailabilityChanges.length);\n\n    for (const change of this.techAvailabilityChanges) {\n      change.save(stream);\n    }\n\n    stream.writeUint32(this.randomUnitTables.length);\n\n    for (const table of this.randomUnitTables) {\n      table.save(stream);\n    }\n\n    if (this.version > 24) {\n      stream.writeUint32(this.randomItemTables.length);\n\n      for (const table of this.randomItemTables) {\n        table.save(stream);\n      }\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 111 + byteLengthUtf8(this.name) + byteLengthUtf8(this.author) + byteLengthUtf8(this.description) + byteLengthUtf8(this.recommendedPlayers) + byteLengthUtf8(this.loadingScreenText) + byteLengthUtf8(this.loadingScreenTitle) + byteLengthUtf8(this.loadingScreenSubtitle) + byteLengthUtf8(this.prologueScreenText) + byteLengthUtf8(this.prologueScreenTitle) + byteLengthUtf8(this.prologueScreenSubtitle);\n\n    for (const player of this.players) {\n      size += player.getByteLength(this.version);\n    }\n\n    for (const force of this.forces) {\n      size += force.getByteLength();\n    }\n\n    size += this.upgradeAvailabilityChanges.length * 16;\n\n    size += this.techAvailabilityChanges.length * 8;\n\n    for (const table of this.randomUnitTables) {\n      size += table.getByteLength();\n    }\n\n    if (this.version > 24) {\n      size += 36 + byteLengthUtf8(this.loadingScreenModel) + byteLengthUtf8(this.prologueScreenModel) + byteLengthUtf8(this.soundEnvironment);\n\n      for (const table of this.randomItemTables) {\n        size += table.getByteLength();\n      }\n    }\n\n    if (this.version > 27) {\n      size += 20;\n    }\n\n    if (this.version > 30) {\n      size += 8;\n    }\n\n    return size;\n  }\n\n  /**\n   * Returns the build version as major+minor.\n   * \n   * For example version 1.31.X will return 131.\n   * \n   * Note that this will always return 0 for any version below 1.31.\n   */\n  getBuildVersion(): number {\n    return this.buildVersion[0] * 100 + this.buildVersion[1];\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/force.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A force.\n */\nexport default class Force {\n  flags = 0;\n  playerMasks = 0;\n  name = '';\n\n  load(stream: BinaryStream): void {\n    this.flags = stream.readUint32();\n    this.playerMasks = stream.readUint32();\n    this.name = stream.readNull();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeUint32(this.flags);\n    stream.writeUint32(this.playerMasks);\n    stream.writeNull(this.name);\n  }\n\n  getByteLength(): number {\n    return 9 + byteLengthUtf8(this.name);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/index.ts",
    "content": "import File from './file';\nimport Player from './player';\nimport Force from './force';\nimport UpgradeAvailabilityChange from './upgradeavailabilitychange';\nimport TechAvailabilityChange from './techavailabilitychange';\nimport RandomUnitTable from './randomunittable';\nimport RandomUnit from './randomunit';\nimport RandomItemTable from './randomitemtable';\nimport RandomItemSet from './randomitemset';\nimport RandomItem from './randomitem';\n\nexport default {\n  File,\n  Player,\n  Force,\n  UpgradeAvailabilityChange,\n  TechAvailabilityChange,\n  RandomUnitTable,\n  RandomUnit,\n  RandomItemTable,\n  RandomItemSet,\n  RandomItem,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3i/player.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A player.\n */\nexport default class Player {\n  id = 0;\n  type = 0;\n  race = 0;\n  isFixedStartPosition = 0;\n  name = '';\n  startLocation = new Float32Array(2);\n  allyLowPriorities = 0;\n  allyHighPriorities = 0;\n  unknown1 = new Uint8Array(8);\n\n  load(stream: BinaryStream, version: number): void {\n    this.id = stream.readInt32();\n    this.type = stream.readInt32();\n    this.race = stream.readInt32();\n    this.isFixedStartPosition = stream.readInt32();\n    this.name = stream.readNull();\n    stream.readFloat32Array(this.startLocation);\n    this.allyLowPriorities = stream.readUint32();\n    this.allyHighPriorities = stream.readUint32();\n    if (version > 30) {\n      stream.readUint8Array(this.unknown1);\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeInt32(this.id);\n    stream.writeInt32(this.type);\n    stream.writeInt32(this.race);\n    stream.writeInt32(this.isFixedStartPosition);\n    stream.writeNull(this.name);\n    stream.writeFloat32Array(this.startLocation);\n    stream.writeUint32(this.allyLowPriorities);\n    stream.writeUint32(this.allyHighPriorities);\n    if (version > 30) {\n      stream.writeUint8Array(this.unknown1);\n    }\n  }\n\n  getByteLength(version: number): number {\n    let size = 33 + byteLengthUtf8(this.name);\n\n    if (version > 30) {\n      size += 8;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/randomitem.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A random item.\n */\nexport default class RandomItem {\n  chance = 0;\n  id = '\\0\\0\\0\\0';\n\n  load(stream: BinaryStream): void {\n    this.chance = stream.readInt32();\n    this.id = stream.readBinary(4);\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.chance);\n    stream.writeBinary(this.id);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/randomitemset.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport RandomItem from './randomitem';\n\n/**\n * A random item set.\n */\nexport default class RandomItemSet {\n  items: RandomItem[] = [];\n\n  load(stream: BinaryStream): void {\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const item = new RandomItem();\n\n      item.load(stream);\n\n      this.items[i] = item;\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeUint32(this.items.length);\n\n    for (const item of this.items) {\n      item.save(stream);\n    }\n  }\n\n  getByteLength(): number {\n    return 4 + this.items.length * 8;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/randomitemtable.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport RandomItemSet from './randomitemset';\n\n/**\n * A random item table.\n */\nexport default class RandomItemTable {\n  id = 0;\n  name = '';\n  sets: RandomItemSet[] = [];\n\n  load(stream: BinaryStream): void {\n    this.id = stream.readInt32();\n    this.name = stream.readNull();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const set = new RandomItemSet();\n\n      set.load(stream);\n\n      this.sets[i] = set;\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.id);\n    stream.writeNull(this.name);\n    stream.writeUint32(this.sets.length);\n\n    for (const set of this.sets) {\n      set.save(stream);\n    }\n  }\n\n  getByteLength(): number {\n    let size = 9 + byteLengthUtf8(this.name);\n\n    for (const set of this.sets) {\n      size += set.getByteLength();\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/randomunit.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A random unit.\n */\nexport default class RandomUnit {\n  chance = 0;\n  ids: string[] = [];\n\n  load(stream: BinaryStream, positions: number): void {\n    this.chance = stream.readInt32();\n\n    for (let i = 0; i < positions; i++) {\n      this.ids[i] = stream.readBinary(4);\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.chance);\n\n    for (const id of this.ids) {\n      stream.writeBinary(id);\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/randomunittable.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport RandomUnit from './randomunit';\n\n/**\n * A random unit table.\n */\nexport default class RandomUnitTable {\n  id = 0;\n  name = '';\n  positions = 0;\n  columnTypes = new Int32Array(0);\n  units: RandomUnit[] = [];\n\n  load(stream: BinaryStream): void {\n    this.id = stream.readInt32();\n    this.name = stream.readNull();\n    this.positions = stream.readInt32();\n    this.columnTypes = stream.readInt32Array(this.positions);\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const unit = new RandomUnit();\n\n      unit.load(stream, this.positions);\n\n      this.units[i] = unit;\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeInt32(this.id);\n    stream.writeNull(this.name);\n    stream.writeInt32(this.positions);\n    stream.writeInt32Array(this.columnTypes);\n    stream.writeUint32(this.units.length);\n\n    for (const unit of this.units) {\n      unit.save(stream);\n    }\n  }\n\n  getByteLength(): number {\n    return 13 + byteLengthUtf8(this.name) + this.columnTypes.byteLength + (this.units.length * (4 + 4 * this.positions));\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/techavailabilitychange.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * A tech availablity change.\n */\nexport default class TechAvailabilityChange {\n  playerFlags = 0;\n  id = '\\0\\0\\0\\0';\n\n  load(stream: BinaryStream): void {\n    this.playerFlags = stream.readUint32();\n    this.id = stream.readBinary(4);\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeUint32(this.playerFlags);\n    stream.writeBinary(this.id);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3i/upgradeavailabilitychange.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * An upgrade availability change.\n */\nexport default class UpgradeAvailabilityChange {\n  playerFlags = 0;\n  id = '\\0\\0\\0\\0';\n  levelAffected = 0;\n  availability = 0;\n\n  load(stream: BinaryStream): void {\n    this.playerFlags = stream.readUint32();\n    this.id = stream.readBinary(4);\n    this.levelAffected = stream.readInt32();\n    this.availability = stream.readInt32();\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeUint32(this.playerFlags);\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.levelAffected);\n    stream.writeInt32(this.availability);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3o/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport War3MapW3u from '../w3u/file';\nimport War3MapW3d from '../w3d/file';\n\n/**\n * war3map.w3o - the combined modification file.\n *\n * Contains all of the modifications of a map.\n * Can be exported and imported via the World Editor.\n */\nexport default class War3MapW3o {\n  version = 0;\n  units: War3MapW3u | null = null;\n  items: War3MapW3u | null = null;\n  destructables: War3MapW3u | null = null;\n  doodads: War3MapW3d | null = null;\n  abilities: War3MapW3d | null = null;\n  buffs: War3MapW3u | null = null;\n  upgrades: War3MapW3d | null = null;\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n\n    if (stream.readInt32()) {\n      this.units = new War3MapW3u();\n      this.units.load(stream);\n    }\n\n    if (stream.readInt32()) {\n      this.items = new War3MapW3u();\n      this.items.load(stream);\n    }\n\n    if (stream.readInt32()) {\n      this.destructables = new War3MapW3u();\n      this.destructables.load(stream);\n    }\n\n    if (stream.readInt32()) {\n      this.doodads = new War3MapW3d();\n      this.doodads.load(stream);\n    }\n\n    if (stream.readInt32()) {\n      this.abilities = new War3MapW3d();\n      this.abilities.load(stream);\n    }\n\n    if (stream.readInt32()) {\n      this.buffs = new War3MapW3u();\n      this.buffs.load(stream);\n    }\n\n    if (stream.readInt32()) {\n      this.upgrades = new War3MapW3d();\n      this.upgrades.load(stream);\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n\n    if (this.units) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.units.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if (this.items) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.items.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if (this.destructables) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.destructables.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if (this.doodads) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.doodads.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if (this.abilities) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.abilities.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if (this.buffs) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.buffs.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if (this.upgrades) {\n      stream.writeInt32(1);\n      stream.writeUint8Array(this.upgrades.save());\n    } else {\n      stream.writeInt32(0);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 32;\n\n    if (this.units) {\n      size += this.units.getByteLength();\n    }\n\n    if (this.items) {\n      size += this.items.getByteLength();\n    }\n\n    if (this.destructables) {\n      size += this.destructables.getByteLength();\n    }\n\n    if (this.doodads) {\n      size += this.doodads.getByteLength();\n    }\n\n    if (this.abilities) {\n      size += this.abilities.getByteLength();\n    }\n\n    if (this.buffs) {\n      size += this.buffs.getByteLength();\n    }\n\n    if (this.upgrades) {\n      size += this.upgrades.getByteLength();\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3o/index.ts",
    "content": "import File from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3r/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Region from './region';\n\n/**\n * war3map.w3r - the region file.\n */\nexport default class War3MapW3r {\n  version = 0;\n  regions: Region[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const region = new Region();\n\n      region.load(stream);\n\n      this.regions[i] = region;\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n    stream.writeUint32(this.regions.length);\n\n    for (const region of this.regions) {\n      region.save(stream);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 8;\n\n    for (const region of this.regions) {\n      size += region.getByteLength();\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3r/index.ts",
    "content": "import File from './file';\nimport Region from './region';\n\nexport default {\n  File,\n  Region,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3r/region.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A region.\n */\nexport default class Region {\n  left = 0;\n  right = 0;\n  bottom = 0;\n  top = 0;\n  name = '';\n  creationNumber = 0;\n  weatherEffectId = '\\0\\0\\0\\0';\n  ambientSound = '';\n  color = new Uint8Array(4);\n\n  load(stream: BinaryStream): void {\n    this.left = stream.readFloat32();\n    this.right = stream.readFloat32();\n    this.bottom = stream.readFloat32();\n    this.top = stream.readFloat32();\n    this.name = stream.readNull();\n    this.creationNumber = stream.readUint32();\n    this.weatherEffectId = stream.readBinary(4);\n    this.ambientSound = stream.readNull();\n    stream.readUint8Array(this.color);\n  }\n\n  save(stream: BinaryStream): void {\n    stream.writeFloat32(this.left);\n    stream.writeFloat32(this.right);\n    stream.writeFloat32(this.bottom);\n    stream.writeFloat32(this.top);\n    stream.writeNull(this.name);\n    stream.writeUint32(this.creationNumber);\n\n    if (this.weatherEffectId) {\n      stream.writeBinary(this.weatherEffectId);\n    } else {\n      stream.writeUint32(0);\n    }\n\n    stream.writeNull(this.ambientSound);\n    stream.writeUint8Array(this.color);\n  }\n\n  getByteLength(): number {\n    return 30 + byteLengthUtf8(this.name) + byteLengthUtf8(this.ambientSound);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3s/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport Sound from './sound';\n\n/**\n * war3map.w3s - the sound file.\n */\nexport default class War3MapW3s {\n  version = 0;\n  sounds: Sound[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const sound = new Sound();\n\n      sound.load(stream, this.version);\n\n      this.sounds[i] = sound;\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n    stream.writeUint32(this.sounds.length);\n\n    for (const sound of this.sounds) {\n      sound.save(stream, this.version);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 8;\n\n    for (const sound of this.sounds) {\n      size += sound.getByteLength(this.version);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3s/index.ts",
    "content": "import File from './file';\nimport Sound from './sound';\n\nexport default {\n  File,\n  Sound,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3s/sound.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A sound.\n */\nexport default class Sound {\n  name = '';\n  file = '';\n  eaxEffect = '';\n  flags = 0;\n  fadeInRate = 0;\n  fadeOutRate = 0;\n  volume = 0;\n  pitch = 0;\n  pitchVariance = 0;\n  priority = 0;\n  channel = 0;\n  minDistance = 0;\n  maxDistance = 0;\n  distanceCutoff = 0;\n  coneInside = 0;\n  coneOutside = 0;\n  coneOutsideVolume = 0;\n  coneOrientationX = 0;\n  coneOrientationY = 0;\n  coneOrientationZ = 0;\n\n  load(stream: BinaryStream, version: number): void {\n    this.name = stream.readNull();\n    this.file = stream.readNull();\n    this.eaxEffect = stream.readNull();\n    this.flags = stream.readUint32();\n    this.fadeInRate = stream.readInt32();\n    this.fadeOutRate = stream.readInt32();\n    this.volume = stream.readInt32();\n    this.pitch = stream.readFloat32();\n    this.pitchVariance = stream.readFloat32();\n    this.priority = stream.readInt32();\n    this.channel = stream.readInt32();\n    this.minDistance = stream.readFloat32();\n    this.maxDistance = stream.readFloat32();\n    this.distanceCutoff = stream.readFloat32();\n    this.coneInside = stream.readFloat32();\n    this.coneOutside = stream.readFloat32();\n    this.coneOutsideVolume = stream.readInt32();\n    this.coneOrientationX = stream.readFloat32();\n    this.coneOrientationY = stream.readFloat32();\n    this.coneOrientationZ = stream.readFloat32();\n\n    if (version > 1) {\n\n      if (version > 2) {\n\n      }\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeNull(this.name);\n    stream.writeNull(this.file);\n    stream.writeNull(this.eaxEffect);\n    stream.writeUint32(this.flags);\n    stream.writeUint32(this.fadeInRate);\n    stream.writeUint32(this.fadeOutRate);\n    stream.writeUint32(this.volume);\n    stream.writeFloat32(this.pitch);\n    stream.writeFloat32(this.pitchVariance);\n    stream.writeInt32(this.priority);\n    stream.writeInt32(this.channel);\n    stream.writeFloat32(this.minDistance);\n    stream.writeFloat32(this.maxDistance);\n    stream.writeFloat32(this.distanceCutoff);\n    stream.writeFloat32(this.coneInside);\n    stream.writeFloat32(this.coneOutside);\n    stream.writeInt32(this.coneOutsideVolume);\n    stream.writeFloat32(this.coneOrientationX);\n    stream.writeFloat32(this.coneOrientationY);\n    stream.writeFloat32(this.coneOrientationZ);\n\n    if (version > 1) {\n\n      if (version > 2) {\n        \n      }\n    }\n  }\n\n  getByteLength(version: number): number {\n    const size = 71 + byteLengthUtf8(this.name) + byteLengthUtf8(this.file) + byteLengthUtf8(this.eaxEffect);\n\n    if (version > 1) {\n\n      if (version > 2) {\n        \n      }\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3u/file.ts",
    "content": "import BinaryStream from \"../../../common/binarystream\";\nimport ModificationTable from \"./modificationtable\";\n\n/**\n * war3map.w3u - the unit modification file.\n *\n * Also used for war3map.w3t (items), war3map.w3b (destructibles), and war3map.w3h (buffs).\n */\nexport default class War3MapW3u {\n  version = 0;\n  originalTable = new ModificationTable();\n  customTable = new ModificationTable();\n\n  load(bufferOrStream: ArrayBuffer | Uint8Array | BinaryStream): void {\n    let stream;\n\n    if (bufferOrStream instanceof BinaryStream) {\n      stream = bufferOrStream;\n    } else {\n      stream = new BinaryStream(bufferOrStream);\n    }\n\n    this.version = stream.readInt32();\n    this.originalTable.load(stream, false, this.version);\n    this.customTable.load(stream, false, this.version);\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n    this.originalTable.save(stream, false, this.version);\n    this.customTable.save(stream, false, this.version);\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    return (\n      4 +\n      this.originalTable.getByteLength(false, this.version) +\n      this.customTable.getByteLength(false, this.version)\n    );\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3u/index.ts",
    "content": "import File from './file';\nimport ModificationTable from './modificationtable';\nimport ModificationObject from './modifiedobject';\nimport Modification from './modification';\n\nexport default {\n  File,\n  ModificationTable,\n  ModificationObject,\n  Modification,\n};\n"
  },
  {
    "path": "src/parsers/w3x/w3u/modification.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A modification.\n */\nexport default class Modification {\n  id = '\\0\\0\\0\\0';\n  variableType = 0;\n  levelOrVariation = 0;\n  dataPointer = 0;\n  value: number | string = 0;\n  u1 = 0;\n\n  load(stream: BinaryStream, useOptionalInts: boolean): void {\n    this.id = stream.readBinary(4);\n    this.variableType = stream.readInt32();\n\n    if (useOptionalInts) {\n      this.levelOrVariation = stream.readInt32();\n      this.dataPointer = stream.readInt32();\n    }\n\n    if (this.variableType === 0) {\n      this.value = stream.readInt32();\n    } else if (this.variableType === 1 || this.variableType === 2) {\n      this.value = stream.readFloat32();\n    } else if (this.variableType === 3) {\n      this.value = stream.readNull();\n    } else {\n      throw new Error(`Modification: unknown variable type ${this.variableType}`);\n    }\n\n    this.u1 = stream.readInt32();\n  }\n\n  save(stream: BinaryStream, useOptionalInts: boolean): void {\n    stream.writeBinary(this.id);\n    stream.writeInt32(this.variableType);\n\n    if (useOptionalInts) {\n      stream.writeInt32(this.levelOrVariation);\n      stream.writeInt32(this.dataPointer);\n    }\n\n    if (this.variableType === 0) {\n      stream.writeInt32(<number>this.value);\n    } else if (this.variableType === 1 || this.variableType === 2) {\n      stream.writeFloat32(<number>this.value);\n    } else if (this.variableType === 3) {\n      stream.writeNull(<string>this.value);\n    } else {\n      throw new Error(`Modification: unknown variable type ${this.variableType}`);\n    }\n\n    stream.writeInt32(this.u1);\n  }\n\n  getByteLength(useOptionalInts: boolean): number {\n    let size = 12;\n\n    if (useOptionalInts) {\n      size += 8;\n    }\n\n    if (this.variableType === 3) {\n      size += byteLengthUtf8(<string>this.value) + 1;\n    } else {\n      size += 4;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3u/modificationtable.ts",
    "content": "import BinaryStream from \"../../../common/binarystream\";\nimport ModifiedObject from \"./modifiedobject\";\n\n/**\n * A modification table.\n */\nexport default class ModificationTable {\n  objects: ModifiedObject[] = [];\n\n  load(\n    stream: BinaryStream,\n    useOptionalInts: boolean,\n    formatVersion: number\n  ): void {\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const object = new ModifiedObject();\n\n      object.load(stream, useOptionalInts, formatVersion);\n\n      this.objects[i] = object;\n    }\n  }\n\n  save(\n    stream: BinaryStream,\n    useOptionalInts: boolean,\n    formatVersion: number\n  ): void {\n    stream.writeUint32(this.objects.length);\n\n    for (const object of this.objects) {\n      object.save(stream, useOptionalInts, formatVersion);\n    }\n  }\n\n  getByteLength(useOptionalInts: boolean, formatVersion: number): number {\n    let size = 4;\n\n    for (const object of this.objects) {\n      size += object.getByteLength(useOptionalInts, formatVersion);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/w3u/modifiedobject.ts",
    "content": "import BinaryStream from \"../../../common/binarystream\";\nimport Modification from \"./modification\";\n\n/**\n * A modified object.\n */\nexport default class ModifiedObject {\n  oldId = \"\\0\\0\\0\\0\";\n  newId = \"\\0\\0\\0\\0\";\n  sets = 1;\n  setsFlag: number[] = [];\n  modifications: Modification[] = [];\n\n  load(\n    stream: BinaryStream,\n    useOptionalInts: boolean,\n    formatVersion: number\n  ): void {\n    this.oldId = stream.readBinary(4);\n    this.newId = stream.readBinary(4);\n\n    if (formatVersion >= 3) {\n      this.sets = stream.readUint32();\n    }\n\n    for (let set = 0; set < this.sets; set++) {\n      if (formatVersion >= 3) {\n        this.setsFlag[set] = stream.readUint32();\n      }\n\n      for (let i = 0, l = stream.readUint32(); i < l; i++) {\n        const modification = new Modification();\n\n        modification.load(stream, useOptionalInts);\n\n        this.modifications[i] = modification;\n      }\n    }\n  }\n\n  save(\n    stream: BinaryStream,\n    useOptionalInts: boolean,\n    formatVersion: number\n  ): void {\n    if (this.oldId !== \"\\0\\0\\0\\0\") {\n      stream.writeBinary(this.oldId);\n    } else {\n      stream.writeUint32(0);\n    }\n\n    if (this.newId !== \"\\0\\0\\0\\0\") {\n      stream.writeBinary(this.newId);\n    } else {\n      stream.writeUint32(0);\n    }\n\n    if (formatVersion >= 3) {\n      stream.writeUint32(this.sets);\n    }\n\n    stream.writeUint32(this.modifications.length);\n\n    for (let set = 0; set < this.sets; set++) {\n      if (formatVersion >= 3) {\n        stream.writeUint32(this.setsFlag[set]);\n      }\n      for (const modification of this.modifications) {\n        modification.save(stream, useOptionalInts);\n      }\n    }\n  }\n\n  getByteLength(useOptionalInts: boolean, formatVersion: number): number {\n    let size = formatVersion >= 3 ? 16 : 12;\n\n    for (let set = 0; set < this.sets; set++) {\n      if (formatVersion >= 3) {\n        size += 4;\n      }\n      for (const modification of this.modifications) {\n        size += modification.getByteLength(useOptionalInts);\n      }\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wct/customtexttrigger.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A custom text trigger.\n */\nexport default class CustomTextTrigger {\n  text = '';\n\n  load(stream: BinaryStream): void {\n    const textLength = stream.readInt32();\n\n    if (textLength) {\n      this.text = stream.read(textLength - 1);\n      stream.skip(1);\n    }\n  }\n\n  save(stream: BinaryStream): void {\n    if (this.text.length) {\n      stream.writeInt32(byteLengthUtf8(this.text) + 1);\n      stream.write(this.text);\n      stream.skip(1);\n    } else {\n      stream.writeInt32(0);\n    }\n  }\n\n  getByteLength(): number {\n    let size = 4;\n\n    if (this.text.length) {\n      size += byteLengthUtf8(this.text) + 1;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wct/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport CustomTextTrigger from './customtexttrigger';\n\n/**\n * war3map.wct - the custom text (jass) trigger file.\n */\nexport default class War3MapWct {\n  version = 0;\n  comment = '';\n  trigger = new CustomTextTrigger();\n  triggers: CustomTextTrigger[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    this.version = stream.readInt32();\n\n    if (this.version === 1) {\n      this.comment = stream.readNull();\n\n      this.trigger.load(stream);\n    }\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const trigger = new CustomTextTrigger();\n\n      trigger.load(stream);\n\n      this.triggers[i] = trigger;\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeInt32(this.version);\n\n    if (this.version === 1) {\n      stream.writeNull(this.comment);\n\n      this.trigger.save(stream);\n    }\n\n    stream.writeUint32(this.triggers.length);\n\n    for (const trigger of this.triggers) {\n      trigger.save(stream);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 8;\n\n    if (this.version === 1) {\n      size += byteLengthUtf8(this.comment) + 1 + this.trigger.getByteLength();\n    }\n\n    for (const trigger of this.triggers) {\n      size += trigger.getByteLength();\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wct/index.ts",
    "content": "import File from './file';\nimport CustomTextTrigger from './customtexttrigger';\n\nexport default {\n  File,\n  CustomTextTrigger,\n};\n"
  },
  {
    "path": "src/parsers/w3x/wpm/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\n\n/**\n * war3map.wpm - the pathing file.\n */\nexport default class War3MapWpm {\n  version = 0;\n  size = new Int32Array(2);\n  pathing = new Uint8Array(0);\n\n  load(buffer: ArrayBuffer | Uint8Array): void {\n    const stream = new BinaryStream(buffer);\n\n    if (stream.readBinary(4) !== 'MP3W') {\n      return;\n    }\n\n    this.version = stream.readInt32();\n    stream.readInt32Array(this.size);\n    this.pathing = stream.readUint8Array(this.size[0] * this.size[1]);\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeBinary('MP3W');\n    stream.writeInt32(this.version);\n    stream.writeInt32Array(this.size);\n    stream.writeUint8Array(this.pathing);\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    return 16 + (this.size[0] * this.size[1]);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wpm/index.ts",
    "content": "import File from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/parsers/w3x/wtg/eca.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport Parameter from './parameter';\nimport { TriggerData } from './triggerdata';\n\n/**\n * An Event/Condition/Action.\n */\nexport default class ECA {\n  type = -1;\n  group = -1;\n  name = '';\n  isEnabled = 0;\n  parameters: Parameter[] = [];\n  ecas: ECA[] = [];\n\n  load(stream: BinaryStream, version: number, isChildECA: boolean, triggerData: TriggerData): void {\n    this.type = stream.readInt32();\n\n    if (this.type < 0 || this.type > 3) {\n      throw new Error(`ECA: Bad type: ${this.type}`);\n    }\n\n    if (isChildECA) {\n      this.group = stream.readUint32();\n    }\n\n    this.name = stream.readNull();\n\n    if (this.name.length === 0) {\n      throw new Error('ECA: Empty name');\n    }\n\n    this.isEnabled = stream.readInt32();\n\n    const signature = triggerData.getFunction(this.type, this.name);\n\n    if (!signature) {\n      throw new Error(`ECA \"${this.name}:${this.type}\": Unknown signature`);\n    }\n\n    const args = signature.args;\n\n    for (let i = 0, l = args.length; i < l; i++) {\n      const parameter = new Parameter();\n\n      try {\n        parameter.load(stream, version, triggerData);\n      } catch (e) {\n        throw new Error(`ECA \"${this.name}\": Parameter ${i}: ${e}`);\n      }\n\n      this.parameters[i] = parameter;\n    }\n\n    if (version === 7) {\n      for (let i = 0, l = stream.readUint32(); i < l; i++) {\n        const eca = new ECA();\n\n        try {\n          eca.load(stream, version, true, triggerData);\n        } catch (e) {\n          throw new Error(`ECA \"${this.name}\": Child ECA ${i} ${e}`);\n        }\n\n        this.ecas[i] = eca;\n      }\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeInt32(this.type);\n\n    if (this.group !== -1) {\n      stream.writeInt32(this.group);\n    }\n\n    stream.writeNull(this.name);\n    stream.writeInt32(this.isEnabled);\n\n    for (const parameter of this.parameters) {\n      parameter.save(stream, version);\n    }\n\n    if (version === 7) {\n      stream.writeUint32(this.ecas.length);\n\n      for (const eca of this.ecas) {\n        eca.save(stream, version);\n      }\n    }\n  }\n\n  getByteLength(version: number): number {\n    let size = 9 + byteLengthUtf8(this.name);\n\n    if (this.group !== -1) {\n      size += 4;\n    }\n\n    for (const parameter of this.parameters) {\n      size += parameter.getByteLength(version);\n    }\n\n    if (version === 7) {\n      size += 4;\n\n      for (const eca of this.ecas) {\n        size += eca.getByteLength(version);\n      }\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/file.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport TriggerCategory from './triggercategory';\nimport Variable from './variable';\nimport Trigger from './trigger';\nimport { TriggerData } from './triggerdata';\n\n/**\n * war3map.wtg - the trigger file.\n */\nexport default class War3MapWtg {\n  version = 0;\n  categories: TriggerCategory[] = [];\n  u1 = 0;\n  variables: Variable[] = [];\n  triggers: Trigger[] = [];\n\n  load(buffer: ArrayBuffer | Uint8Array, triggerData: TriggerData): void {\n    const stream = new BinaryStream(buffer);\n\n    if (stream.readBinary(4) !== 'WTG!') {\n      throw new Error('Not a WTG file');\n    }\n\n    this.version = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const category = new TriggerCategory();\n\n      category.load(stream, this.version);\n\n      this.categories[i] = category;\n    }\n\n    this.u1 = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const variable = new Variable();\n\n      variable.load(stream, this.version);\n\n      this.variables[i] = variable;\n    }\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const trigger = new Trigger();\n\n      try {\n        trigger.load(stream, this.version, triggerData);\n      } catch (e) {\n        throw new Error(`Trigger ${i}: ${e}`);\n      }\n\n      this.triggers[i] = trigger;\n    }\n  }\n\n  save(): Uint8Array {\n    const stream = new BinaryStream(new ArrayBuffer(this.getByteLength()));\n\n    stream.writeBinary('WTG!');\n    stream.writeInt32(this.version);\n    stream.writeUint32(this.categories.length);\n\n    for (const category of this.categories) {\n      category.save(stream, this.version);\n    }\n\n    stream.writeInt32(this.u1);\n    stream.writeUint32(this.variables.length);\n\n    for (const variable of this.variables) {\n      variable.save(stream, this.version);\n    }\n\n    stream.writeUint32(this.triggers.length);\n\n    for (const trigger of this.triggers) {\n      trigger.save(stream, this.version);\n    }\n\n    return stream.uint8array;\n  }\n\n  getByteLength(): number {\n    let size = 24;\n    const version = this.version;\n\n    for (const category of this.categories) {\n      size += category.getByteLength(version);\n    }\n\n    for (const variable of this.variables) {\n      size += variable.getByteLength(version);\n    }\n\n    for (const trigger of this.triggers) {\n      size += trigger.getByteLength(version);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/index.ts",
    "content": "import File from './file';\nimport TriggerCategory from './triggercategory';\nimport Variable from './variable';\nimport Trigger from './trigger';\nimport ECA from './eca';\nimport Parameter from './parameter';\nimport SubParameters from './subparameters';\nimport { TriggerData } from './triggerdata';\n\nexport default {\n  File,\n  TriggerCategory,\n  Variable,\n  Trigger,\n  ECA,\n  Parameter,\n  SubParameters,\n  TriggerData,\n};\n"
  },
  {
    "path": "src/parsers/w3x/wtg/parameter.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport SubParameters from './subparameters';\nimport { TriggerData } from './triggerdata';\n\n/**\n * A function parameter. Can be a function itself, in which case it will have a SubParameters structure.\n */\nexport default class Parameter {\n  type = 0;\n  value = '';\n  subParameters: SubParameters | null = null;\n  u1 = 0;\n  isArray = 0;\n  arrayIndex: Parameter | null = null;\n\n  load(stream: BinaryStream, version: number, triggerData: TriggerData): void {\n    this.type = stream.readInt32();\n\n    if (this.type < -1 || this.type > 3) {\n      throw new Error(`Parameter: Bad type: ${this.type}`);\n    }\n\n    this.value = stream.readNull();\n\n    if (stream.readInt32()) {\n      const subParameters = new SubParameters();\n\n      try {\n        subParameters.load(stream, version, triggerData);\n      } catch (e) {\n        throw new Error(`Parameter \"${this.value}\": SubParameters ${e}`);\n      }\n\n      this.subParameters = subParameters;\n    }\n\n    if ((version === 4 && this.type === 2) || (version === 7 && this.subParameters)) {\n      this.u1 = stream.readInt32();\n    }\n\n    if ((version === 4 && this.type !== 2) || version === 7) {\n      this.isArray = stream.readInt32();\n    }\n\n    if (this.isArray) {\n      const arrayIndex = new Parameter();\n\n      try {\n        arrayIndex.load(stream, version, triggerData);\n      } catch (e) {\n        throw new Error(`Parameter \"${this.value}\": ArrayIndex: ${e}`);\n      }\n\n      this.arrayIndex = arrayIndex;\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeInt32(this.type);\n    stream.writeNull(this.value);\n\n    if (this.subParameters) {\n      stream.writeInt32(1);\n      this.subParameters.save(stream, version);\n    } else {\n      stream.writeInt32(0);\n    }\n\n    if ((version === 4 && this.type === 2) || (version === 7 && this.subParameters)) {\n      stream.writeInt32(this.u1);\n    }\n\n    if ((version === 4 && this.type !== 2) || version === 7) {\n      stream.writeInt32(this.isArray);\n    }\n\n    if (this.isArray && this.arrayIndex) {\n      this.arrayIndex.save(stream, version);\n    }\n  }\n\n  getByteLength(version: number): number {\n    let size = 9 + byteLengthUtf8(this.value);\n\n    if (this.subParameters) {\n      size += this.subParameters.getByteLength(version);\n    }\n\n    if ((version === 4 && this.type === 2) || (version === 7 && this.subParameters)) {\n      size += 4;\n    }\n\n    if ((version === 4 && this.type !== 2) || version === 7) {\n      size += 4;\n    }\n\n    if (this.isArray && this.arrayIndex) {\n      size += this.arrayIndex.getByteLength(version);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/subparameters.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport Parameter from './parameter';\nimport { TriggerData } from './triggerdata';\n\n/**\n * A function call in an expression.\n */\nexport default class SubParameters {\n  type = 0;\n  name = '';\n  beginParameters = 0;\n  parameters: Parameter[] = [];\n\n  load(stream: BinaryStream, version: number, triggerData: TriggerData): void {\n    this.type = stream.readInt32();\n\n    if (this.type < 0 || this.type > 3) {\n      throw new Error(`SubParameters: Bad type: ${this.type}`);\n    }\n\n    this.name = stream.readNull();\n\n    if (this.name.length === 0) {\n      throw new Error(`SubParameters: Empty name`);\n    }\n\n    this.beginParameters = stream.readInt32();\n\n    if (this.beginParameters) {\n      const signature = triggerData.getFunction(this.type, this.name);\n\n      if (!signature) {\n        throw new Error(`SubParameters \"${this.name}:${this.type}\": Unknown signature`);\n      }\n\n      const args = signature.args;\n\n      for (let i = 0, l = args.length; i < l; i++) {\n        const parameter = new Parameter();\n\n        try {\n          parameter.load(stream, version, triggerData);\n        } catch (e) {\n          throw new Error(`SubParameters \"${this.name}\": Parameter ${i}: ${e}`);\n        }\n\n        this.parameters[i] = parameter;\n      }\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeInt32(this.type);\n    stream.writeNull(this.name);\n    stream.writeInt32(this.beginParameters);\n\n    for (const parameter of this.parameters) {\n      parameter.save(stream, version);\n    }\n  }\n\n  getByteLength(version: number): number {\n    let size = 9 + byteLengthUtf8(this.name);\n\n    if (this.parameters.length) {\n      for (const parameter of this.parameters) {\n        size += parameter.getByteLength(version);\n      }\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/trigger.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\nimport ECA from './eca';\nimport { TriggerData } from './triggerdata';\n\n/**\n * A GUI Trigger.\n */\nexport default class Trigger {\n  name = '';\n  description = '';\n  isComment = 0;\n  isEnabled = 0;\n  isCustom = 0;\n  isInitiallyOff = 0;\n  runOnInitialization = 0;\n  category = 0;\n  ecas: ECA[] = [];\n\n  load(stream: BinaryStream, version: number, triggerData: TriggerData): void {\n    this.name = stream.readNull();\n    this.description = stream.readNull();\n\n    if (version === 7) {\n      this.isComment = stream.readInt32();\n    }\n\n    this.isEnabled = stream.readInt32();\n    this.isCustom = stream.readInt32();\n    this.isInitiallyOff = stream.readInt32();\n    this.runOnInitialization = stream.readInt32();\n    this.category = stream.readInt32();\n\n    for (let i = 0, l = stream.readUint32(); i < l; i++) {\n      const eca = new ECA();\n\n      try {\n        eca.load(stream, version, false, triggerData);\n      } catch (e) {\n        throw new Error(`Trigger \"${this.name}\": ECA ${i}: ${e}`);\n      }\n\n      this.ecas[i] = eca;\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeNull(this.name);\n    stream.writeNull(this.description);\n\n    if (version === 7) {\n      stream.writeInt32(this.isComment);\n    }\n\n    stream.writeInt32(this.isEnabled);\n    stream.writeInt32(this.isCustom);\n    stream.writeInt32(this.isInitiallyOff);\n    stream.writeInt32(this.runOnInitialization);\n    stream.writeInt32(this.category);\n    stream.writeUint32(this.ecas.length);\n\n    for (const eca of this.ecas) {\n      eca.save(stream, version);\n    }\n  }\n\n  getByteLength(version: number): number {\n    let size = 26 + byteLengthUtf8(this.name) + byteLengthUtf8(this.description);\n\n    if (version === 7) {\n      size += 4;\n    }\n\n    for (const eca of this.ecas) {\n      size += eca.getByteLength(version);\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/triggercategory.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A Trigger category.\n * \n * Used to scope triggers together in a Folder-like hierarchy.\n */\nexport default class TriggerCategory {\n  id = 0;\n  name = '';\n  isComment = 0;\n\n  load(stream: BinaryStream, version: number): void {\n    this.id = stream.readInt32();\n    this.name = stream.readNull();\n\n    if (version === 7) {\n      this.isComment = stream.readInt32();\n    }\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeInt32(this.id);\n    stream.writeNull(this.name);\n\n    if (version === 7) {\n      stream.writeInt32(this.isComment);\n    }\n  }\n\n  getByteLength(version: number): number {\n    let size = 5 + byteLengthUtf8(this.name);\n\n    if (version === 7) {\n      size += 4;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/triggerdata.ts",
    "content": "import TokenStream from '../../../utils/jass2/tokenstream';\nimport { IniSection, IniFile } from '../../ini/file';\n\n/**\n * A standard object mapping strings to strings.\n */\nexport type StringObject = {[key: string]: string };\n\n\nexport type FunctionSignature = { args: string[], scriptName: string | null, returnType: string | null };\n\n/**\n * A standard object mapping strings to function signatures and an optional Jass name.\n */\nexport type FunctionObject = {[key: string]: FunctionSignature };\n\n/**\n * Trigger data needed to load a WTG file.\n */\nexport class TriggerData {\n  types: StringObject = {};\n  functions: FunctionObject[] = [{}, {}, {}, {}];\n  presets: StringObject = {};\n  externalTypes: StringObject = {};\n  externalFunctions: FunctionObject[] = [{}, {}, {}, {}];\n  externalPresets: StringObject = {};\n\n  addTriggerData(buffer: string, isExternal: boolean): void {\n    let types = this.types;\n    let functions = this.functions;\n    let presets = this.presets;\n\n    if (isExternal) {\n      types = this.externalTypes;\n      functions = this.externalFunctions;\n      presets = this.externalPresets;\n    }\n\n    const triggerData = new IniFile();\n\n    triggerData.load(buffer);\n\n    let section = triggerData.getSection('TriggerTypes');\n    if (section) {\n      this.addTriggerTypes(types, section);\n    }\n\n    section = triggerData.getSection('TriggerEvents');\n    if (section) {\n      this.addTriggerDataFunctions(functions[0], section, 1);\n    }\n\n    section = triggerData.getSection('TriggerConditions');\n    if (section) {\n      this.addTriggerDataFunctions(functions[1], section, 1);\n    }\n\n    section = triggerData.getSection('TriggerActions');\n    if (section) {\n      this.addTriggerDataFunctions(functions[2], section, 1);\n    }\n\n    section = triggerData.getSection('TriggerCalls');\n    if (section) {\n      this.addTriggerDataFunctions(functions[3], section, 3);\n    }\n\n    section = triggerData.getSection('TriggerParams');\n    if (section) {\n      this.addTriggerDataPresets(presets, section);\n    }\n  }\n\n  addTriggerTypes(types: StringObject, section: IniSection): void {\n    for (const [key, value] of section) {\n      // We know the values are going to be strings.\n      const tokens = value.split(',');\n\n      types[key.toLowerCase()] = tokens[4] || '';\n    }\n  }\n\n  addTriggerDataFunctions(functions: FunctionObject, section: IniSection, skipped: number): void {\n    for (const [key, value] of section) {\n      // We don't care about metadata lines.\n      if (key[0] !== '_') {\n        // We know the values are going to be strings.\n        const tokens = value.split(',');\n        const args = [];\n\n        // Can be used by actions to make aliases.\n        const scriptName = <string>section.get(`_${key}_scriptname`) || null;\n\n        let returnType = null;\n\n        // TriggerCalls have a return type.\n        if (skipped === 3) {\n          returnType = tokens[2];\n        }\n\n        for (let i = skipped, l = tokens.length; i < l; i++) {\n          const token = tokens[i];\n\n          // We don't care about constants.\n          if (Number.isNaN(parseFloat(token)) && token !== 'nothing' && token !== '') {\n            args.push(token);\n          }\n        }\n\n        functions[key.toLowerCase()] = { args, scriptName, returnType };\n      }\n    }\n  }\n\n  addTriggerDataPresets(presets: StringObject, section: IniSection): void {\n    for (const [key, value] of section) {\n      // We know the values are going to be strings.\n      const tokens = value.split(',');\n\n      // Note that the operators are enclosed by \"\" for some reason.\n      // Note that string literals are enclosed by backticks.\n      presets[key.toLowerCase()] = tokens[2].replace(/\"/g, '').replace(/`/g, '\"');\n    }\n  }\n\n  addJassFunctions(jass: string): void {\n    const stream = new TokenStream(jass);\n    let token;\n\n    while ((token = stream.read()) !== undefined) {\n      if (token === 'native' || token === 'function') {\n        const scriptName = stream.read();\n\n        if (scriptName) {\n          token = stream.read();\n\n          if (token === 'takes') {\n            const args = [];\n            const token = stream.readSafe(); // nothing or type\n\n            if (token !== 'nothing') {\n              args.push(token);\n              stream.readSafe();\n\n              while (stream.read() === ',') {\n                args.push(stream.readSafe());\n                stream.readSafe();\n              }\n            } else {\n              stream.read(); // returns\n            }\n\n            let returnType: string | null = stream.readSafe();\n\n            if (returnType === 'nothing') {\n              returnType = null;\n            }\n\n            const name = scriptName.toLowerCase();\n            const signature = { args, scriptName, returnType };\n\n            // There is no way to know if this signature could be used as a TriggerAction or TriggerCall.\n            // So try to always add to TriggerAction...\n            this.externalFunctions[2][name] = signature;\n\n            // ...and if there is a return type, add also to TriggerCall.\n            if (returnType !== 'nothing') {\n              this.externalFunctions[3][name] = signature;\n            }\n          }\n        }\n      }\n    }\n  }\n\n  /**\n   * Given a type, return its base type.\n   * \n   * Returns the given type if its not a child type.\n   */\n  getBaseType(type: string): string {\n    type = type.toLowerCase();\n\n    let base = this.types[type];\n\n    if (base === undefined) {\n      base = this.externalTypes[type];\n    }\n\n    // Same as !base, but be explicit to be clearer.\n    if (base === '' || base === undefined) {\n      return type;\n    }\n\n    return base;\n  }\n\n  isBaseFunction(type: number, name: string): boolean {\n    name = name.toLowerCase();\n\n    if (this.functions[type][name]) {\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Gets the signature of the given function.\n   */\n  getFunction(type: number, name: string): FunctionSignature {\n    name = name.toLowerCase();\n\n    let args = this.functions[type][name];\n\n    if (!args) {\n      args = this.externalFunctions[type][name];\n    }\n\n    return args;\n  }\n\n  /**\n   * Get the type of a function given its name.\n   * Returns -1 if the function isn't recognized.\n   */\n  getFunctionType(name: string): number {\n    name = name.toLowerCase();\n\n    const functions = this.functions;\n\n    for (let i = 0; i < 4; i++) {\n      if (functions[i][name]) {\n        return i;\n      }\n    }\n\n    return -1;\n  }\n\n  /**\n   * Gets a preset value.\n   */\n  getPreset(name: string): string {\n    name = name.toLowerCase();\n\n    let preset = this.presets[name];\n\n    if (preset === undefined) {\n      preset = this.externalPresets[name];\n    }\n\n    return preset;\n  }\n\n  /**\n   * Is the given preset a custom or standard one?\n   */\n  isCustomPreset(name: string): boolean {\n    name = name.toLowerCase();\n\n    if (this.presets[name] !== undefined) {\n      return false;\n    }\n\n    if (this.externalPresets[name] !== undefined) {\n      return true;\n    }\n\n    throw new Error(`Failed to find a preset: ${name}`);\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wtg/variable.ts",
    "content": "import BinaryStream from '../../../common/binarystream';\nimport { byteLengthUtf8 } from '../../../common/utf8';\n\n/**\n * A global variable.\n */\nexport default class Variable {\n  name = '';\n  type = '';\n  u1 = 0;\n  isArray = 0;\n  arraySize = 0;\n  isInitialized = 0;\n  initialValue = '';\n\n  load(stream: BinaryStream, version: number): void {\n    this.name = stream.readNull();\n    this.type = stream.readNull();\n    this.u1 = stream.readInt32();\n    this.isArray = stream.readInt32();\n\n    if (version === 7) {\n      this.arraySize = stream.readInt32();\n    }\n\n    this.isInitialized = stream.readInt32();\n    this.initialValue = stream.readNull();\n  }\n\n  save(stream: BinaryStream, version: number): void {\n    stream.writeNull(this.name);\n    stream.writeNull(this.type);\n    stream.writeInt32(this.u1);\n    stream.writeInt32(this.isArray);\n\n    if (version === 7) {\n      stream.writeInt32(this.arraySize);\n    }\n\n    stream.writeInt32(this.isInitialized);\n    stream.writeNull(this.initialValue);\n  }\n\n  getByteLength(version: number): number {\n    let size = 15 + byteLengthUtf8(this.name) + byteLengthUtf8(this.type) + byteLengthUtf8(this.initialValue);\n\n    if (version === 7) {\n      size += 4;\n    }\n\n    return size;\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wts/file.ts",
    "content": "import TokenStream from '../../mdlx/tokenstream';\n\n/**\n * war3map.wts - the string table file.\n *\n * Contains a map of number->string.\n * When other map data like triggers use the string TRIGSTR_XXX, where XXX is a number, the value will be fetched from the table.\n */\nexport default class War3MapWts {\n  stringMap: Map<number, string> = new Map();\n\n  load(buffer: string): void {\n    const stream = new TokenStream(buffer);\n    let token;\n\n    // Find the first instance of \"STRING\".\n    // There are some weird war3map.wts files that begin with the bytes \"ï»¿\", and this causes the tokenizer to see the first token as \"ï»¿STRING\".\n    // Going to the first \"STRING\" means we can ignore any weird bytes that happened to be before.\n    const start = buffer.indexOf('STRING');\n\n    // Can war3map.wts have no entries? I don't know, might as well add a condition.\n    if (start === -1) {\n      throw new Error('Not a valid war3map.wts buffer');\n    }\n\n    stream.index = start;\n\n    while ((token = stream.readToken())) {\n      if (token === 'STRING') {\n        const index = stream.readInt();\n\n        stream.read(); // {\n\n        const end = buffer.indexOf('}', stream.index);\n\n        // For broken files, keep whatever data can be kept, and throw an exception.\n        if (end === -1) {\n          this.stringMap.set(index, buffer.slice(stream.index, buffer.length).trim());\n\n          throw new Error(`WTS: missing data in string ${this.stringMap.size} (and maybe more)`);\n        }\n\n        this.stringMap.set(index, buffer.slice(stream.index, end).trim());\n\n        stream.index = end;\n      }\n    }\n  }\n\n  save(): string {\n    let buffer = '';\n\n    for (const [key, value] of this.stringMap) {\n      buffer += `STRING ${key}\\r\\n{\\r\\n${value}\\r\\n}\\r\\n\\r\\n`;\n    }\n\n    return buffer;\n  }\n\n  /**\n   * Get the string at the given index.\n   * \n   * Strings in the form \"TRIGSTR_nnn\" are also supported.\n   */\n  getString(index: number | string): string | undefined {\n    if (typeof index === 'string') {\n      if (index.startsWith('TRIGSTR_')) {\n        return this.stringMap.get(parseInt(index.slice(8)));\n      }\n    } else {\n      return this.stringMap.get(index);\n    }\n\n    return;\n  }\n\n  /**\n   * Set the string at the given index.\n   * \n   * Strings in the form \"TRIGSTR_nnn\" are also supported.\n   */\n  setString(index: number | string, value: string): void {\n    if (typeof index === 'string') {\n      if (index.startsWith('TRIGSTR_')) {\n        this.stringMap.set(parseInt(index.slice(8)), value);\n      }\n    } else {\n      this.stringMap.set(index, value);\n    }\n  }\n}\n"
  },
  {
    "path": "src/parsers/w3x/wts/index.ts",
    "content": "import File from './file';\n\nexport default {\n  File,\n};\n"
  },
  {
    "path": "src/utils/blp/index.ts",
    "content": "import sanityTest from './sanitytest';\n\nexport default {\n  sanityTest,\n};\n"
  },
  {
    "path": "src/utils/blp/sanitytest.ts",
    "content": "import { isPowerOfTwo } from '../../common/math';\nimport { BlpImage } from '../../parsers/blp/image';\n\n/**\n * Some tools allow to setup fake mipmaps.\n * These are mipmaps that use the same JPG data as other mipmaps.\n * This is technically not valid, but can work properly in the game.\n * Not always though.\n * Sadly I don't quite know the rules.\n */\nfunction isMipmapFake(whichMipmap: number, mipmapOffsets: Uint32Array): boolean {\n  const offset = mipmapOffsets[whichMipmap];\n\n  for (let i = 0; i < whichMipmap; i++) {\n    if (mipmapOffsets[i] === offset) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nexport interface SanityTestNode {\n  type: string;\n  message: string;\n}\n\nexport interface SanityTestResult {\n  nodes: SanityTestNode[];\n  warnings: number;\n}\n\n/**\n * Tests for issues in BLP textures.\n */\nexport default function sanityTest(texture: BlpImage): SanityTestResult {\n  const nodes = [];\n  const content = texture.content;\n  const alphaBits = texture.alphaBits;\n  const mipmapOffsets = texture.mipmapOffsets;\n  const mipmapSizes = texture.mipmapSizes;\n  let width = texture.width;\n  let height = texture.height;\n\n  if (content !== 0 && content !== 1) {\n    nodes.push({ type: 'warning', message: 'Unknown content type' });\n  }\n\n  if (alphaBits !== 0 && alphaBits !== 1 && alphaBits !== 4 && alphaBits !== 8) {\n    nodes.push({ type: 'warning', message: `Expected alpha bits to be 0, 1, 4, or 8, but got ${alphaBits}` });\n  }\n\n  if (width > 512 || height > 512) {\n    nodes.push({ type: 'warning', message: `Expected width and height up to 512, but got ${width}x${height}` });\n  }\n\n  if (content === 0) {\n    const jpgHeader = <Uint8Array>texture.jpgHeader;\n\n    if (jpgHeader.length > 624) {\n      nodes.push({ type: 'warning', message: `Expected the JPG header to be at most 624 bytes, but got ${jpgHeader.length}` });\n    }\n  }\n\n  if (!isPowerOfTwo(width) || !isPowerOfTwo(height)) {\n    nodes.push({ type: 'warning', message: `Expected the width and height to be powers of two, but got ${width}x${height}` });\n  }\n\n  for (let i = 0; i < 16; i++) {\n    if (mipmapSizes[i] > 0) {\n      // This happens if this mipmap level supposedly exists, but we already passed the level that should have been last.\n      if (width < 1 && height < 1) {\n        nodes.push({ type: 'warning', message: `Mipmap ${i}: this mipmap should not exist` });\n      } else if (isMipmapFake(i, mipmapOffsets)) {\n        nodes.push({ type: 'warning', message: `Mipmap ${i}: this mipmap is fake` });\n      } else {\n        // In the case this is not a square texture, one dimension will get to size 1 before the other.\n        width = Math.max(width, 1);\n        height = Math.max(height, 1);\n\n        let mipmapData;\n\n        try {\n          mipmapData = texture.getMipmap(i);\n        } catch (e) {\n          nodes.push({ type: 'warning', message: `Mipmap ${i}: Decoding failed` });\n        }\n\n        if (mipmapData) {\n          if (content === 0) {\n            if (mipmapData.width !== width || mipmapData.height !== height) {\n              nodes.push({ type: 'warning', message: `Mipmap ${i}: the JPG width (${mipmapData.width}) and height (${mipmapData.height}) do not match the mipmap width (${width}) and height (${height})` });\n            }\n          } else if (content === 1) {\n            const pixels = width * height;\n            const size = pixels + Math.ceil((pixels * alphaBits) / 8);\n\n            if (size !== mipmapSizes[i]) {\n              nodes.push({ type: 'warning', message: `Mipmap ${i}: the declared size is ${mipmapSizes[i]}, but the real size is ${size}` });\n            }\n          }\n        }\n      }\n    }\n\n    width >>= 1;\n    height >>= 1;\n  }\n\n  return { nodes, warnings: nodes.length };\n}\n"
  },
  {
    "path": "src/utils/dds/index.ts",
    "content": "import sanityTest from './sanitytest';\n\nexport default {\n  sanityTest,\n};\n"
  },
  {
    "path": "src/utils/dds/sanitytest.ts",
    "content": "import { isPowerOfTwo } from '../../common/math';\nimport { DdsImage } from '../../parsers/dds/image';\n\nexport interface SanityTestNode {\n  type: string;\n  message: string;\n}\n\nexport interface SanityTestResult {\n  nodes: SanityTestNode[];\n  warnings: number;\n}\n\n/**\n * Tests for issues in DDS textures.\n */\nexport default function sanityTest(texture: DdsImage): SanityTestResult {\n  \n  const nodes = [];\n  const width = texture.width;\n  const height = texture.height;\n  const mipmaps = texture.mipmaps();\n  const expectedMipmaps = Math.log2(Math.max(width, height));\n\n  if (mipmaps < expectedMipmaps) {\n    nodes.push({ type: 'warning', message: `Expected ${expectedMipmaps} mipmaps, but got ${mipmaps}` });\n  }\n\n  if ((width % 4 !== 0) || (height % 4 !== 0)) {\n    nodes.push({ type: 'warning', message: `Expected the width and height to be multiples of four, but got ${width}x${height}` });\n  }\n\n  if (!isPowerOfTwo(width) || !isPowerOfTwo(height)) {\n    nodes.push({ type: 'warning', message: `Expected the width and height to be powers of two, but got ${width}x${height}` });\n  }\n\n  for (let i = 0; i < mipmaps; i++) {\n    try {\n      texture.getMipmap(i);\n    } catch (e) {\n      nodes.push({ type: 'warning', message: `Mipmap ${i}: Decoding failed` });\n    }\n  }\n\n  return { nodes, warnings: nodes.length };\n}\n"
  },
  {
    "path": "src/utils/index.ts",
    "content": "import blp from './blp';\nimport dds from './dds';\nimport { MappedData } from './mappeddata';\nimport jass2 from './jass2';\nimport mdlx from './mdlx';\nimport w3x from './w3x';\n\nexport default {\n  blp,\n  dds,\n  MappedData,\n  jass2,\n  mdlx,\n  w3x,\n};\n"
  },
  {
    "path": "src/utils/jass2/compilenatives.ts",
    "content": "import TokenStream from './tokenstream';\n\nfunction compileGetters(params: { type: string, name: string }[]): string {\n  return params.map((p, i) => {\n    const type = p.type;\n\n    if (type === 'code') {\n      return `let _${p.name} = luaL_ref(L, LUA_REGISTRYINDEX);`;\n    } else {\n      let func;\n\n      if (type === 'integer') {\n        func = 'luaL_checkinteger';\n      } else if (type === 'real') {\n        func = 'luaL_checknumber';\n      } else if (type === 'boolean') {\n        func = 'lua_toboolean';\n      } else if (type === 'string') {\n        func = 'luaL_checkstring';\n      } else {\n        func = 'lua_touserdata';\n      }\n\n      return `let _${p.name} = ${func}(L, ${i + 1});`;\n    }\n  }).join('\\n');\n}\n\nfunction compileReturn(type: string): string {\n  if (type === 'nothing') {\n    return 'return 0';\n  } else {\n    let func;\n    let value;\n\n    if (type === 'integer') {\n      func = 'lua_pushinteger';\n      value = '0';\n    } else if (type === 'real') {\n      func = 'lua_pushnumber';\n      value = '0';\n    } else if (type === 'boolean') {\n      func = 'lua_pushboolean';\n      value = 'false';\n    } else if (type === 'string') {\n      func = 'lua_pushstring';\n      value = `''`;\n    } else if (type === 'code') {\n      throw 'CODE??';\n    } else {\n      func = 'lua_pushlightuserdata';\n      value = `{name: 'FAKE'}`;\n    }\n\n    return `${func}(L, ${value});\\nreturn 1;`;\n  }\n}\n\nfunction compileNative(stream: TokenStream, isConstant: boolean): { name: string, decl: string } {\n  const name = stream.readSafe();\n  const params = [];\n\n  stream.read(); // takes\n\n  const token = stream.readSafe(); // nothing or type\n\n  if (token !== 'nothing') {\n    params.push({ type: token, name: stream.readSafe() });\n\n    while (stream.read() === ',') {\n      params.push({ type: stream.readSafe(), name: stream.readSafe() });\n    }\n  } else {\n    stream.read(); // returns\n  }\n\n  const returnType = stream.readSafe();\n  let luaParams;\n\n  if (params.length) {\n    luaParams = 'C: Context, L: lua_State';\n  } else {\n    luaParams = '_C: Context, _L: lua_State';\n  }\n\n  const decl = `\n/**\n * ${isConstant ? 'constant ' : ''}native ${name} takes ${params.length ? params.map((p) => `${p.type} ${p.name}`).join(', ') : 'nothing'} returns ${returnType}\n */\nfunction ${name}(${luaParams}): number {\n  ${compileGetters(params)}\n  console.warn('${name} was called but is not implemented :(');\n  ${compileReturn(returnType)}\n}`;\n\n  return { name, decl };\n}\n\nfunction compileBindings(names: string[]): string {\n  return `\n/**\n * Bind natives to the given context.\n */\nexport default function bind(C: Context): void {\\nlet L = C.L;\\n${names.map((name) => `  lua_register(L, '${name}', ${name}.bind(null, C));`).join('\\n')}\\n}`;\n}\n\nexport default function compileNatives(jass: string): string {\n  const stream = new TokenStream(jass);\n  const names = [];\n  const decls = [];\n  let token;\n\n  while ((token = stream.read()) !== undefined) {\n    let isConstant = false;\n\n    if (token === 'constant') {\n      isConstant = true;\n\n      token = stream.read();\n    }\n\n    if (token === 'native') {\n      const { name, decl } = compileNative(stream, isConstant);\n\n      names.push(name);\n      decls.push(decl);\n    }\n  }\n\n  return `${decls.join('\\n')}\\n${compileBindings(names)}\\n`;\n}\n"
  },
  {
    "path": "src/utils/jass2/constanthandles.ts",
    "content": "import JassPlayerColor from './types/playercolor';\nimport JassRace from './types/race';\nimport JassPlayerGameResult from './types/playergameresult';\nimport JassAllianceType from './types/alliancetype';\nimport JassVersion from './types/version';\nimport JassAttackType from './types/attacktype';\nimport JassDamageType from './types/damagetype';\nimport JassWeaponType from './types/weapontype';\nimport JassPathingType from './types/pathingtype';\nimport JassMouseButtonType from './types/mousebuttontype';\nimport JassAnimType from './types/animtype';\nimport JassSubAnimType from './types/subanimtype';\nimport JassRacePreference from './types/racepreference';\nimport JassMapControl from './types/mapcontrol';\nimport JassGameType from './types/gametype';\nimport JassMapFlag from './types/mapflag';\nimport JassPlacement from './types/placement';\nimport JassStartLocPrio from './types/startlocprio';\nimport JassMapDensity from './types/mapdensity';\nimport JassGameDifficulty from './types/gamedifficulty';\nimport JassGameSpeed from './types/gamespeed';\nimport JassPlayerSlotState from './types/playerslotstate';\nimport JassVolumeGroup from './types/volumegroup';\nimport JassIGameState from './types/igamestate';\nimport JassFGameState from './types/fgamestate';\nimport JassPlayerState from './types/playerstate';\nimport JassUnitState from './types/unitstate';\nimport JassAiDifficulty from './types/aidifficulty';\nimport JassPlayerScore from './types/playerscore';\nimport JassGameEvent from './types/gameevent';\nimport JassPlayerEvent from './types/playerevent';\nimport JassPlayerUnitEvent from './types/playerunitevent';\nimport JassUnitEvent from './types/unitevent';\nimport JassWidgetEvent from './types/widgetevent';\nimport JassDialogEvent from './types/dialogevent';\nimport JassLimitOp from './types/limitop';\nimport JassUnitType from './types/unittype';\nimport JassItemType from './types/itemtype';\nimport JassCameraField from './types/camerafield';\nimport JassBlendMode from './types/blendmode';\nimport JassRarityControl from './types/raritycontrol';\nimport JassTexMapFlags from './types/texmapflags';\nimport JassFogState from './types/fogstate';\nimport JassEffectType from './types/effecttype';\nimport JassSoundType from './types/soundtype';\nimport { JassEventId, JassGameState } from './types';\n\nexport interface ConstantHandles {\n  playerColors: JassPlayerColor[];\n  races: JassRace[];\n  playerGameResults: JassPlayerGameResult[];\n  allianceTypes: JassAllianceType[];\n  versions: JassVersion[];\n  attackTypes: JassAttackType[];\n  damageTypes: JassDamageType[];\n  weaponTypes: JassWeaponType[];\n  pathingTypes: JassPathingType[];\n  mouseButtonTypes: JassMouseButtonType[];\n  animTypes: JassAnimType[];\n  subAnimTypes: JassSubAnimType[];\n  racePrefs: JassRacePreference[];\n  mapControls: JassMapControl[];\n  gameTypes: JassGameType[];\n  mapFlags: JassMapFlag[];\n  placements: JassPlacement[];\n  startLocPrios: JassStartLocPrio[];\n  mapDensities: JassMapDensity[];\n  gameDifficulties: JassGameDifficulty[];\n  gameSpeeds: JassGameSpeed[];\n  playerSlotStates: JassPlayerSlotState[];\n  volumeGroups: JassVolumeGroup[];\n  gameStates: JassGameState[];\n  playerStates: JassPlayerState[];\n  unitStates: JassUnitState[];\n  aiDifficulties: JassAiDifficulty[];\n  playerScores: JassPlayerScore[];\n  events: JassEventId[];\n  limitOps: JassLimitOp[];\n  unitTypes: JassUnitType[];\n  itemTypes: JassItemType[];\n  cameraFields: JassCameraField[];\n  blendModes: JassBlendMode[];\n  rarityControls: JassRarityControl[];\n  texMapFlags: JassTexMapFlags[];\n  fogStates: JassFogState[];\n  effectTypes: JassEffectType[];\n  soundTypes: JassSoundType[];\n}\n\nexport default function constantHandles(): ConstantHandles {\n  const playerColors = [];\n  const races = [];\n  const playerGameResults = [];\n  const allianceTypes = [];\n  const versions = [];\n  const attackTypes = [];\n  const damageTypes = [];\n  const weaponTypes = [];\n  const pathingTypes = [];\n  const mouseButtonTypes = [];\n  const animTypes = [];\n  const subAnimTypes = [];\n  const racePrefs = [];\n  const mapControls = [];\n  const gameTypes = [];\n  const mapFlags = [];\n  const placements = [];\n  const startLocPrios = [];\n  const mapDensities = [];\n  const gameDifficulties = [];\n  const gameSpeeds = [];\n  const playerSlotStates = [];\n  const volumeGroups = [];\n  const gameStates = [];\n  const playerStates = [];\n  const unitStates = [];\n  const aiDifficulties = [];\n  const playerScores = [];\n  const events = [];\n  const limitOps = [];\n  const unitTypes = [];\n  const itemTypes = [];\n  const cameraFields = [];\n  const blendModes = [];\n  const rarityControls = [];\n  const texMapFlags = [];\n  const fogStates = [];\n  const effectTypes = [];\n  const soundTypes = [];\n\n  for (let i = 0; i < 24; i++) {\n    playerColors[i] = new JassPlayerColor(i);\n  }\n\n  for (let i = 0; i < 8; i++) {\n    races[i] = new JassRace(i);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    playerGameResults[i] = new JassPlayerGameResult(i);\n  }\n\n  for (let i = 0; i < 10; i++) {\n    allianceTypes[i] = new JassAllianceType(i);\n  }\n\n  for (let i = 0; i < 2; i++) {\n    versions[i] = new JassVersion(i);\n  }\n\n  for (let i = 0; i < 7; i++) {\n    attackTypes[i] = new JassAttackType(i);\n  }\n\n  for (let i = 0; i < 27; i++) {\n    // Note: 1, 2, 3, 6, and 7 not exposed in common.j\n    damageTypes[i] = new JassDamageType(i);\n  }\n\n  for (let i = 0; i < 24; i++) {\n    weaponTypes[i] = new JassWeaponType(i);\n  }\n\n  for (let i = 0; i < 8; i++) {\n    pathingTypes[i] = new JassPathingType(i);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    mouseButtonTypes[i] = new JassMouseButtonType(i);\n  }\n\n  for (let i = 0; i < 11; i++) {\n    animTypes[i] = new JassAnimType(i);\n  }\n\n  for (let i = 11; i < 63; i++) {\n    subAnimTypes[i] = new JassSubAnimType(i);\n  }\n\n  for (let i = 0; i < 8; i++) {\n    const p = Math.pow(2, i);\n\n    racePrefs[p] = new JassRacePreference(p);\n  }\n\n  for (let i = 0; i < 6; i++) {\n    mapControls[i] = new JassMapControl(i);\n  }\n\n  for (let i = 0; i < 8; i++) {\n    const p = Math.pow(2, i);\n\n    gameTypes[p] = new JassGameType(p);\n  }\n\n  for (let i = 0; i < 20; i++) {\n    const p = Math.pow(2, i);\n\n    mapFlags[p] = new JassMapFlag(p);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    placements[i] = new JassPlacement(i);\n  }\n\n  for (let i = 0; i < 3; i++) {\n    startLocPrios[i] = new JassStartLocPrio(i);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    mapDensities[i] = new JassMapDensity(i);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    gameDifficulties[i] = new JassGameDifficulty(i);\n  }\n\n  for (let i = 0; i < 5; i++) {\n    gameSpeeds[i] = new JassGameSpeed(i);\n  }\n\n  for (let i = 0; i < 3; i++) {\n    playerSlotStates[i] = new JassPlayerSlotState(i);\n  }\n\n  for (let i = 0; i < 8; i++) {\n    volumeGroups[i] = new JassVolumeGroup(i);\n  }\n\n  for (let i = 0; i < 2; i++) {\n    gameStates[i] = new JassIGameState(i);\n  }\n\n  for (let i = 2; i < 3; i++) {\n    gameStates[i] = new JassFGameState(i);\n  }\n\n  for (let i = 0; i < 26; i++) {\n    // Note: 17-24 not exposed in common.j\n    playerStates[i] = new JassPlayerState(i);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    unitStates[i] = new JassUnitState(i);\n  }\n\n  for (let i = 0; i < 3; i++) {\n    aiDifficulties[i] = new JassAiDifficulty(i);\n  }\n\n  for (let i = 0; i < 25; i++) {\n    playerScores[i] = new JassPlayerScore(i);\n  }\n\n  for (let i = 0; i < 11; i++) {\n    events[i] = new JassGameEvent(i);\n  }\n\n  for (let i = 11; i < 18; i++) {\n    events[i] = new JassPlayerEvent(i);\n  }\n\n  for (let i = 18; i < 52; i++) {\n    events[i] = new JassPlayerUnitEvent(i);\n  }\n\n  for (let i = 52; i < 89; i++) {\n    events[i] = new JassUnitEvent(i);\n  }\n\n  for (let i = 89; i < 90; i++) {\n    events[i] = new JassWidgetEvent(i);\n  }\n\n  for (let i = 90; i < 92; i++) {\n    events[i] = new JassDialogEvent(i);\n  }\n\n  for (let i = 256; i < 260; i++) {\n    events[i] = new JassGameEvent(i);\n  }\n\n  for (let i = 261; i < 269; i++) {\n    events[i] = new JassPlayerEvent(i);\n  }\n\n  for (let i = 269; i < 278; i++) {\n    events[i] = new JassPlayerUnitEvent(i);\n  }\n\n  for (let i = 286; i < 295; i++) {\n    events[i] = new JassUnitEvent(i);\n  }\n\n  for (let i = 0; i < 6; i++) {\n    limitOps[i] = new JassLimitOp(i);\n  }\n\n  for (let i = 0; i < 27; i++) {\n    unitTypes[i] = new JassUnitType(i);\n  }\n\n  for (let i = 0; i < 9; i++) {\n    itemTypes[i] = new JassItemType(i);\n  }\n\n  for (let i = 0; i < 7; i++) {\n    cameraFields[i] = new JassCameraField(i);\n  }\n\n  for (let i = 0; i < 6; i++) {\n    blendModes[i] = new JassBlendMode(i);\n  }\n\n  for (let i = 0; i < 1; i++) {\n    rarityControls[i] = new JassRarityControl(i);\n  }\n\n  for (let i = 0; i < 4; i++) {\n    texMapFlags[i] = new JassTexMapFlags(i);\n  }\n\n  for (let i = 0; i < 3; i++) {\n    const p = Math.pow(2, i);\n\n    fogStates[p] = new JassFogState(p);\n  }\n\n  for (let i = 0; i < 7; i++) {\n    effectTypes[i] = new JassEffectType(i);\n  }\n\n  for (let i = 0; i < 2; i++) {\n    soundTypes[i] = new JassSoundType(i);\n  }\n\n  return {\n    playerColors,\n    races,\n    playerGameResults,\n    allianceTypes,\n    versions,\n    attackTypes,\n    damageTypes,\n    weaponTypes,\n    pathingTypes,\n    mouseButtonTypes,\n    animTypes,\n    subAnimTypes,\n    racePrefs,\n    mapControls,\n    gameTypes,\n    mapFlags,\n    placements,\n    startLocPrios,\n    mapDensities,\n    gameDifficulties,\n    gameSpeeds,\n    playerSlotStates,\n    volumeGroups,\n    gameStates,\n    playerStates,\n    unitStates,\n    aiDifficulties,\n    playerScores,\n    events,\n    limitOps,\n    unitTypes,\n    itemTypes,\n    cameraFields,\n    blendModes,\n    rarityControls,\n    texMapFlags,\n    fogStates,\n    effectTypes,\n    soundTypes,\n  };\n}\n"
  },
  {
    "path": "src/utils/jass2/context.ts",
    "content": "\nimport { EventEmitter } from 'events';\nimport { lua_State } from 'fengari/src/lstate';\nimport { lua_atnativeerror, lua_getglobal, lua_pcall, lua_pop, lua_pushstring, lua_rawgeti, lua_touserdata } from 'fengari/src/lapi';\nimport { LUA_REGISTRYINDEX, thread_status, to_jsstring, to_luastring } from 'fengari/src/defs';\nimport { luaL_checknumber, luaL_loadstring, luaL_newstate, luaL_tolstring } from 'fengari/src/lauxlib';\nimport { lua_resume } from 'fengari/src/ldo';\nimport War3Map from '../../parsers/w3x/map';\nimport jass2lua from './jass2lua';\nimport bindNatives from './natives';\nimport JassPlayer from './types/player';\nimport constantHandles from './constanthandles';\nimport Thread from './thread';\nimport JassHandle from './types/handle';\nimport JassLocation from './types/location';\nimport JassTimer from './types/timer';\nimport { JassTrigger } from './types/index';\n\n/**\n * A Jass2 context.\n */\nexport default class Context extends EventEmitter {\n  L: lua_State;\n  map: War3Map | null = null;\n  handle = 0;\n  freeHandles: number[] = [];\n  handles: (JassHandle | null)[] = [];\n  name = '';\n  description = '';\n  players: JassPlayer[] = [];\n  actualPlayers = 0;\n  startLocations: JassLocation[] = [];\n  constantHandles = constantHandles();\n  timers: Set<JassTimer> = new Set();\n  triggers: Set<JassTrigger> = new Set();\n  threads: Set<Thread> = new Set();\n  currentThread: Thread | null = null;\n  enumUnit: JassHandle | null = null;\n  filterUnit: JassHandle | null = null;\n  enumPlayer: JassHandle | null = null;\n  t = 0;\n\n  constructor() {\n    super();\n\n    this.L = luaL_newstate();\n\n    //luaL_openlibs(this.L);\n\n    bindNatives(this);\n\n    lua_atnativeerror(this.L, (L: lua_State) => {\n      const e = <Error>lua_touserdata(L, -1);\n\n      lua_pushstring(L, e.stack || 'An unknown error occured');\n\n      return 1;\n    });\n\n    for (let i = 0; i < 28; i++) {\n      this.players[i] = <JassPlayer>this.addHandle(new JassPlayer(i, 28));\n    }\n\n    // this.mappedData = new MappedData();\n\n    // this.mapName = '';\n    // this.mapDescription = '';\n    // this.gamePlacement = null;\n    // this.gameSpeed = null;\n    // this.gameDifficulty = null;\n    // this.playerCount = 0;\n    // this.teamCount = 0;\n    // this.startLocations = [];\n    // this.players = [];\n    // this.teams = [];\n\n    // this.stringTable = map.readStringTable();\n  }\n\n  start(): void {\n    this.t = performance.now();\n  }\n\n  step(): void {\n    const t = performance.now();\n    const dt = (t - this.t) * 0.001;\n    const timers = this.timers;\n    const threads = this.threads;\n\n    for (const timer of timers) {\n      timer.elapsed += dt;\n\n      if (timer.elapsed >= timer.timeout) {\n        const thread = new Thread(this.L, { expiredTimer: timer });\n        const L = thread.L;\n\n        // Push the entry point onto the thread's stack, so when the thread is resumed it will immediately be called.\n        lua_rawgeti(L, LUA_REGISTRYINDEX, timer.handlerFunc);\n\n        this.threads.add(thread);\n\n        if (timer.periodic) {\n          timer.elapsed = 0;\n        } else {\n          timers.delete(timer);\n\n          /// TODO: better way to clean references.\n          // If the timer isn't periodic, the callback reference can be collected.\n          ///luaL_unref(timer.handlerFunc);\n        }\n      }\n    }\n\n    for (const thread of threads) {\n      thread.sleep -= dt;\n\n      if (thread.sleep <= 0) {\n        this.currentThread = thread;\n\n        const L = thread.L;\n        const status = lua_resume(L, this.L, 0);\n\n        if (status === thread_status.LUA_OK) {\n          threads.delete(thread);\n        } else if (status === thread_status.LUA_YIELD) {\n          thread.sleep = luaL_checknumber(L, 1);\n        } else {\n          console.log('[JS] Something went wrong during execution');\n          console.log(to_jsstring(luaL_tolstring(L, -1)));\n          lua_pop(L, 2);\n        }\n      }\n    }\n\n    this.t = t;\n  }\n\n  addHandle(handle: JassHandle): JassHandle {\n    if (handle.handleId === -1) {\n      let handleId;\n\n      if (this.freeHandles.length) {\n        handleId = <number>this.freeHandles.pop();\n      } else {\n        handleId = this.handle++;\n      }\n\n      this.handles[handleId] = handle;\n\n      handle.handleId = handleId;\n    }\n\n    return handle;\n  }\n\n  freeHandle(handle: JassHandle): void {\n    if (handle.handleId !== -1) {\n      this.freeHandles.push(handle.handleId);\n\n      this.handles[handle.handleId] = null;\n\n      handle.handleId = -1;\n    }\n  }\n\n  call(name?: string | number): void {\n    const L = this.L;\n\n    if (typeof name === 'string') {\n      lua_getglobal(L, name);\n    } else if (typeof name === 'number') {\n      lua_rawgeti(L, LUA_REGISTRYINDEX, name);\n    }\n\n    if (lua_pcall(L, 0, 0, 0)) {\n      console.log('Something went wrong during execution');\n      console.log(to_jsstring(luaL_tolstring(L, -1)));\n      lua_pop(L, 2);\n    }\n  }\n\n  run(code: string, isJass: boolean): void {\n    const L = this.L;\n\n    if (isJass) {\n      code = jass2lua(code);\n    }\n\n    if (luaL_loadstring(L, to_luastring(code))) {\n      console.log('Something went wrong during execution');\n      console.log(to_jsstring(luaL_tolstring(L, -1)));\n      lua_pop(L, 2);\n    }\n\n    if (lua_pcall(L, 0, 0, 0)) {\n      console.log('Something went wrong during execution');\n      console.log(to_jsstring(luaL_tolstring(L, -1)));\n      lua_pop(L, 2);\n    }\n  }\n\n  open(map: War3Map): void {\n    this.map = map;\n\n    const file = map.getScriptFile();\n\n    if (file) {\n      const buffer = file.text();\n\n      if (buffer) {\n        const isJass = file.name.endsWith('.j');\n\n        this.run(buffer, isJass);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/index.ts",
    "content": "import Context from './context';\nimport jass2lua from './jass2lua';\nimport * as types from './types';\nimport compileNatives from './compilenatives';\n\nexport default {\n  Context,\n  jass2lua,\n  types,\n  compileNatives,\n};\n"
  },
  {
    "path": "src/utils/jass2/jass2lua.ts",
    "content": "import TokenStream from './tokenstream';\n\nexport default function jass2lua(jass: string): string {\n  const stream = new TokenStream(jass);\n  const tokens = [];\n  let token;\n\n  while ((token = stream.read()) !== undefined) {\n    if (token === 'function') {\n      const name = stream.readSafe();\n\n      stream.read(); // takes\n\n      token = stream.read(); // nothing or type\n\n      let params = '';\n\n      if (token !== 'nothing') {\n        params += stream.readSafe();\n\n        while (stream.read() === ',') {\n          stream.read();\n\n          params += ',' + stream.readSafe();\n        }\n      } else {\n        stream.read(); // returns\n      }\n\n      stream.read(); // return type\n\n      const header = `function ${name}(${params})`;\n      const body = [];\n\n      while ((token = stream.readSafe()) !== 'endfunction') {\n        if (token === 'local') {\n          stream.read(); // type\n\n          const arrayOrName = stream.readSafe();\n\n          if (arrayOrName === 'array') {\n            body.push(`local ${stream.readSafe()}={}`);\n          } else {\n            body.push(`local ${arrayOrName}${stream.readUntil('\\n')}\\n`);\n          }\n        } else if (token === 'if' || token === 'elseif' || token === 'not') {\n          body.push(token + ' ');\n        } else if (token === 'then') {\n          body.push(' ' + token);\n        } else if (token === 'loop') {\n          body.push('while 1 do');\n        } else if (token === 'endloop' || token === 'endif') {\n          body.push('end');\n        } else if (token === 'exitwhen') {\n          body.push(`if ${stream.readUntil('\\n')} then break end\\n`);\n        } else if (token === 'return') {\n          const value = stream.readUntil('\\n');\n\n          token = stream.peek();\n\n          // return statmentes can only be the last statements in their block.\n          // If a statement isn't the last in its block, it is inserted into its own if block.\n          if (token === 'endif' || token === 'endloop' || token === 'endfunction') {\n            body.push(`return ${value}\\n`);\n          } else {\n            body.push(`if 1 then return ${value} end\\n`);\n          }\n        } else if (token === '\\n') {\n          const lastLine = body[body.length - 1];\n\n          if (lastLine && lastLine[lastLine.length - 1] !== '\\n') {\n            body.push('\\n');\n          }\n        } else if (token !== 'set' && token !== 'call' && token !== 'function') {\n          body.push(token);\n        }\n      }\n\n      tokens.push(`${header}\\n${body.join('')}end`);\n    } else if (token === 'globals') {\n      while ((token = stream.read()) !== 'endglobals') {\n        if (token !== '\\n') {\n          // token can either be type or constant.\n          if (token === 'constant') {\n            token = stream.read();\n          }\n\n          const arrayOrName = stream.read();\n\n          if (arrayOrName === 'array') {\n            tokens.push(`${stream.readSafe()}={}`);\n          } else {\n            // Unlike locals, having a global name with no value is a syntax error.\n            // In addition, globals that are nil effectively don't exist in Lua.\n            // Therefore, remove both cases.\n            let value = 'nil';\n\n            if (stream.peek() === '=') {\n              stream.read(); // =\n\n              value = stream.readUntil('\\n');\n            }\n\n            if (value !== 'nil') {\n              tokens.push(`${arrayOrName}=${value}`);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  return tokens.join('\\n');\n}\n"
  },
  {
    "path": "src/utils/jass2/natives.ts",
    "content": "import { LUA_REGISTRYINDEX } from 'fengari/src/defs';\nimport { lua_State } from 'fengari/src/lstate';\nimport { lua_register, lua_pushinteger, lua_pushnumber, lua_pushstring, lua_pushlightuserdata, lua_touserdata, lua_pushboolean, lua_pushnil, lua_toboolean } from 'fengari/src/lapi';\nimport { luaL_checkstring, luaL_checkinteger, luaL_checknumber, luaL_ref, luaL_unref } from 'fengari/src/lauxlib';\nimport { lua_yield } from 'fengari/src/ldo';\nimport { JassTimer, JassGroup, JassLocation, JassForce, JassUnit, JassTrigger, JassPlayer, JassPlayerColor, JassMapControl, JassHandle } from './types';\nimport Context from './context';\n\n/**\n * constant native ConvertRace takes integer i returns race\n */\nfunction ConvertRace(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.races[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertAllianceType takes integer i returns alliancetype\n */\nfunction ConvertAllianceType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.allianceTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertRacePref takes integer i returns racepreference\n */\nfunction ConvertRacePref(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.racePrefs[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertIGameState takes integer i returns igamestate\n */\nfunction ConvertIGameState(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.gameStates[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertFGameState takes integer i returns fgamestate\n */\nfunction ConvertFGameState(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.gameStates[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerState takes integer i returns playerstate\n */\nfunction ConvertPlayerState(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.playerStates[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerScore takes integer i returns playerscore\n */\nfunction ConvertPlayerScore(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.playerScores[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerGameResult takes integer i returns playergameresult\n */\nfunction ConvertPlayerGameResult(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.playerGameResults[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertUnitState takes integer i returns unitstate\n */\nfunction ConvertUnitState(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.unitStates[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertAIDifficulty takes integer i returns aidifficulty\n */\nfunction ConvertAIDifficulty(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.aiDifficulties[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertGameEvent takes integer i returns gameevent\n */\nfunction ConvertGameEvent(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.events[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerEvent takes integer i returns playerevent\n */\nfunction ConvertPlayerEvent(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.events[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerUnitEvent takes integer i returns playerunitevent\n */\nfunction ConvertPlayerUnitEvent(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.events[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertWidgetEvent takes integer i returns widgetevent\n */\nfunction ConvertWidgetEvent(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.events[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertDialogEvent takes integer i returns dialogevent\n */\nfunction ConvertDialogEvent(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.events[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertUnitEvent takes integer i returns unitevent\n */\nfunction ConvertUnitEvent(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.events[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertLimitOp takes integer i returns limitop\n */\nfunction ConvertLimitOp(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.limitOps[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertUnitType takes integer i returns unittype\n */\nfunction ConvertUnitType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.unitTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertGameSpeed takes integer i returns gamespeed\n */\nfunction ConvertGameSpeed(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.gameSpeeds[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlacement takes integer i returns placement\n */\nfunction ConvertPlacement(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.placements[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertStartLocPrio takes integer i returns startlocprio\n */\nfunction ConvertStartLocPrio(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.startLocPrios[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertGameDifficulty takes integer i returns gamedifficulty\n */\nfunction ConvertGameDifficulty(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.gameDifficulties[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertGameType takes integer i returns gametype\n */\nfunction ConvertGameType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.gameTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertMapFlag takes integer i returns mapflag\n */\nfunction ConvertMapFlag(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.mapFlags[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertMapVisibility takes integer i returns mapvisibility\n */\nfunction ConvertMapVisibility(C: Context, L: lua_State): number {\n  const _i = luaL_checkinteger(L, 1);\n\n  console.warn('ConvertMapVisibility used, but the implementation is unknown');\n\n  lua_pushnil(L);\n\n  return 1;\n}\n\n/**\n * constant native ConvertMapSetting takes integer i returns mapsetting\n */\nfunction ConvertMapSetting(C: Context, L: lua_State): number {\n  const _i = luaL_checkinteger(L, 1);\n\n  console.warn('ConvertMapSetting used, but the implementation is unknown');\n\n  lua_pushnil(L);\n\n  return 1;\n}\n\n/**\n * constant native ConvertMapDensity takes integer i returns mapdensity\n */\nfunction ConvertMapDensity(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.mapDensities[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertMapControl takes integer i returns mapcontrol\n */\nfunction ConvertMapControl(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.mapControls[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerColor takes integer i returns playercolor\n */\nfunction ConvertPlayerColor(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.playerColors[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPlayerSlotState takes integer i returns playerslotstate\n */\nfunction ConvertPlayerSlotState(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.playerSlotStates[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertVolumeGroup takes integer i returns volumegroup\n */\nfunction ConvertVolumeGroup(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.volumeGroups[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertCameraField takes integer i returns camerafield\n */\nfunction ConvertCameraField(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.cameraFields[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertBlendMode takes integer i returns blendmode\n */\nfunction ConvertBlendMode(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.blendModes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertRarityControl takes integer i returns raritycontrol\n */\nfunction ConvertRarityControl(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.rarityControls[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertTexMapFlags takes integer i returns texmapflags\n */\nfunction ConvertTexMapFlags(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.texMapFlags[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertFogState takes integer i returns fogstate\n */\nfunction ConvertFogState(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.fogStates[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertEffectType takes integer i returns effecttype\n */\nfunction ConvertEffectType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.effectTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertVersion takes integer i returns version\n */\nfunction ConvertVersion(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.versions[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertItemType takes integer i returns itemtype\n */\nfunction ConvertItemType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.itemTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertAttackType takes integer i returns attacktype\n */\nfunction ConvertAttackType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.attackTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertDamageType takes integer i returns damagetype\n */\nfunction ConvertDamageType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.damageTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertWeaponType takes integer i returns weapontype\n */\nfunction ConvertWeaponType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.weaponTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertSoundType takes integer i returns soundtype\n */\nfunction ConvertSoundType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.soundTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertPathingType takes integer i returns pathingtype\n */\nfunction ConvertPathingType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.pathingTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertMouseButtonType takes integer i returns mousebuttontype\n */\nfunction ConvertMouseButtonType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.mouseButtonTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertAnimType takes integer i returns animtype\n */\nfunction ConvertAnimType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.animTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native ConvertSubAnimType takes integer i returns subanimtype\n */\nfunction ConvertSubAnimType(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.subAnimTypes[i]);\n\n  return 1;\n}\n\n/**\n * constant native OrderId takes string orderIdString returns integer\n */\nfunction OrderId(C: Context, L: lua_State): number {\n  const _orderIdString = luaL_checkstring(L, 1);\n  console.warn('OrderId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native OrderId2String takes integer orderId returns string\n */\nfunction OrderId2String(C: Context, L: lua_State): number {\n  const _orderId = luaL_checkinteger(L, 1);\n  console.warn('OrderId2String was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native UnitId takes string unitIdString returns integer\n */\nfunction UnitId(C: Context, L: lua_State): number {\n  const _unitIdString = luaL_checkstring(L, 1);\n  console.warn('UnitId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native UnitId2String takes integer unitId returns string\n */\nfunction UnitId2String(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  console.warn('UnitId2String was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native AbilityId takes string abilityIdString returns integer\n */\nfunction AbilityId(C: Context, L: lua_State): number {\n  const _abilityIdString = luaL_checkstring(L, 1);\n  console.warn('AbilityId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native AbilityId2String takes integer abilityId returns string\n */\nfunction AbilityId2String(C: Context, L: lua_State): number {\n  const _abilityId = luaL_checkinteger(L, 1);\n  console.warn('AbilityId2String was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native GetObjectName takes integer objectId returns string\n */\nfunction GetObjectName(C: Context, L: lua_State): number {\n  const _objectId = luaL_checkinteger(L, 1);\n  console.warn('GetObjectName was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native GetBJMaxPlayers takes nothing returns integer\n */\nfunction GetBJMaxPlayers(C: Context, L: lua_State): number {\n  lua_pushinteger(L, 24);\n\n  return 1;\n}\n\n/**\n * constant native GetBJPlayerNeutralVictim takes nothing returns integer\n */\nfunction GetBJPlayerNeutralVictim(C: Context, L: lua_State): number {\n  lua_pushinteger(L, 24);\n\n  return 1;\n}\n\n/**\n * constant native GetBJPlayerNeutralExtra takes nothing returns integer\n */\nfunction GetBJPlayerNeutralExtra(C: Context, L: lua_State): number {\n  lua_pushinteger(L, 25);\n\n  return 1;\n}\n\n/**\n * constant native GetBJMaxPlayerSlots takes nothing returns integer\n */\nfunction GetBJMaxPlayerSlots(C: Context, L: lua_State): number {\n  lua_pushinteger(L, 28);\n\n  return 1;\n}\n\n/**\n * constant native GetPlayerNeutralPassive takes nothing returns integer\n */\nfunction GetPlayerNeutralPassive(C: Context, L: lua_State): number {\n  lua_pushinteger(L, 26);\n\n  return 1;\n}\n\n/**\n * constant native GetPlayerNeutralAggressive takes nothing returns integer\n */\nfunction GetPlayerNeutralAggressive(C: Context, L: lua_State): number {\n  lua_pushinteger(L, 27);\n\n  return 1;\n}\n\n/**\n * native Deg2Rad takes real degrees returns real\n */\nfunction Deg2Rad(C: Context, L: lua_State): number {\n  const degrees = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, degrees * (Math.PI / 180));\n\n  return 1;\n}\n\n/**\n * native Rad2Deg takes real radians returns real\n */\nfunction Rad2Deg(C: Context, L: lua_State): number {\n  const radians = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, radians * (180 / Math.PI));\n\n  return 1;\n}\n\n/**\n * native Sin takes real radians returns real\n */\nfunction Sin(C: Context, L: lua_State): number {\n  const radians = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.sin(radians));\n\n  return 1;\n}\n\n/**\n * native Cos takes real radians returns real\n */\nfunction Cos(C: Context, L: lua_State): number {\n  const radians = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.cos(radians));\n\n  return 1;\n}\n\n/**\n * native Tan takes real radians returns real\n */\nfunction Tan(C: Context, L: lua_State): number {\n  const radians = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.tan(radians));\n\n  return 1;\n}\n\n/**\n * native Asin takes real y returns real\n */\nfunction Asin(C: Context, L: lua_State): number {\n  const y = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.asin(y));\n\n  return 1;\n}\n\n/**\n * native Acos takes real x returns real\n */\nfunction Acos(C: Context, L: lua_State): number {\n  const x = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.acos(x));\n\n  return 1;\n}\n\n/**\n * native Atan takes real x returns real\n */\nfunction Atan(C: Context, L: lua_State): number {\n  const x = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.atan(x));\n\n  return 1;\n}\n\n/**\n * native Atan2 takes real y, real x returns real\n */\nfunction Atan2(C: Context, L: lua_State): number {\n  const y = luaL_checknumber(L, 1);\n  const x = luaL_checknumber(L, 2);\n\n  lua_pushnumber(L, Math.atan2(y, x));\n\n  return 1;\n}\n\n/**\n * native SquareRoot takes real x returns real\n */\nfunction SquareRoot(C: Context, L: lua_State): number {\n  const x = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, Math.sqrt(x));\n\n  return 1;\n}\n\n/**\n * native Pow takes real x, real power returns real\n */\nfunction Pow(C: Context, L: lua_State): number {\n  const x = luaL_checknumber(L, 1);\n  const power = luaL_checknumber(L, 2);\n\n  lua_pushnumber(L, Math.pow(x, power));\n\n  return 1;\n}\n\n/**\n * native I2R takes integer i returns real\n */\nfunction I2R(C: Context, L: lua_State): number {\n  const i = luaL_checkinteger(L, 1);\n\n  lua_pushnumber(L, i);\n\n  return 1;\n}\n\n/**\n * native R2I takes real r returns integer\n */\nfunction R2I(C: Context, L: lua_State): number {\n  const r = luaL_checknumber(L, 1);\n\n  lua_pushinteger(L, r | 0);\n\n  return 1;\n}\n\n/**\n * native I2S takes integer i returns string\n */\nfunction I2S(C: Context, L: lua_State): number {\n  const _i = luaL_checkinteger(L, 1);\n  console.warn('I2S was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native R2S takes real r returns string\n */\nfunction R2S(C: Context, L: lua_State): number {\n  const _r = luaL_checknumber(L, 1);\n  console.warn('R2S was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native R2SW takes real r, integer width, integer precision returns string\n */\nfunction R2SW(C: Context, L: lua_State): number {\n  const _r = luaL_checknumber(L, 1);\n  const _width = luaL_checkinteger(L, 2);\n  const _precision = luaL_checkinteger(L, 3);\n  console.warn('R2SW was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native S2I takes string s returns integer\n */\nfunction S2I(C: Context, L: lua_State): number {\n  const _s = luaL_checkstring(L, 1);\n  console.warn('S2I was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native S2R takes string s returns real\n */\nfunction S2R(C: Context, L: lua_State): number {\n  const _s = luaL_checkstring(L, 1);\n  console.warn('S2R was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetHandleId takes handle h returns integer\n */\nfunction GetHandleId(C: Context, L: lua_State): number {\n  const h = <JassHandle>lua_touserdata(L, 1);\n\n  lua_pushinteger(L, h.handleId);\n\n  return 1;\n}\n\n/**\n * native SubString takes string source, integer start, integer end_ returns string\n */\nfunction SubString(C: Context, L: lua_State): number {\n  const _source = luaL_checkstring(L, 1);\n  const _start = luaL_checkinteger(L, 2);\n  const _end_ = luaL_checkinteger(L, 3);\n  console.warn('SubString was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native StringLength takes string s returns integer\n */\nfunction StringLength(C: Context, L: lua_State): number {\n  const _s = luaL_checkstring(L, 1);\n  console.warn('StringLength was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native StringCase takes string source, boolean upper returns string\n */\nfunction StringCase(C: Context, L: lua_State): number {\n  const _source = luaL_checkstring(L, 1);\n  const _upper = lua_toboolean(L, 2);\n  console.warn('StringCase was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native StringHash takes string s returns integer\n */\nfunction StringHash(C: Context, L: lua_State): number {\n  const _s = luaL_checkstring(L, 1);\n  console.warn('StringHash was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetLocalizedString takes string source returns string\n */\nfunction GetLocalizedString(C: Context, L: lua_State): number {\n  const _source = luaL_checkstring(L, 1);\n  console.warn('GetLocalizedString was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native GetLocalizedHotkey takes string source returns integer\n */\nfunction GetLocalizedHotkey(C: Context, L: lua_State): number {\n  const _source = luaL_checkstring(L, 1);\n  console.warn('GetLocalizedHotkey was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetMapName takes string name returns nothing\n */\nfunction SetMapName(C: Context, L: lua_State): number {\n  const _name = luaL_checkstring(L, 1);\n  console.warn('SetMapName was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetMapDescription takes string description returns nothing\n */\nfunction SetMapDescription(C: Context, L: lua_State): number {\n  const _description = luaL_checkstring(L, 1);\n  console.warn('SetMapDescription was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTeams takes integer teamcount returns nothing\n */\nfunction SetTeams(C: Context, L: lua_State): number {\n  const _teamcount = luaL_checkinteger(L, 1);\n  console.warn('SetTeams was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayers takes integer playercount returns nothing\n */\nfunction SetPlayers(C: Context, L: lua_State): number {\n  const _playercount = luaL_checkinteger(L, 1);\n  console.warn('SetPlayers was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DefineStartLocation takes integer whichStartLoc, real x, real y returns nothing\n */\nfunction DefineStartLocation(C: Context, L: lua_State): number {\n  const whichStartLoc = luaL_checkinteger(L, 1);\n  const x = luaL_checknumber(L, 2);\n  const y = luaL_checknumber(L, 3);\n\n  C.startLocations[whichStartLoc] = <JassLocation>C.addHandle(new JassLocation(x, y));\n\n  return 0;\n}\n\n/**\n * native DefineStartLocationLoc takes integer whichStartLoc, location whichLocation returns nothing\n */\nfunction DefineStartLocationLoc(C: Context, L: lua_State): number {\n  const _whichStartLoc = luaL_checkinteger(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  console.warn('DefineStartLocationLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetStartLocPrioCount takes integer whichStartLoc, integer prioSlotCount returns nothing\n */\nfunction SetStartLocPrioCount(C: Context, L: lua_State): number {\n  const _whichStartLoc = luaL_checkinteger(L, 1);\n  const _prioSlotCount = luaL_checkinteger(L, 2);\n  console.warn('SetStartLocPrioCount was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetStartLocPrio takes integer whichStartLoc, integer prioSlotIndex, integer otherStartLocIndex, startlocprio priority returns nothing\n */\nfunction SetStartLocPrio(C: Context, L: lua_State): number {\n  const _whichStartLoc = luaL_checkinteger(L, 1);\n  const _prioSlotIndex = luaL_checkinteger(L, 2);\n  const _otherStartLocIndex = luaL_checkinteger(L, 3);\n  const _priority = lua_touserdata(L, 4);\n  console.warn('SetStartLocPrio was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetStartLocPrioSlot takes integer whichStartLoc, integer prioSlotIndex returns integer\n */\nfunction GetStartLocPrioSlot(C: Context, L: lua_State): number {\n  const _whichStartLoc = luaL_checkinteger(L, 1);\n  const _prioSlotIndex = luaL_checkinteger(L, 2);\n  console.warn('GetStartLocPrioSlot was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetStartLocPrio takes integer whichStartLoc, integer prioSlotIndex returns startlocprio\n */\nfunction GetStartLocPrio(C: Context, L: lua_State): number {\n  const _whichStartLoc = luaL_checkinteger(L, 1);\n  const _prioSlotIndex = luaL_checkinteger(L, 2);\n  console.warn('GetStartLocPrio was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SetGameTypeSupported takes gametype whichGameType, boolean value returns nothing\n */\nfunction SetGameTypeSupported(C: Context, L: lua_State): number {\n  const _whichGameType = lua_touserdata(L, 1);\n  const _value = lua_toboolean(L, 2);\n  console.warn('SetGameTypeSupported was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetMapFlag takes mapflag whichMapFlag, boolean value returns nothing\n */\nfunction SetMapFlag(C: Context, L: lua_State): number {\n  const _whichMapFlag = lua_touserdata(L, 1);\n  const _value = lua_toboolean(L, 2);\n  console.warn('SetMapFlag was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetGamePlacement takes placement whichPlacementType returns nothing\n */\nfunction SetGamePlacement(C: Context, L: lua_State): number {\n  const _whichPlacementType = lua_touserdata(L, 1);\n  console.warn('SetGamePlacement was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetGameSpeed takes gamespeed whichspeed returns nothing\n */\nfunction SetGameSpeed(C: Context, L: lua_State): number {\n  const _whichspeed = lua_touserdata(L, 1);\n  console.warn('SetGameSpeed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetGameDifficulty takes gamedifficulty whichdifficulty returns nothing\n */\nfunction SetGameDifficulty(C: Context, L: lua_State): number {\n  const _whichdifficulty = lua_touserdata(L, 1);\n  console.warn('SetGameDifficulty was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetResourceDensity takes mapdensity whichdensity returns nothing\n */\nfunction SetResourceDensity(C: Context, L: lua_State): number {\n  const _whichdensity = lua_touserdata(L, 1);\n  console.warn('SetResourceDensity was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCreatureDensity takes mapdensity whichdensity returns nothing\n */\nfunction SetCreatureDensity(C: Context, L: lua_State): number {\n  const _whichdensity = lua_touserdata(L, 1);\n  console.warn('SetCreatureDensity was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetTeams takes nothing returns integer\n */\nfunction GetTeams(C: Context, L: lua_State): number {\n\n  console.warn('GetTeams was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetPlayers takes nothing returns integer\n */\nfunction GetPlayers(C: Context, L: lua_State): number {\n\n  console.warn('GetPlayers was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native IsGameTypeSupported takes gametype whichGameType returns boolean\n */\nfunction IsGameTypeSupported(C: Context, L: lua_State): number {\n  const _whichGameType = lua_touserdata(L, 1);\n  console.warn('IsGameTypeSupported was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetGameTypeSelected takes nothing returns gametype\n */\nfunction GetGameTypeSelected(C: Context, L: lua_State): number {\n\n  console.warn('GetGameTypeSelected was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native IsMapFlagSet takes mapflag whichMapFlag returns boolean\n */\nfunction IsMapFlagSet(C: Context, L: lua_State): number {\n  const _whichMapFlag = lua_touserdata(L, 1);\n  console.warn('IsMapFlagSet was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native GetGamePlacement takes nothing returns placement\n */\nfunction GetGamePlacement(C: Context, L: lua_State): number {\n\n  console.warn('GetGamePlacement was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetGameSpeed takes nothing returns gamespeed\n */\nfunction GetGameSpeed(C: Context, L: lua_State): number {\n\n  console.warn('GetGameSpeed was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetGameDifficulty takes nothing returns gamedifficulty\n */\nfunction GetGameDifficulty(C: Context, L: lua_State): number {\n\n  console.warn('GetGameDifficulty was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetResourceDensity takes nothing returns mapdensity\n */\nfunction GetResourceDensity(C: Context, L: lua_State): number {\n\n  console.warn('GetResourceDensity was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetCreatureDensity takes nothing returns mapdensity\n */\nfunction GetCreatureDensity(C: Context, L: lua_State): number {\n\n  console.warn('GetCreatureDensity was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetStartLocationX takes integer whichStartLocation returns real\n */\nfunction GetStartLocationX(C: Context, L: lua_State): number {\n  const _whichStartLocation = luaL_checkinteger(L, 1);\n  console.warn('GetStartLocationX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetStartLocationY takes integer whichStartLocation returns real\n */\nfunction GetStartLocationY(C: Context, L: lua_State): number {\n  const _whichStartLocation = luaL_checkinteger(L, 1);\n  console.warn('GetStartLocationY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetStartLocationLoc takes integer whichStartLocation returns location\n */\nfunction GetStartLocationLoc(C: Context, L: lua_State): number {\n  const _whichStartLocation = luaL_checkinteger(L, 1);\n  console.warn('GetStartLocationLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SetPlayerTeam takes player whichPlayer, integer whichTeam returns nothing\n */\nfunction SetPlayerTeam(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichTeam = luaL_checkinteger(L, 2);\n  console.warn('SetPlayerTeam was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerStartLocation takes player whichPlayer, integer startLocIndex returns nothing\n */\nfunction SetPlayerStartLocation(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n  const startLocIndex = luaL_checkinteger(L, 2);\n\n  whichPlayer.startLocation = startLocIndex;\n\n  return 0;\n}\n\n/**\n * native ForcePlayerStartLocation takes player whichPlayer, integer startLocIndex returns nothing\n */\nfunction ForcePlayerStartLocation(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _startLocIndex = luaL_checkinteger(L, 2);\n  console.warn('ForcePlayerStartLocation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerColor takes player whichPlayer, playercolor color returns nothing\n */\nfunction SetPlayerColor(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n  const color = <JassPlayerColor>lua_touserdata(L, 2);\n\n  whichPlayer.color = color.id;\n\n  return 0;\n}\n\n/**\n * native SetPlayerAlliance takes player sourcePlayer, player otherPlayer, alliancetype whichAllianceSetting, boolean value returns nothing\n */\nfunction SetPlayerAlliance(C: Context, L: lua_State): number {\n  const _sourcePlayer = lua_touserdata(L, 1);\n  const _otherPlayer = lua_touserdata(L, 2);\n  const _whichAllianceSetting = lua_touserdata(L, 3);\n  const _value = lua_toboolean(L, 4);\n  console.warn('SetPlayerAlliance was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerTaxRate takes player sourcePlayer, player otherPlayer, playerstate whichResource, integer rate returns nothing\n */\nfunction SetPlayerTaxRate(C: Context, L: lua_State): number {\n  const _sourcePlayer = lua_touserdata(L, 1);\n  const _otherPlayer = lua_touserdata(L, 2);\n  const _whichResource = lua_touserdata(L, 3);\n  const _rate = luaL_checkinteger(L, 4);\n  console.warn('SetPlayerTaxRate was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerRacePreference takes player whichPlayer, racepreference whichRacePreference returns nothing\n */\nfunction SetPlayerRacePreference(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichRacePreference = lua_touserdata(L, 2);\n  console.warn('SetPlayerRacePreference was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerRaceSelectable takes player whichPlayer, boolean value returns nothing\n */\nfunction SetPlayerRaceSelectable(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n  const value = lua_toboolean(L, 2);\n\n  whichPlayer.raceSelectable = value;\n\n  return 0;\n}\n\n/**\n * native SetPlayerController takes player whichPlayer, mapcontrol controlType returns nothing\n */\nfunction SetPlayerController(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n  const controlType = <JassMapControl>lua_touserdata(L, 2);\n\n  whichPlayer.controller = controlType.id;\n\n  return 0;\n}\n\n/**\n * native SetPlayerName takes player whichPlayer, string name returns nothing\n */\nfunction SetPlayerName(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n  const name = luaL_checkstring(L, 2);\n\n  whichPlayer.name = name;\n\n  return 0;\n}\n\n/**\n * native SetPlayerOnScoreScreen takes player whichPlayer, boolean flag returns nothing\n */\nfunction SetPlayerOnScoreScreen(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetPlayerOnScoreScreen was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetPlayerTeam takes player whichPlayer returns integer\n */\nfunction GetPlayerTeam(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('GetPlayerTeam was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetPlayerStartLocation takes player whichPlayer returns integer\n */\nfunction GetPlayerStartLocation(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n\n  lua_pushinteger(L, whichPlayer.startLocation);\n\n  return 1;\n}\n\n/**\n * native GetPlayerColor takes player whichPlayer returns playercolor\n */\nfunction GetPlayerColor(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n\n  lua_pushlightuserdata(L, whichPlayer.color);\n\n  return 1;\n}\n\n/**\n * native GetPlayerSelectable takes player whichPlayer returns boolean\n */\nfunction GetPlayerSelectable(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('GetPlayerSelectable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetPlayerController takes player whichPlayer returns mapcontrol\n */\nfunction GetPlayerController(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n\n  lua_pushlightuserdata(L, whichPlayer.controller);\n\n  return 1;\n}\n\n/**\n * native GetPlayerSlotState takes player whichPlayer returns playerslotstate\n */\nfunction GetPlayerSlotState(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('GetPlayerSlotState was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native GetPlayerTaxRate takes player sourcePlayer, player otherPlayer, playerstate whichResource returns integer\n */\nfunction GetPlayerTaxRate(C: Context, L: lua_State): number {\n  const _sourcePlayer = lua_touserdata(L, 1);\n  const _otherPlayer = lua_touserdata(L, 2);\n  const _whichResource = lua_touserdata(L, 3);\n  console.warn('GetPlayerTaxRate was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native IsPlayerRacePrefSet takes player whichPlayer, racepreference pref returns boolean\n */\nfunction IsPlayerRacePrefSet(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _pref = lua_touserdata(L, 2);\n  console.warn('IsPlayerRacePrefSet was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetPlayerName takes player whichPlayer returns string\n */\nfunction GetPlayerName(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n\n  lua_pushstring(L, whichPlayer.name);\n\n  return 1;\n}\n\n/**\n * native CreateTimer takes nothing returns timer\n */\nfunction CreateTimer(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.addHandle(new JassTimer()));\n\n  return 1;\n}\n\n/**\n * native DestroyTimer takes timer whichTimer returns nothing\n */\nfunction DestroyTimer(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n\n  // In case it's in the middle of running, remove it.\n  C.timers.delete(whichTimer);\n\n  C.freeHandle(whichTimer);\n\n  return 0;\n}\n\n/**\n * native TimerStart takes timer whichTimer, real timeout, boolean periodic, code handlerFunc returns nothing\n */\nfunction TimerStart(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n  const timeout = luaL_checknumber(L, 2);\n  const periodic = lua_toboolean(L, 3);\n  const handlerFunc = luaL_ref(L, LUA_REGISTRYINDEX);\n\n  whichTimer.elapsed = 0;\n  whichTimer.timeout = timeout;\n  whichTimer.periodic = periodic;\n  whichTimer.handlerFunc = handlerFunc;\n\n  C.timers.add(whichTimer);\n\n  return 0;\n}\n\n/**\n * native TimerGetElapsed takes timer whichTimer returns real\n */\nfunction TimerGetElapsed(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n\n  lua_pushnumber(L, whichTimer.elapsed);\n\n  return 1;\n}\n\n/**\n * native TimerGetRemaining takes timer whichTimer returns real\n */\nfunction TimerGetRemaining(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n\n  lua_pushnumber(L, whichTimer.timeout - whichTimer.elapsed);\n\n  return 1;\n}\n\n/**\n * native TimerGetTimeout takes timer whichTimer returns real\n */\nfunction TimerGetTimeout(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n\n  lua_pushnumber(L, whichTimer.timeout);\n\n  return 1;\n}\n\n/**\n * native PauseTimer takes timer whichTimer returns nothing\n */\nfunction PauseTimer(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n\n  C.timers.delete(whichTimer);\n\n  return 0;\n}\n\n/**\n * native ResumeTimer takes timer whichTimer returns nothing\n */\nfunction ResumeTimer(C: Context, L: lua_State): number {\n  const whichTimer = <JassTimer>lua_touserdata(L, 1);\n\n  C.timers.add(whichTimer);\n\n  return 0;\n}\n\n/**\n * native GetExpiredTimer takes nothing returns timer\n */\nfunction GetExpiredTimer(C: Context, L: lua_State): number {\n  const thread = C.currentThread;\n\n  if (thread && thread.expiredTimer) {\n    lua_pushlightuserdata(L, thread.expiredTimer);\n  } else {\n    lua_pushnil(L);\n  }\n\n  return 1;\n}\n\n/**\n * native CreateGroup takes nothing returns group\n */\nfunction CreateGroup(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.addHandle(new JassGroup()));\n\n  return 1;\n}\n\n/**\n * native DestroyGroup takes group whichGroup returns nothing\n */\nfunction DestroyGroup(C: Context, L: lua_State): number {\n  const whichGroup = <JassGroup>lua_touserdata(L, 1);\n\n  C.freeHandle(whichGroup);\n\n  return 0;\n}\n\n/**\n * native GroupAddUnit takes group whichGroup, unit whichUnit returns nothing\n */\nfunction GroupAddUnit(C: Context, L: lua_State): number {\n  const whichGroup = <JassGroup>lua_touserdata(L, 1);\n  const whichUnit = <JassUnit>lua_touserdata(L, 2);\n\n  whichGroup.units.add(whichUnit);\n\n  return 0;\n}\n\n/**\n * native GroupRemoveUnit takes group whichGroup, unit whichUnit returns nothing\n */\nfunction GroupRemoveUnit(C: Context, L: lua_State): number {\n  const whichGroup = <JassGroup>lua_touserdata(L, 1);\n  const whichUnit = <JassUnit>lua_touserdata(L, 2);\n\n  whichGroup.units.delete(whichUnit);\n\n  return 0;\n}\n\n/**\n * native GroupClear takes group whichGroup returns nothing\n */\nfunction GroupClear(C: Context, L: lua_State): number {\n  const whichGroup = <JassGroup>lua_touserdata(L, 1);\n\n  whichGroup.units.clear();\n\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsOfType takes group whichGroup, string unitname, boolexpr filter returns nothing\n */\nfunction GroupEnumUnitsOfType(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _unitname = luaL_checkstring(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('GroupEnumUnitsOfType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsOfPlayer takes group whichGroup, player whichPlayer, boolexpr filter returns nothing\n */\nfunction GroupEnumUnitsOfPlayer(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('GroupEnumUnitsOfPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsOfTypeCounted takes group whichGroup, string unitname, boolexpr filter, integer countLimit returns nothing\n */\nfunction GroupEnumUnitsOfTypeCounted(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _unitname = luaL_checkstring(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  const _countLimit = luaL_checkinteger(L, 4);\n  console.warn('GroupEnumUnitsOfTypeCounted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsInRect takes group whichGroup, rect r, boolexpr filter returns nothing\n */\nfunction GroupEnumUnitsInRect(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _r = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('GroupEnumUnitsInRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsInRectCounted takes group whichGroup, rect r, boolexpr filter, integer countLimit returns nothing\n */\nfunction GroupEnumUnitsInRectCounted(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _r = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  const _countLimit = luaL_checkinteger(L, 4);\n  console.warn('GroupEnumUnitsInRectCounted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsInRange takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing\n */\nfunction GroupEnumUnitsInRange(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _radius = luaL_checknumber(L, 4);\n  const _filter = lua_touserdata(L, 5);\n  console.warn('GroupEnumUnitsInRange was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsInRangeOfLoc takes group whichGroup, location whichLocation, real radius, boolexpr filter returns nothing\n */\nfunction GroupEnumUnitsInRangeOfLoc(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _filter = lua_touserdata(L, 4);\n  console.warn('GroupEnumUnitsInRangeOfLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsInRangeCounted takes group whichGroup, real x, real y, real radius, boolexpr filter, integer countLimit returns nothing\n */\nfunction GroupEnumUnitsInRangeCounted(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _radius = luaL_checknumber(L, 4);\n  const _filter = lua_touserdata(L, 5);\n  const _countLimit = luaL_checkinteger(L, 6);\n  console.warn('GroupEnumUnitsInRangeCounted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsInRangeOfLocCounted takes group whichGroup, location whichLocation, real radius, boolexpr filter, integer countLimit returns nothing\n */\nfunction GroupEnumUnitsInRangeOfLocCounted(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _filter = lua_touserdata(L, 4);\n  const _countLimit = luaL_checkinteger(L, 5);\n  console.warn('GroupEnumUnitsInRangeOfLocCounted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupEnumUnitsSelected takes group whichGroup, player whichPlayer, boolexpr filter returns nothing\n */\nfunction GroupEnumUnitsSelected(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('GroupEnumUnitsSelected was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GroupImmediateOrder takes group whichGroup, string order returns boolean\n */\nfunction GroupImmediateOrder(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  console.warn('GroupImmediateOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupImmediateOrderById takes group whichGroup, integer order returns boolean\n */\nfunction GroupImmediateOrderById(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  console.warn('GroupImmediateOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupPointOrder takes group whichGroup, string order, real x, real y returns boolean\n */\nfunction GroupPointOrder(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('GroupPointOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupPointOrderLoc takes group whichGroup, string order, location whichLocation returns boolean\n */\nfunction GroupPointOrderLoc(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _whichLocation = lua_touserdata(L, 3);\n  console.warn('GroupPointOrderLoc was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupPointOrderById takes group whichGroup, integer order, real x, real y returns boolean\n */\nfunction GroupPointOrderById(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('GroupPointOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupPointOrderByIdLoc takes group whichGroup, integer order, location whichLocation returns boolean\n */\nfunction GroupPointOrderByIdLoc(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _whichLocation = lua_touserdata(L, 3);\n  console.warn('GroupPointOrderByIdLoc was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupTargetOrder takes group whichGroup, string order, widget targetWidget returns boolean\n */\nfunction GroupTargetOrder(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  console.warn('GroupTargetOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GroupTargetOrderById takes group whichGroup, integer order, widget targetWidget returns boolean\n */\nfunction GroupTargetOrderById(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  console.warn('GroupTargetOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native ForGroup takes group whichGroup, code callback returns nothing\n */\nfunction ForGroup(C: Context, L: lua_State): number {\n  const whichGroup = <JassGroup>lua_touserdata(L, 1);\n  const callback = luaL_ref(L, LUA_REGISTRYINDEX);\n\n  for (const unit of whichGroup.units) {\n    C.enumUnit = unit;\n\n    C.call(callback);\n  }\n\n  C.enumUnit = null;\n\n  luaL_unref(L, LUA_REGISTRYINDEX, callback);\n\n  return 0;\n}\n\n/**\n * native FirstOfGroup takes group whichGroup returns unit\n */\nfunction FirstOfGroup(C: Context, L: lua_State): number {\n  const _whichGroup = lua_touserdata(L, 1);\n  console.warn('FirstOfGroup was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateForce takes nothing returns force\n */\nfunction CreateForce(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.addHandle(new JassForce()));\n\n  return 1;\n}\n\n/**\n * native DestroyForce takes force whichForce returns nothing\n */\nfunction DestroyForce(C: Context, L: lua_State): number {\n  const whichForce = <JassForce>lua_touserdata(L, 1);\n\n  C.freeHandle(whichForce);\n\n  return 0;\n}\n\n/**\n * native ForceAddPlayer takes force whichForce, player whichPlayer returns nothing\n */\nfunction ForceAddPlayer(C: Context, L: lua_State): number {\n  const whichForce = <JassForce>lua_touserdata(L, 1);\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 2);\n\n  whichForce.players.add(whichPlayer);\n\n  return 0;\n}\n\n/**\n * native ForceRemovePlayer takes force whichForce, player whichPlayer returns nothing\n */\nfunction ForceRemovePlayer(C: Context, L: lua_State): number {\n  const whichForce = <JassForce>lua_touserdata(L, 1);\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 2);\n\n  whichForce.players.delete(whichPlayer);\n\n  return 0;\n}\n\n/**\n * native ForceClear takes force whichForce returns nothing\n */\nfunction ForceClear(C: Context, L: lua_State): number {\n  const whichForce = <JassForce>lua_touserdata(L, 1);\n\n  whichForce.players.clear();\n\n  return 0;\n}\n\n/**\n * native ForceEnumPlayers takes force whichForce, boolexpr filter returns nothing\n */\nfunction ForceEnumPlayers(C: Context, L: lua_State): number {\n  const _whichForce = lua_touserdata(L, 1);\n  const _filter = lua_touserdata(L, 2);\n  console.warn('ForceEnumPlayers was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceEnumPlayersCounted takes force whichForce, boolexpr filter, integer countLimit returns nothing\n */\nfunction ForceEnumPlayersCounted(C: Context, L: lua_State): number {\n  const _whichForce = lua_touserdata(L, 1);\n  const _filter = lua_touserdata(L, 2);\n  const _countLimit = luaL_checkinteger(L, 3);\n  console.warn('ForceEnumPlayersCounted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceEnumAllies takes force whichForce, player whichPlayer, boolexpr filter returns nothing\n */\nfunction ForceEnumAllies(C: Context, L: lua_State): number {\n  const _whichForce = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('ForceEnumAllies was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceEnumEnemies takes force whichForce, player whichPlayer, boolexpr filter returns nothing\n */\nfunction ForceEnumEnemies(C: Context, L: lua_State): number {\n  const _whichForce = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('ForceEnumEnemies was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForForce takes force whichForce, code callback returns nothing\n */\nfunction ForForce(C: Context, L: lua_State): number {\n  const whichForce = <JassForce>lua_touserdata(L, 1);\n  const callback = luaL_ref(L, LUA_REGISTRYINDEX);\n\n  for (const player of whichForce.players) {\n    C.enumPlayer = player;\n\n    C.call(callback);\n  }\n\n  C.enumPlayer = null;\n\n  luaL_unref(L, LUA_REGISTRYINDEX, callback);\n\n  return 0;\n}\n\n/**\n * native Rect takes real minx, real miny, real maxx, real maxy returns rect\n */\nfunction Rect(C: Context, L: lua_State): number {\n  const _minx = luaL_checknumber(L, 1);\n  const _miny = luaL_checknumber(L, 2);\n  const _maxx = luaL_checknumber(L, 3);\n  const _maxy = luaL_checknumber(L, 4);\n  console.warn('Rect was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RectFromLoc takes location min, location max returns rect\n */\nfunction RectFromLoc(C: Context, L: lua_State): number {\n  const _min = lua_touserdata(L, 1);\n  const _max = lua_touserdata(L, 2);\n  console.warn('RectFromLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveRect takes rect whichRect returns nothing\n */\nfunction RemoveRect(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('RemoveRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetRect takes rect whichRect, real minx, real miny, real maxx, real maxy returns nothing\n */\nfunction SetRect(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  const _minx = luaL_checknumber(L, 2);\n  const _miny = luaL_checknumber(L, 3);\n  const _maxx = luaL_checknumber(L, 4);\n  const _maxy = luaL_checknumber(L, 5);\n  console.warn('SetRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetRectFromLoc takes rect whichRect, location min, location max returns nothing\n */\nfunction SetRectFromLoc(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  const _min = lua_touserdata(L, 2);\n  const _max = lua_touserdata(L, 3);\n  console.warn('SetRectFromLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MoveRectTo takes rect whichRect, real newCenterX, real newCenterY returns nothing\n */\nfunction MoveRectTo(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  const _newCenterX = luaL_checknumber(L, 2);\n  const _newCenterY = luaL_checknumber(L, 3);\n  console.warn('MoveRectTo was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MoveRectToLoc takes rect whichRect, location newCenterLoc returns nothing\n */\nfunction MoveRectToLoc(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  const _newCenterLoc = lua_touserdata(L, 2);\n  console.warn('MoveRectToLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetRectCenterX takes rect whichRect returns real\n */\nfunction GetRectCenterX(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('GetRectCenterX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetRectCenterY takes rect whichRect returns real\n */\nfunction GetRectCenterY(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('GetRectCenterY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetRectMinX takes rect whichRect returns real\n */\nfunction GetRectMinX(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('GetRectMinX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetRectMinY takes rect whichRect returns real\n */\nfunction GetRectMinY(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('GetRectMinY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetRectMaxX takes rect whichRect returns real\n */\nfunction GetRectMaxX(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('GetRectMaxX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetRectMaxY takes rect whichRect returns real\n */\nfunction GetRectMaxY(C: Context, L: lua_State): number {\n  const _whichRect = lua_touserdata(L, 1);\n  console.warn('GetRectMaxY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native CreateRegion takes nothing returns region\n */\nfunction CreateRegion(C: Context, L: lua_State): number {\n\n  console.warn('CreateRegion was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveRegion takes region whichRegion returns nothing\n */\nfunction RemoveRegion(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  console.warn('RemoveRegion was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RegionAddRect takes region whichRegion, rect r returns nothing\n */\nfunction RegionAddRect(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _r = lua_touserdata(L, 2);\n  console.warn('RegionAddRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RegionClearRect takes region whichRegion, rect r returns nothing\n */\nfunction RegionClearRect(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _r = lua_touserdata(L, 2);\n  console.warn('RegionClearRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RegionAddCell takes region whichRegion, real x, real y returns nothing\n */\nfunction RegionAddCell(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('RegionAddCell was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RegionAddCellAtLoc takes region whichRegion, location whichLocation returns nothing\n */\nfunction RegionAddCellAtLoc(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  console.warn('RegionAddCellAtLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RegionClearCell takes region whichRegion, real x, real y returns nothing\n */\nfunction RegionClearCell(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('RegionClearCell was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RegionClearCellAtLoc takes region whichRegion, location whichLocation returns nothing\n */\nfunction RegionClearCellAtLoc(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  console.warn('RegionClearCellAtLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native Location takes real x, real y returns location\n */\nfunction Location(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('Location was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveLocation takes location whichLocation returns nothing\n */\nfunction RemoveLocation(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  console.warn('RemoveLocation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MoveLocation takes location whichLocation, real newX, real newY returns nothing\n */\nfunction MoveLocation(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  const _newX = luaL_checknumber(L, 2);\n  const _newY = luaL_checknumber(L, 3);\n  console.warn('MoveLocation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetLocationX takes location whichLocation returns real\n */\nfunction GetLocationX(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  console.warn('GetLocationX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetLocationY takes location whichLocation returns real\n */\nfunction GetLocationY(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  console.warn('GetLocationY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetLocationZ takes location whichLocation returns real\n */\nfunction GetLocationZ(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  console.warn('GetLocationZ was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native IsUnitInRegion takes region whichRegion, unit whichUnit returns boolean\n */\nfunction IsUnitInRegion(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  console.warn('IsUnitInRegion was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsPointInRegion takes region whichRegion, real x, real y returns boolean\n */\nfunction IsPointInRegion(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('IsPointInRegion was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsLocationInRegion takes region whichRegion, location whichLocation returns boolean\n */\nfunction IsLocationInRegion(C: Context, L: lua_State): number {\n  const _whichRegion = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  console.warn('IsLocationInRegion was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetWorldBounds takes nothing returns rect\n */\nfunction GetWorldBounds(C: Context, L: lua_State): number {\n\n  console.warn('GetWorldBounds was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateTrigger takes nothing returns trigger\n */\nfunction CreateTrigger(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.addHandle(new JassTrigger()));\n\n  return 1;\n}\n\n/**\n * native DestroyTrigger takes trigger whichTrigger returns nothing\n */\nfunction DestroyTrigger(C: Context, L: lua_State): number {\n  const whichTrigger = <JassTrigger>lua_touserdata(L, 1);\n\n  // In case it's registered, remove it.\n  C.triggers.delete(whichTrigger);\n\n  C.freeHandle(whichTrigger);\n\n  return 0;\n}\n\n/**\n * native ResetTrigger takes trigger whichTrigger returns nothing\n */\nfunction ResetTrigger(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('ResetTrigger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableTrigger takes trigger whichTrigger returns nothing\n */\nfunction EnableTrigger(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('EnableTrigger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisableTrigger takes trigger whichTrigger returns nothing\n */\nfunction DisableTrigger(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('DisableTrigger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsTriggerEnabled takes trigger whichTrigger returns boolean\n */\nfunction IsTriggerEnabled(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('IsTriggerEnabled was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native TriggerWaitOnSleeps takes trigger whichTrigger, boolean flag returns nothing\n */\nfunction TriggerWaitOnSleeps(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('TriggerWaitOnSleeps was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsTriggerWaitOnSleeps takes trigger whichTrigger returns boolean\n */\nfunction IsTriggerWaitOnSleeps(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('IsTriggerWaitOnSleeps was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native GetFilterUnit takes nothing returns unit\n */\nfunction GetFilterUnit(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.filterUnit);\n\n  return 1;\n}\n\n/**\n * constant native GetEnumUnit takes nothing returns unit\n */\nfunction GetEnumUnit(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.enumUnit);\n\n  return 1;\n}\n\n/**\n * constant native GetFilterDestructable takes nothing returns destructable\n */\nfunction GetFilterDestructable(C: Context, L: lua_State): number {\n\n  console.warn('GetFilterDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEnumDestructable takes nothing returns destructable\n */\nfunction GetEnumDestructable(C: Context, L: lua_State): number {\n\n  console.warn('GetEnumDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetFilterItem takes nothing returns item\n */\nfunction GetFilterItem(C: Context, L: lua_State): number {\n\n  console.warn('GetFilterItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEnumItem takes nothing returns item\n */\nfunction GetEnumItem(C: Context, L: lua_State): number {\n\n  console.warn('GetEnumItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetFilterPlayer takes nothing returns player\n */\nfunction GetFilterPlayer(C: Context, L: lua_State): number {\n\n  console.warn('GetFilterPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEnumPlayer takes nothing returns player\n */\nfunction GetEnumPlayer(C: Context, L: lua_State): number {\n  lua_pushlightuserdata(L, C.enumPlayer);\n\n  return 1;\n}\n\n/**\n * constant native GetTriggeringTrigger takes nothing returns trigger\n */\nfunction GetTriggeringTrigger(C: Context, L: lua_State): number {\n  const thread = C.currentThread;\n\n  if (thread && thread.triggeringTrigger) {\n    lua_pushlightuserdata(L, thread.triggeringTrigger);\n  } else {\n    lua_pushnil(L);\n  }\n\n  return 1;\n}\n\n/**\n * constant native GetTriggerEventId takes nothing returns eventid\n */\nfunction GetTriggerEventId(C: Context, L: lua_State): number {\n\n  console.warn('GetTriggerEventId was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTriggerEvalCount takes trigger whichTrigger returns integer\n */\nfunction GetTriggerEvalCount(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('GetTriggerEvalCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetTriggerExecCount takes trigger whichTrigger returns integer\n */\nfunction GetTriggerExecCount(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('GetTriggerExecCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native ExecuteFunc takes string funcName returns nothing\n */\nfunction ExecuteFunc(C: Context, L: lua_State): number {\n  const _funcName = luaL_checkstring(L, 1);\n  console.warn('ExecuteFunc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native And takes boolexpr operandA, boolexpr operandB returns boolexpr\n */\nfunction And(C: Context, L: lua_State): number {\n  const _operandA = lua_touserdata(L, 1);\n  const _operandB = lua_touserdata(L, 2);\n  console.warn('And was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native Or takes boolexpr operandA, boolexpr operandB returns boolexpr\n */\nfunction Or(C: Context, L: lua_State): number {\n  const _operandA = lua_touserdata(L, 1);\n  const _operandB = lua_touserdata(L, 2);\n  console.warn('Or was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native Not takes boolexpr operand returns boolexpr\n */\nfunction Not(C: Context, L: lua_State): number {\n  const _operand = lua_touserdata(L, 1);\n  console.warn('Not was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native Condition takes code func returns conditionfunc\n */\nfunction Condition(C: Context, L: lua_State): number {\n  const _func = luaL_ref(L, LUA_REGISTRYINDEX);\n  console.warn('Condition was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyCondition takes conditionfunc c returns nothing\n */\nfunction DestroyCondition(C: Context, L: lua_State): number {\n  const _c = lua_touserdata(L, 1);\n  console.warn('DestroyCondition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native Filter takes code func returns filterfunc\n */\nfunction Filter(C: Context, L: lua_State): number {\n  const _func = luaL_ref(L, LUA_REGISTRYINDEX);\n  console.warn('Filter was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyFilter takes filterfunc f returns nothing\n */\nfunction DestroyFilter(C: Context, L: lua_State): number {\n  const _f = lua_touserdata(L, 1);\n  console.warn('DestroyFilter was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DestroyBoolExpr takes boolexpr e returns nothing\n */\nfunction DestroyBoolExpr(C: Context, L: lua_State): number {\n  const _e = lua_touserdata(L, 1);\n  console.warn('DestroyBoolExpr was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerRegisterVariableEvent takes trigger whichTrigger, string varName, limitop opcode, real limitval returns event\n */\nfunction TriggerRegisterVariableEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _varName = luaL_checkstring(L, 2);\n  const _opcode = lua_touserdata(L, 3);\n  const _limitval = luaL_checknumber(L, 4);\n  console.warn('TriggerRegisterVariableEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterTimerEvent takes trigger whichTrigger, real timeout, boolean periodic returns event\n */\nfunction TriggerRegisterTimerEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _timeout = luaL_checknumber(L, 2);\n  const _periodic = lua_toboolean(L, 3);\n  console.warn('TriggerRegisterTimerEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterTimerExpireEvent takes trigger whichTrigger, timer t returns event\n */\nfunction TriggerRegisterTimerExpireEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _t = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterTimerExpireEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterGameStateEvent takes trigger whichTrigger, gamestate whichState, limitop opcode, real limitval returns event\n */\nfunction TriggerRegisterGameStateEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _opcode = lua_touserdata(L, 3);\n  const _limitval = luaL_checknumber(L, 4);\n  console.warn('TriggerRegisterGameStateEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterDialogEvent takes trigger whichTrigger, dialog whichDialog returns event\n */\nfunction TriggerRegisterDialogEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichDialog = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterDialogEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterDialogButtonEvent takes trigger whichTrigger, button whichButton returns event\n */\nfunction TriggerRegisterDialogButtonEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichButton = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterDialogButtonEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventGameState takes nothing returns gamestate\n */\nfunction GetEventGameState(C: Context, L: lua_State): number {\n\n  console.warn('GetEventGameState was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterGameEvent takes trigger whichTrigger, gameevent whichGameEvent returns event\n */\nfunction TriggerRegisterGameEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichGameEvent = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterGameEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetWinningPlayer takes nothing returns player\n */\nfunction GetWinningPlayer(C: Context, L: lua_State): number {\n\n  console.warn('GetWinningPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterEnterRegion takes trigger whichTrigger, region whichRegion, boolexpr filter returns event\n */\nfunction TriggerRegisterEnterRegion(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichRegion = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('TriggerRegisterEnterRegion was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTriggeringRegion takes nothing returns region\n */\nfunction GetTriggeringRegion(C: Context, L: lua_State): number {\n\n  console.warn('GetTriggeringRegion was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEnteringUnit takes nothing returns unit\n */\nfunction GetEnteringUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetEnteringUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterLeaveRegion takes trigger whichTrigger, region whichRegion, boolexpr filter returns event\n */\nfunction TriggerRegisterLeaveRegion(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichRegion = lua_touserdata(L, 2);\n  const _filter = lua_touserdata(L, 3);\n  console.warn('TriggerRegisterLeaveRegion was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetLeavingUnit takes nothing returns unit\n */\nfunction GetLeavingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetLeavingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterTrackableHitEvent takes trigger whichTrigger, trackable t returns event\n */\nfunction TriggerRegisterTrackableHitEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _t = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterTrackableHitEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterTrackableTrackEvent takes trigger whichTrigger, trackable t returns event\n */\nfunction TriggerRegisterTrackableTrackEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _t = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterTrackableTrackEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTriggeringTrackable takes nothing returns trackable\n */\nfunction GetTriggeringTrackable(C: Context, L: lua_State): number {\n\n  console.warn('GetTriggeringTrackable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetClickedButton takes nothing returns button\n */\nfunction GetClickedButton(C: Context, L: lua_State): number {\n\n  console.warn('GetClickedButton was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetClickedDialog takes nothing returns dialog\n */\nfunction GetClickedDialog(C: Context, L: lua_State): number {\n\n  console.warn('GetClickedDialog was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTournamentFinishSoonTimeRemaining takes nothing returns real\n */\nfunction GetTournamentFinishSoonTimeRemaining(C: Context, L: lua_State): number {\n\n  console.warn('GetTournamentFinishSoonTimeRemaining was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetTournamentFinishNowRule takes nothing returns integer\n */\nfunction GetTournamentFinishNowRule(C: Context, L: lua_State): number {\n\n  console.warn('GetTournamentFinishNowRule was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetTournamentFinishNowPlayer takes nothing returns player\n */\nfunction GetTournamentFinishNowPlayer(C: Context, L: lua_State): number {\n\n  console.warn('GetTournamentFinishNowPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTournamentScore takes player whichPlayer returns integer\n */\nfunction GetTournamentScore(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('GetTournamentScore was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetSaveBasicFilename takes nothing returns string\n */\nfunction GetSaveBasicFilename(C: Context, L: lua_State): number {\n\n  console.warn('GetSaveBasicFilename was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native TriggerRegisterPlayerEvent takes trigger whichTrigger, player whichPlayer, playerevent whichPlayerEvent returns event\n */\nfunction TriggerRegisterPlayerEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _whichPlayerEvent = lua_touserdata(L, 3);\n  console.warn('TriggerRegisterPlayerEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTriggerPlayer takes nothing returns player\n */\nfunction GetTriggerPlayer(C: Context, L: lua_State): number {\n\n  console.warn('GetTriggerPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterPlayerUnitEvent takes trigger whichTrigger, player whichPlayer, playerunitevent whichPlayerUnitEvent, boolexpr filter returns event\n */\nfunction TriggerRegisterPlayerUnitEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _whichPlayerUnitEvent = lua_touserdata(L, 3);\n  const _filter = lua_touserdata(L, 4);\n  console.warn('TriggerRegisterPlayerUnitEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetLevelingUnit takes nothing returns unit\n */\nfunction GetLevelingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetLevelingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetLearningUnit takes nothing returns unit\n */\nfunction GetLearningUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetLearningUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetLearnedSkill takes nothing returns integer\n */\nfunction GetLearnedSkill(C: Context, L: lua_State): number {\n\n  console.warn('GetLearnedSkill was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetLearnedSkillLevel takes nothing returns integer\n */\nfunction GetLearnedSkillLevel(C: Context, L: lua_State): number {\n\n  console.warn('GetLearnedSkillLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetRevivableUnit takes nothing returns unit\n */\nfunction GetRevivableUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetRevivableUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetRevivingUnit takes nothing returns unit\n */\nfunction GetRevivingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetRevivingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetAttacker takes nothing returns unit\n */\nfunction GetAttacker(C: Context, L: lua_State): number {\n\n  console.warn('GetAttacker was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetRescuer takes nothing returns unit\n */\nfunction GetRescuer(C: Context, L: lua_State): number {\n\n  console.warn('GetRescuer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetDyingUnit takes nothing returns unit\n */\nfunction GetDyingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetDyingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetKillingUnit takes nothing returns unit\n */\nfunction GetKillingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetKillingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetDecayingUnit takes nothing returns unit\n */\nfunction GetDecayingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetDecayingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetConstructingStructure takes nothing returns unit\n */\nfunction GetConstructingStructure(C: Context, L: lua_State): number {\n\n  console.warn('GetConstructingStructure was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetCancelledStructure takes nothing returns unit\n */\nfunction GetCancelledStructure(C: Context, L: lua_State): number {\n\n  console.warn('GetCancelledStructure was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetConstructedStructure takes nothing returns unit\n */\nfunction GetConstructedStructure(C: Context, L: lua_State): number {\n\n  console.warn('GetConstructedStructure was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetResearchingUnit takes nothing returns unit\n */\nfunction GetResearchingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetResearchingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetResearched takes nothing returns integer\n */\nfunction GetResearched(C: Context, L: lua_State): number {\n\n  console.warn('GetResearched was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetTrainedUnitType takes nothing returns integer\n */\nfunction GetTrainedUnitType(C: Context, L: lua_State): number {\n\n  console.warn('GetTrainedUnitType was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetTrainedUnit takes nothing returns unit\n */\nfunction GetTrainedUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetTrainedUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetDetectedUnit takes nothing returns unit\n */\nfunction GetDetectedUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetDetectedUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSummoningUnit takes nothing returns unit\n */\nfunction GetSummoningUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetSummoningUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSummonedUnit takes nothing returns unit\n */\nfunction GetSummonedUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetSummonedUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTransportUnit takes nothing returns unit\n */\nfunction GetTransportUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetTransportUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetLoadedUnit takes nothing returns unit\n */\nfunction GetLoadedUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetLoadedUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSellingUnit takes nothing returns unit\n */\nfunction GetSellingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetSellingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSoldUnit takes nothing returns unit\n */\nfunction GetSoldUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetSoldUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetBuyingUnit takes nothing returns unit\n */\nfunction GetBuyingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetBuyingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSoldItem takes nothing returns item\n */\nfunction GetSoldItem(C: Context, L: lua_State): number {\n\n  console.warn('GetSoldItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetChangingUnit takes nothing returns unit\n */\nfunction GetChangingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetChangingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetChangingUnitPrevOwner takes nothing returns player\n */\nfunction GetChangingUnitPrevOwner(C: Context, L: lua_State): number {\n\n  console.warn('GetChangingUnitPrevOwner was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetManipulatingUnit takes nothing returns unit\n */\nfunction GetManipulatingUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetManipulatingUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetManipulatedItem takes nothing returns item\n */\nfunction GetManipulatedItem(C: Context, L: lua_State): number {\n\n  console.warn('GetManipulatedItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetOrderedUnit takes nothing returns unit\n */\nfunction GetOrderedUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderedUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetIssuedOrderId takes nothing returns integer\n */\nfunction GetIssuedOrderId(C: Context, L: lua_State): number {\n\n  console.warn('GetIssuedOrderId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetOrderPointX takes nothing returns real\n */\nfunction GetOrderPointX(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderPointX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetOrderPointY takes nothing returns real\n */\nfunction GetOrderPointY(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderPointY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetOrderPointLoc takes nothing returns location\n */\nfunction GetOrderPointLoc(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderPointLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetOrderTarget takes nothing returns widget\n */\nfunction GetOrderTarget(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderTarget was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetOrderTargetDestructable takes nothing returns destructable\n */\nfunction GetOrderTargetDestructable(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderTargetDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetOrderTargetItem takes nothing returns item\n */\nfunction GetOrderTargetItem(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderTargetItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetOrderTargetUnit takes nothing returns unit\n */\nfunction GetOrderTargetUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetOrderTargetUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSpellAbilityUnit takes nothing returns unit\n */\nfunction GetSpellAbilityUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellAbilityUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSpellAbilityId takes nothing returns integer\n */\nfunction GetSpellAbilityId(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellAbilityId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetSpellAbility takes nothing returns ability\n */\nfunction GetSpellAbility(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellAbility was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSpellTargetLoc takes nothing returns location\n */\nfunction GetSpellTargetLoc(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellTargetLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSpellTargetX takes nothing returns real\n */\nfunction GetSpellTargetX(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellTargetX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetSpellTargetY takes nothing returns real\n */\nfunction GetSpellTargetY(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellTargetY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetSpellTargetDestructable takes nothing returns destructable\n */\nfunction GetSpellTargetDestructable(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellTargetDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSpellTargetItem takes nothing returns item\n */\nfunction GetSpellTargetItem(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellTargetItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetSpellTargetUnit takes nothing returns unit\n */\nfunction GetSpellTargetUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetSpellTargetUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterPlayerAllianceChange takes trigger whichTrigger, player whichPlayer, alliancetype whichAlliance returns event\n */\nfunction TriggerRegisterPlayerAllianceChange(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _whichAlliance = lua_touserdata(L, 3);\n  console.warn('TriggerRegisterPlayerAllianceChange was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterPlayerStateEvent takes trigger whichTrigger, player whichPlayer, playerstate whichState, limitop opcode, real limitval returns event\n */\nfunction TriggerRegisterPlayerStateEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _whichState = lua_touserdata(L, 3);\n  const _opcode = lua_touserdata(L, 4);\n  const _limitval = luaL_checknumber(L, 5);\n  console.warn('TriggerRegisterPlayerStateEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventPlayerState takes nothing returns playerstate\n */\nfunction GetEventPlayerState(C: Context, L: lua_State): number {\n\n  console.warn('GetEventPlayerState was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterPlayerChatEvent takes trigger whichTrigger, player whichPlayer, string chatMessageToDetect, boolean exactMatchOnly returns event\n */\nfunction TriggerRegisterPlayerChatEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _chatMessageToDetect = luaL_checkstring(L, 3);\n  const _exactMatchOnly = lua_toboolean(L, 4);\n  console.warn('TriggerRegisterPlayerChatEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventPlayerChatString takes nothing returns string\n */\nfunction GetEventPlayerChatString(C: Context, L: lua_State): number {\n\n  console.warn('GetEventPlayerChatString was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native GetEventPlayerChatStringMatched takes nothing returns string\n */\nfunction GetEventPlayerChatStringMatched(C: Context, L: lua_State): number {\n\n  console.warn('GetEventPlayerChatStringMatched was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native TriggerRegisterDeathEvent takes trigger whichTrigger, widget whichWidget returns event\n */\nfunction TriggerRegisterDeathEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichWidget = lua_touserdata(L, 2);\n  console.warn('TriggerRegisterDeathEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetTriggerUnit takes nothing returns unit\n */\nfunction GetTriggerUnit(C: Context, L: lua_State): number {\n  const thread = C.currentThread;\n\n  if (thread && thread.triggerUnit) {\n    lua_pushlightuserdata(L, thread.triggerUnit);\n  } else {\n    lua_pushnil(L);\n  }\n\n  return 1;\n}\n\n/**\n * native TriggerRegisterUnitStateEvent takes trigger whichTrigger, unit whichUnit, unitstate whichState, limitop opcode, real limitval returns event\n */\nfunction TriggerRegisterUnitStateEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  const _whichState = lua_touserdata(L, 3);\n  const _opcode = lua_touserdata(L, 4);\n  const _limitval = luaL_checknumber(L, 5);\n  console.warn('TriggerRegisterUnitStateEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventUnitState takes nothing returns unitstate\n */\nfunction GetEventUnitState(C: Context, L: lua_State): number {\n\n  console.warn('GetEventUnitState was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterUnitEvent takes trigger whichTrigger, unit whichUnit, unitevent whichEvent returns event\n */\nfunction TriggerRegisterUnitEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  const _whichEvent = lua_touserdata(L, 3);\n  console.warn('TriggerRegisterUnitEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventDamage takes nothing returns real\n */\nfunction GetEventDamage(C: Context, L: lua_State): number {\n\n  console.warn('GetEventDamage was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetEventDamageSource takes nothing returns unit\n */\nfunction GetEventDamageSource(C: Context, L: lua_State): number {\n\n  console.warn('GetEventDamageSource was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventDetectingPlayer takes nothing returns player\n */\nfunction GetEventDetectingPlayer(C: Context, L: lua_State): number {\n\n  console.warn('GetEventDetectingPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterFilterUnitEvent takes trigger whichTrigger, unit whichUnit, unitevent whichEvent, boolexpr filter returns event\n */\nfunction TriggerRegisterFilterUnitEvent(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  const _whichEvent = lua_touserdata(L, 3);\n  const _filter = lua_touserdata(L, 4);\n  console.warn('TriggerRegisterFilterUnitEvent was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetEventTargetUnit takes nothing returns unit\n */\nfunction GetEventTargetUnit(C: Context, L: lua_State): number {\n\n  console.warn('GetEventTargetUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRegisterUnitInRange takes trigger whichTrigger, unit whichUnit, real range, boolexpr filter returns event\n */\nfunction TriggerRegisterUnitInRange(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  const _range = luaL_checknumber(L, 3);\n  const _filter = lua_touserdata(L, 4);\n  console.warn('TriggerRegisterUnitInRange was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerAddCondition takes trigger whichTrigger, boolexpr condition returns triggercondition\n */\nfunction TriggerAddCondition(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _condition = lua_touserdata(L, 2);\n  console.warn('TriggerAddCondition was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRemoveCondition takes trigger whichTrigger, triggercondition whichCondition returns nothing\n */\nfunction TriggerRemoveCondition(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichCondition = lua_touserdata(L, 2);\n  console.warn('TriggerRemoveCondition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerClearConditions takes trigger whichTrigger returns nothing\n */\nfunction TriggerClearConditions(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('TriggerClearConditions was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerAddAction takes trigger whichTrigger, code actionFunc returns triggeraction\n */\nfunction TriggerAddAction(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _actionFunc = luaL_ref(L, LUA_REGISTRYINDEX);\n  console.warn('TriggerAddAction was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TriggerRemoveAction takes trigger whichTrigger, triggeraction whichAction returns nothing\n */\nfunction TriggerRemoveAction(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  const _whichAction = lua_touserdata(L, 2);\n  console.warn('TriggerRemoveAction was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerClearActions takes trigger whichTrigger returns nothing\n */\nfunction TriggerClearActions(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('TriggerClearActions was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerSleepAction takes real timeout returns nothing\n */\nfunction TriggerSleepAction(C: Context, L: lua_State): number {\n  const timeout = luaL_checknumber(L, 1);\n\n  lua_pushnumber(L, timeout);\n\n  lua_yield(L, 1);\n\n  return 0;\n}\n\n/**\n * native TriggerWaitForSound takes sound s, real offset returns nothing\n */\nfunction TriggerWaitForSound(C: Context, L: lua_State): number {\n  const _s = lua_touserdata(L, 1);\n  const _offset = luaL_checknumber(L, 2);\n  console.warn('TriggerWaitForSound was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerEvaluate takes trigger whichTrigger returns boolean\n */\nfunction TriggerEvaluate(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('TriggerEvaluate was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native TriggerExecute takes trigger whichTrigger returns nothing\n */\nfunction TriggerExecute(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('TriggerExecute was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerExecuteWait takes trigger whichTrigger returns nothing\n */\nfunction TriggerExecuteWait(C: Context, L: lua_State): number {\n  const _whichTrigger = lua_touserdata(L, 1);\n  console.warn('TriggerExecuteWait was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerSyncStart takes nothing returns nothing\n */\nfunction TriggerSyncStart(_C: Context, _L: lua_State): number {\n\n  console.warn('TriggerSyncStart was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TriggerSyncReady takes nothing returns nothing\n */\nfunction TriggerSyncReady(_C: Context, _L: lua_State): number {\n\n  console.warn('TriggerSyncReady was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetWidgetLife takes widget whichWidget returns real\n */\nfunction GetWidgetLife(C: Context, L: lua_State): number {\n  const _whichWidget = lua_touserdata(L, 1);\n  console.warn('GetWidgetLife was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetWidgetLife takes widget whichWidget, real newLife returns nothing\n */\nfunction SetWidgetLife(C: Context, L: lua_State): number {\n  const _whichWidget = lua_touserdata(L, 1);\n  const _newLife = luaL_checknumber(L, 2);\n  console.warn('SetWidgetLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetWidgetX takes widget whichWidget returns real\n */\nfunction GetWidgetX(C: Context, L: lua_State): number {\n  const _whichWidget = lua_touserdata(L, 1);\n  console.warn('GetWidgetX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetWidgetY takes widget whichWidget returns real\n */\nfunction GetWidgetY(C: Context, L: lua_State): number {\n  const _whichWidget = lua_touserdata(L, 1);\n  console.warn('GetWidgetY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetTriggerWidget takes nothing returns widget\n */\nfunction GetTriggerWidget(C: Context, L: lua_State): number {\n\n  console.warn('GetTriggerWidget was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateDestructable takes integer objectid, real x, real y, real face, real scale, integer variation returns destructable\n */\nfunction CreateDestructable(C: Context, L: lua_State): number {\n  const _objectid = luaL_checkinteger(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _face = luaL_checknumber(L, 4);\n  const _scale = luaL_checknumber(L, 5);\n  const _variation = luaL_checkinteger(L, 6);\n  console.warn('CreateDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateDestructableZ takes integer objectid, real x, real y, real z, real face, real scale, integer variation returns destructable\n */\nfunction CreateDestructableZ(C: Context, L: lua_State): number {\n  const _objectid = luaL_checkinteger(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  const _face = luaL_checknumber(L, 5);\n  const _scale = luaL_checknumber(L, 6);\n  const _variation = luaL_checkinteger(L, 7);\n  console.warn('CreateDestructableZ was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateDeadDestructable takes integer objectid, real x, real y, real face, real scale, integer variation returns destructable\n */\nfunction CreateDeadDestructable(C: Context, L: lua_State): number {\n  const _objectid = luaL_checkinteger(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _face = luaL_checknumber(L, 4);\n  const _scale = luaL_checknumber(L, 5);\n  const _variation = luaL_checkinteger(L, 6);\n  console.warn('CreateDeadDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateDeadDestructableZ takes integer objectid, real x, real y, real z, real face, real scale, integer variation returns destructable\n */\nfunction CreateDeadDestructableZ(C: Context, L: lua_State): number {\n  const _objectid = luaL_checkinteger(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  const _face = luaL_checknumber(L, 5);\n  const _scale = luaL_checknumber(L, 6);\n  const _variation = luaL_checkinteger(L, 7);\n  console.warn('CreateDeadDestructableZ was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveDestructable takes destructable d returns nothing\n */\nfunction RemoveDestructable(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('RemoveDestructable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native KillDestructable takes destructable d returns nothing\n */\nfunction KillDestructable(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('KillDestructable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetDestructableInvulnerable takes destructable d, boolean flag returns nothing\n */\nfunction SetDestructableInvulnerable(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetDestructableInvulnerable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsDestructableInvulnerable takes destructable d returns boolean\n */\nfunction IsDestructableInvulnerable(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('IsDestructableInvulnerable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native EnumDestructablesInRect takes rect r, boolexpr filter, code actionFunc returns nothing\n */\nfunction EnumDestructablesInRect(C: Context, L: lua_State): number {\n  const _r = lua_touserdata(L, 1);\n  const _filter = lua_touserdata(L, 2);\n  const _actionFunc = luaL_ref(L, LUA_REGISTRYINDEX);\n  console.warn('EnumDestructablesInRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetDestructableTypeId takes destructable d returns integer\n */\nfunction GetDestructableTypeId(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableTypeId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetDestructableX takes destructable d returns real\n */\nfunction GetDestructableX(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetDestructableY takes destructable d returns real\n */\nfunction GetDestructableY(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetDestructableLife takes destructable d, real life returns nothing\n */\nfunction SetDestructableLife(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _life = luaL_checknumber(L, 2);\n  console.warn('SetDestructableLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetDestructableLife takes destructable d returns real\n */\nfunction GetDestructableLife(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableLife was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetDestructableMaxLife takes destructable d, real max returns nothing\n */\nfunction SetDestructableMaxLife(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _max = luaL_checknumber(L, 2);\n  console.warn('SetDestructableMaxLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetDestructableMaxLife takes destructable d returns real\n */\nfunction GetDestructableMaxLife(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableMaxLife was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native DestructableRestoreLife takes destructable d, real life, boolean birth returns nothing\n */\nfunction DestructableRestoreLife(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _life = luaL_checknumber(L, 2);\n  const _birth = lua_toboolean(L, 3);\n  console.warn('DestructableRestoreLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QueueDestructableAnimation takes destructable d, string whichAnimation returns nothing\n */\nfunction QueueDestructableAnimation(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _whichAnimation = luaL_checkstring(L, 2);\n  console.warn('QueueDestructableAnimation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetDestructableAnimation takes destructable d, string whichAnimation returns nothing\n */\nfunction SetDestructableAnimation(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _whichAnimation = luaL_checkstring(L, 2);\n  console.warn('SetDestructableAnimation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetDestructableAnimationSpeed takes destructable d, real speedFactor returns nothing\n */\nfunction SetDestructableAnimationSpeed(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _speedFactor = luaL_checknumber(L, 2);\n  console.warn('SetDestructableAnimationSpeed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ShowDestructable takes destructable d, boolean flag returns nothing\n */\nfunction ShowDestructable(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('ShowDestructable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetDestructableOccluderHeight takes destructable d returns real\n */\nfunction GetDestructableOccluderHeight(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableOccluderHeight was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetDestructableOccluderHeight takes destructable d, real height returns nothing\n */\nfunction SetDestructableOccluderHeight(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  const _height = luaL_checknumber(L, 2);\n  console.warn('SetDestructableOccluderHeight was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetDestructableName takes destructable d returns string\n */\nfunction GetDestructableName(C: Context, L: lua_State): number {\n  const _d = lua_touserdata(L, 1);\n  console.warn('GetDestructableName was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native GetTriggerDestructable takes nothing returns destructable\n */\nfunction GetTriggerDestructable(C: Context, L: lua_State): number {\n\n  console.warn('GetTriggerDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateItem takes integer itemid, real x, real y returns item\n */\nfunction CreateItem(C: Context, L: lua_State): number {\n  const _itemid = luaL_checkinteger(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('CreateItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveItem takes item whichItem returns nothing\n */\nfunction RemoveItem(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('RemoveItem was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetItemPlayer takes item whichItem returns player\n */\nfunction GetItemPlayer(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('GetItemPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native GetItemTypeId takes item i returns integer\n */\nfunction GetItemTypeId(C: Context, L: lua_State): number {\n  const _i = lua_touserdata(L, 1);\n  console.warn('GetItemTypeId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetItemX takes item i returns real\n */\nfunction GetItemX(C: Context, L: lua_State): number {\n  const _i = lua_touserdata(L, 1);\n  console.warn('GetItemX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetItemY takes item i returns real\n */\nfunction GetItemY(C: Context, L: lua_State): number {\n  const _i = lua_touserdata(L, 1);\n  console.warn('GetItemY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetItemPosition takes item i, real x, real y returns nothing\n */\nfunction SetItemPosition(C: Context, L: lua_State): number {\n  const _i = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('SetItemPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetItemDropOnDeath takes item whichItem, boolean flag returns nothing\n */\nfunction SetItemDropOnDeath(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetItemDropOnDeath was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetItemDroppable takes item i, boolean flag returns nothing\n */\nfunction SetItemDroppable(C: Context, L: lua_State): number {\n  const _i = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetItemDroppable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetItemPawnable takes item i, boolean flag returns nothing\n */\nfunction SetItemPawnable(C: Context, L: lua_State): number {\n  const _i = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetItemPawnable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetItemPlayer takes item whichItem, player whichPlayer, boolean changeColor returns nothing\n */\nfunction SetItemPlayer(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _changeColor = lua_toboolean(L, 3);\n  console.warn('SetItemPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetItemInvulnerable takes item whichItem, boolean flag returns nothing\n */\nfunction SetItemInvulnerable(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetItemInvulnerable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsItemInvulnerable takes item whichItem returns boolean\n */\nfunction IsItemInvulnerable(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('IsItemInvulnerable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetItemVisible takes item whichItem, boolean show returns nothing\n */\nfunction SetItemVisible(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _show = lua_toboolean(L, 2);\n  console.warn('SetItemVisible was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsItemVisible takes item whichItem returns boolean\n */\nfunction IsItemVisible(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('IsItemVisible was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemOwned takes item whichItem returns boolean\n */\nfunction IsItemOwned(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('IsItemOwned was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemPowerup takes item whichItem returns boolean\n */\nfunction IsItemPowerup(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('IsItemPowerup was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemSellable takes item whichItem returns boolean\n */\nfunction IsItemSellable(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('IsItemSellable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemPawnable takes item whichItem returns boolean\n */\nfunction IsItemPawnable(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('IsItemPawnable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemIdPowerup takes integer itemId returns boolean\n */\nfunction IsItemIdPowerup(C: Context, L: lua_State): number {\n  const _itemId = luaL_checkinteger(L, 1);\n  console.warn('IsItemIdPowerup was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemIdSellable takes integer itemId returns boolean\n */\nfunction IsItemIdSellable(C: Context, L: lua_State): number {\n  const _itemId = luaL_checkinteger(L, 1);\n  console.warn('IsItemIdSellable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsItemIdPawnable takes integer itemId returns boolean\n */\nfunction IsItemIdPawnable(C: Context, L: lua_State): number {\n  const _itemId = luaL_checkinteger(L, 1);\n  console.warn('IsItemIdPawnable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native EnumItemsInRect takes rect r, boolexpr filter, code actionFunc returns nothing\n */\nfunction EnumItemsInRect(C: Context, L: lua_State): number {\n  const _r = lua_touserdata(L, 1);\n  const _filter = lua_touserdata(L, 2);\n  const _actionFunc = luaL_ref(L, LUA_REGISTRYINDEX);\n  console.warn('EnumItemsInRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetItemLevel takes item whichItem returns integer\n */\nfunction GetItemLevel(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('GetItemLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetItemType takes item whichItem returns itemtype\n */\nfunction GetItemType(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('GetItemType was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SetItemDropID takes item whichItem, integer unitId returns nothing\n */\nfunction SetItemDropID(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _unitId = luaL_checkinteger(L, 2);\n  console.warn('SetItemDropID was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetItemName takes item whichItem returns string\n */\nfunction GetItemName(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('GetItemName was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native GetItemCharges takes item whichItem returns integer\n */\nfunction GetItemCharges(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('GetItemCharges was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetItemCharges takes item whichItem, integer charges returns nothing\n */\nfunction SetItemCharges(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _charges = luaL_checkinteger(L, 2);\n  console.warn('SetItemCharges was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetItemUserData takes item whichItem returns integer\n */\nfunction GetItemUserData(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('GetItemUserData was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetItemUserData takes item whichItem, integer data returns nothing\n */\nfunction SetItemUserData(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _data = luaL_checkinteger(L, 2);\n  console.warn('SetItemUserData was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateUnit takes player id, integer unitid, real x, real y, real face returns unit\n */\nfunction CreateUnit(C: Context, L: lua_State): number {\n  const id = <JassPlayer>lua_touserdata(L, 1);\n  const unitid = luaL_checkinteger(L, 2);\n  const x = luaL_checknumber(L, 3);\n  const y = luaL_checknumber(L, 4);\n  const face = luaL_checknumber(L, 5);\n\n  lua_pushlightuserdata(L, C.addHandle(new JassUnit(id, unitid, x, y, face)));\n\n  return 1;\n}\n\n/**\n * native CreateUnitByName takes player whichPlayer, string unitname, real x, real y, real face returns unit\n */\nfunction CreateUnitByName(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _unitname = luaL_checkstring(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  const _face = luaL_checknumber(L, 5);\n  console.warn('CreateUnitByName was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateUnitAtLoc takes player id, integer unitid, location whichLocation, real face returns unit\n */\nfunction CreateUnitAtLoc(C: Context, L: lua_State): number {\n  const _id = lua_touserdata(L, 1);\n  const _unitid = luaL_checkinteger(L, 2);\n  const _whichLocation = lua_touserdata(L, 3);\n  const _face = luaL_checknumber(L, 4);\n  console.warn('CreateUnitAtLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateUnitAtLocByName takes player id, string unitname, location whichLocation, real face returns unit\n */\nfunction CreateUnitAtLocByName(C: Context, L: lua_State): number {\n  const _id = lua_touserdata(L, 1);\n  const _unitname = luaL_checkstring(L, 2);\n  const _whichLocation = lua_touserdata(L, 3);\n  const _face = luaL_checknumber(L, 4);\n  console.warn('CreateUnitAtLocByName was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateCorpse takes player whichPlayer, integer unitid, real x, real y, real face returns unit\n */\nfunction CreateCorpse(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _unitid = luaL_checkinteger(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  const _face = luaL_checknumber(L, 5);\n  console.warn('CreateCorpse was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native KillUnit takes unit whichUnit returns nothing\n */\nfunction KillUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('KillUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveUnit takes unit whichUnit returns nothing\n */\nfunction RemoveUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('RemoveUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ShowUnit takes unit whichUnit, boolean show returns nothing\n */\nfunction ShowUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _show = lua_toboolean(L, 2);\n  console.warn('ShowUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitState takes unit whichUnit, unitstate whichUnitState, real newVal returns nothing\n */\nfunction SetUnitState(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichUnitState = lua_touserdata(L, 2);\n  const _newVal = luaL_checknumber(L, 3);\n  console.warn('SetUnitState was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitX takes unit whichUnit, real newX returns nothing\n */\nfunction SetUnitX(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newX = luaL_checknumber(L, 2);\n  console.warn('SetUnitX was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitY takes unit whichUnit, real newY returns nothing\n */\nfunction SetUnitY(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newY = luaL_checknumber(L, 2);\n  console.warn('SetUnitY was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitPosition takes unit whichUnit, real newX, real newY returns nothing\n */\nfunction SetUnitPosition(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newX = luaL_checknumber(L, 2);\n  const _newY = luaL_checknumber(L, 3);\n  console.warn('SetUnitPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitPositionLoc takes unit whichUnit, location whichLocation returns nothing\n */\nfunction SetUnitPositionLoc(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  console.warn('SetUnitPositionLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitFacing takes unit whichUnit, real facingAngle returns nothing\n */\nfunction SetUnitFacing(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _facingAngle = luaL_checknumber(L, 2);\n  console.warn('SetUnitFacing was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitFacingTimed takes unit whichUnit, real facingAngle, real duration returns nothing\n */\nfunction SetUnitFacingTimed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _facingAngle = luaL_checknumber(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  console.warn('SetUnitFacingTimed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitMoveSpeed takes unit whichUnit, real newSpeed returns nothing\n */\nfunction SetUnitMoveSpeed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newSpeed = luaL_checknumber(L, 2);\n  console.warn('SetUnitMoveSpeed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitFlyHeight takes unit whichUnit, real newHeight, real rate returns nothing\n */\nfunction SetUnitFlyHeight(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newHeight = luaL_checknumber(L, 2);\n  const _rate = luaL_checknumber(L, 3);\n  console.warn('SetUnitFlyHeight was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitTurnSpeed takes unit whichUnit, real newTurnSpeed returns nothing\n */\nfunction SetUnitTurnSpeed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newTurnSpeed = luaL_checknumber(L, 2);\n  console.warn('SetUnitTurnSpeed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitPropWindow takes unit whichUnit, real newPropWindowAngle returns nothing\n */\nfunction SetUnitPropWindow(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newPropWindowAngle = luaL_checknumber(L, 2);\n  console.warn('SetUnitPropWindow was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitAcquireRange takes unit whichUnit, real newAcquireRange returns nothing\n */\nfunction SetUnitAcquireRange(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _newAcquireRange = luaL_checknumber(L, 2);\n  console.warn('SetUnitAcquireRange was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitCreepGuard takes unit whichUnit, boolean creepGuard returns nothing\n */\nfunction SetUnitCreepGuard(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _creepGuard = lua_toboolean(L, 2);\n  console.warn('SetUnitCreepGuard was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetUnitAcquireRange takes unit whichUnit returns real\n */\nfunction GetUnitAcquireRange(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitAcquireRange was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitTurnSpeed takes unit whichUnit returns real\n */\nfunction GetUnitTurnSpeed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitTurnSpeed was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitPropWindow takes unit whichUnit returns real\n */\nfunction GetUnitPropWindow(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitPropWindow was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitFlyHeight takes unit whichUnit returns real\n */\nfunction GetUnitFlyHeight(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitFlyHeight was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitDefaultAcquireRange takes unit whichUnit returns real\n */\nfunction GetUnitDefaultAcquireRange(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitDefaultAcquireRange was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitDefaultTurnSpeed takes unit whichUnit returns real\n */\nfunction GetUnitDefaultTurnSpeed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitDefaultTurnSpeed was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitDefaultPropWindow takes unit whichUnit returns real\n */\nfunction GetUnitDefaultPropWindow(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitDefaultPropWindow was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitDefaultFlyHeight takes unit whichUnit returns real\n */\nfunction GetUnitDefaultFlyHeight(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitDefaultFlyHeight was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetUnitOwner takes unit whichUnit, player whichPlayer, boolean changeColor returns nothing\n */\nfunction SetUnitOwner(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _changeColor = lua_toboolean(L, 3);\n  console.warn('SetUnitOwner was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitColor takes unit whichUnit, playercolor whichColor returns nothing\n */\nfunction SetUnitColor(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichColor = lua_touserdata(L, 2);\n  console.warn('SetUnitColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitScale takes unit whichUnit, real scaleX, real scaleY, real scaleZ returns nothing\n */\nfunction SetUnitScale(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _scaleX = luaL_checknumber(L, 2);\n  const _scaleY = luaL_checknumber(L, 3);\n  const _scaleZ = luaL_checknumber(L, 4);\n  console.warn('SetUnitScale was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitTimeScale takes unit whichUnit, real timeScale returns nothing\n */\nfunction SetUnitTimeScale(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _timeScale = luaL_checknumber(L, 2);\n  console.warn('SetUnitTimeScale was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitBlendTime takes unit whichUnit, real blendTime returns nothing\n */\nfunction SetUnitBlendTime(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _blendTime = luaL_checknumber(L, 2);\n  console.warn('SetUnitBlendTime was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitVertexColor takes unit whichUnit, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction SetUnitVertexColor(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('SetUnitVertexColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QueueUnitAnimation takes unit whichUnit, string whichAnimation returns nothing\n */\nfunction QueueUnitAnimation(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichAnimation = luaL_checkstring(L, 2);\n  console.warn('QueueUnitAnimation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitAnimation takes unit whichUnit, string whichAnimation returns nothing\n */\nfunction SetUnitAnimation(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichAnimation = luaL_checkstring(L, 2);\n  console.warn('SetUnitAnimation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitAnimationByIndex takes unit whichUnit, integer whichAnimation returns nothing\n */\nfunction SetUnitAnimationByIndex(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichAnimation = luaL_checkinteger(L, 2);\n  console.warn('SetUnitAnimationByIndex was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitAnimationWithRarity takes unit whichUnit, string whichAnimation, raritycontrol rarity returns nothing\n */\nfunction SetUnitAnimationWithRarity(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichAnimation = luaL_checkstring(L, 2);\n  const _rarity = lua_touserdata(L, 3);\n  console.warn('SetUnitAnimationWithRarity was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddUnitAnimationProperties takes unit whichUnit, string animProperties, boolean add returns nothing\n */\nfunction AddUnitAnimationProperties(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _animProperties = luaL_checkstring(L, 2);\n  const _add = lua_toboolean(L, 3);\n  console.warn('AddUnitAnimationProperties was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitLookAt takes unit whichUnit, string whichBone, unit lookAtTarget, real offsetX, real offsetY, real offsetZ returns nothing\n */\nfunction SetUnitLookAt(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichBone = luaL_checkstring(L, 2);\n  const _lookAtTarget = lua_touserdata(L, 3);\n  const _offsetX = luaL_checknumber(L, 4);\n  const _offsetY = luaL_checknumber(L, 5);\n  const _offsetZ = luaL_checknumber(L, 6);\n  console.warn('SetUnitLookAt was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ResetUnitLookAt takes unit whichUnit returns nothing\n */\nfunction ResetUnitLookAt(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('ResetUnitLookAt was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitRescuable takes unit whichUnit, player byWhichPlayer, boolean flag returns nothing\n */\nfunction SetUnitRescuable(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _byWhichPlayer = lua_touserdata(L, 2);\n  const _flag = lua_toboolean(L, 3);\n  console.warn('SetUnitRescuable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitRescueRange takes unit whichUnit, real range returns nothing\n */\nfunction SetUnitRescueRange(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _range = luaL_checknumber(L, 2);\n  console.warn('SetUnitRescueRange was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetHeroStr takes unit whichHero, integer newStr, boolean permanent returns nothing\n */\nfunction SetHeroStr(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _newStr = luaL_checkinteger(L, 2);\n  const _permanent = lua_toboolean(L, 3);\n  console.warn('SetHeroStr was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetHeroAgi takes unit whichHero, integer newAgi, boolean permanent returns nothing\n */\nfunction SetHeroAgi(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _newAgi = luaL_checkinteger(L, 2);\n  const _permanent = lua_toboolean(L, 3);\n  console.warn('SetHeroAgi was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetHeroInt takes unit whichHero, integer newInt, boolean permanent returns nothing\n */\nfunction SetHeroInt(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _newInt = luaL_checkinteger(L, 2);\n  const _permanent = lua_toboolean(L, 3);\n  console.warn('SetHeroInt was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetHeroStr takes unit whichHero, boolean includeBonuses returns integer\n */\nfunction GetHeroStr(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _includeBonuses = lua_toboolean(L, 2);\n  console.warn('GetHeroStr was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetHeroAgi takes unit whichHero, boolean includeBonuses returns integer\n */\nfunction GetHeroAgi(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _includeBonuses = lua_toboolean(L, 2);\n  console.warn('GetHeroAgi was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetHeroInt takes unit whichHero, boolean includeBonuses returns integer\n */\nfunction GetHeroInt(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _includeBonuses = lua_toboolean(L, 2);\n  console.warn('GetHeroInt was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native UnitStripHeroLevel takes unit whichHero, integer howManyLevels returns boolean\n */\nfunction UnitStripHeroLevel(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _howManyLevels = luaL_checkinteger(L, 2);\n  console.warn('UnitStripHeroLevel was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetHeroXP takes unit whichHero returns integer\n */\nfunction GetHeroXP(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  console.warn('GetHeroXP was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetHeroXP takes unit whichHero, integer newXpVal, boolean showEyeCandy returns nothing\n */\nfunction SetHeroXP(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _newXpVal = luaL_checkinteger(L, 2);\n  const _showEyeCandy = lua_toboolean(L, 3);\n  console.warn('SetHeroXP was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetHeroSkillPoints takes unit whichHero returns integer\n */\nfunction GetHeroSkillPoints(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  console.warn('GetHeroSkillPoints was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native UnitModifySkillPoints takes unit whichHero, integer skillPointDelta returns boolean\n */\nfunction UnitModifySkillPoints(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _skillPointDelta = luaL_checkinteger(L, 2);\n  console.warn('UnitModifySkillPoints was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native AddHeroXP takes unit whichHero, integer xpToAdd, boolean showEyeCandy returns nothing\n */\nfunction AddHeroXP(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _xpToAdd = luaL_checkinteger(L, 2);\n  const _showEyeCandy = lua_toboolean(L, 3);\n  console.warn('AddHeroXP was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetHeroLevel takes unit whichHero, integer level, boolean showEyeCandy returns nothing\n */\nfunction SetHeroLevel(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  const _showEyeCandy = lua_toboolean(L, 3);\n  console.warn('SetHeroLevel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetHeroLevel takes unit whichHero returns integer\n */\nfunction GetHeroLevel(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  console.warn('GetHeroLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitLevel takes unit whichUnit returns integer\n */\nfunction GetUnitLevel(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetHeroProperName takes unit whichHero returns string\n */\nfunction GetHeroProperName(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  console.warn('GetHeroProperName was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native SuspendHeroXP takes unit whichHero, boolean flag returns nothing\n */\nfunction SuspendHeroXP(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SuspendHeroXP was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsSuspendedXP takes unit whichHero returns boolean\n */\nfunction IsSuspendedXP(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  console.warn('IsSuspendedXP was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SelectHeroSkill takes unit whichHero, integer abilcode returns nothing\n */\nfunction SelectHeroSkill(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _abilcode = luaL_checkinteger(L, 2);\n  console.warn('SelectHeroSkill was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetUnitAbilityLevel takes unit whichUnit, integer abilcode returns integer\n */\nfunction GetUnitAbilityLevel(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilcode = luaL_checkinteger(L, 2);\n  console.warn('GetUnitAbilityLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native DecUnitAbilityLevel takes unit whichUnit, integer abilcode returns integer\n */\nfunction DecUnitAbilityLevel(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilcode = luaL_checkinteger(L, 2);\n  console.warn('DecUnitAbilityLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native IncUnitAbilityLevel takes unit whichUnit, integer abilcode returns integer\n */\nfunction IncUnitAbilityLevel(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilcode = luaL_checkinteger(L, 2);\n  console.warn('IncUnitAbilityLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetUnitAbilityLevel takes unit whichUnit, integer abilcode, integer level returns integer\n */\nfunction SetUnitAbilityLevel(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilcode = luaL_checkinteger(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('SetUnitAbilityLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native ReviveHero takes unit whichHero, real x, real y, boolean doEyecandy returns boolean\n */\nfunction ReviveHero(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _doEyecandy = lua_toboolean(L, 4);\n  console.warn('ReviveHero was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native ReviveHeroLoc takes unit whichHero, location loc, boolean doEyecandy returns boolean\n */\nfunction ReviveHeroLoc(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  const _loc = lua_touserdata(L, 2);\n  const _doEyecandy = lua_toboolean(L, 3);\n  console.warn('ReviveHeroLoc was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetUnitExploded takes unit whichUnit, boolean exploded returns nothing\n */\nfunction SetUnitExploded(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _exploded = lua_toboolean(L, 2);\n  console.warn('SetUnitExploded was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitInvulnerable takes unit whichUnit, boolean flag returns nothing\n */\nfunction SetUnitInvulnerable(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetUnitInvulnerable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PauseUnit takes unit whichUnit, boolean flag returns nothing\n */\nfunction PauseUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('PauseUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsUnitPaused takes unit whichHero returns boolean\n */\nfunction IsUnitPaused(C: Context, L: lua_State): number {\n  const _whichHero = lua_touserdata(L, 1);\n  console.warn('IsUnitPaused was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetUnitPathing takes unit whichUnit, boolean flag returns nothing\n */\nfunction SetUnitPathing(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetUnitPathing was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ClearSelection takes nothing returns nothing\n */\nfunction ClearSelection(_C: Context, _L: lua_State): number {\n\n  console.warn('ClearSelection was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SelectUnit takes unit whichUnit, boolean flag returns nothing\n */\nfunction SelectUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SelectUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetUnitPointValue takes unit whichUnit returns integer\n */\nfunction GetUnitPointValue(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitPointValue was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetUnitPointValueByType takes integer unitType returns integer\n */\nfunction GetUnitPointValueByType(C: Context, L: lua_State): number {\n  const _unitType = luaL_checkinteger(L, 1);\n  console.warn('GetUnitPointValueByType was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native UnitAddItem takes unit whichUnit, item whichItem returns boolean\n */\nfunction UnitAddItem(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  console.warn('UnitAddItem was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitAddItemById takes unit whichUnit, integer itemId returns item\n */\nfunction UnitAddItemById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _itemId = luaL_checkinteger(L, 2);\n  console.warn('UnitAddItemById was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native UnitAddItemToSlotById takes unit whichUnit, integer itemId, integer itemSlot returns boolean\n */\nfunction UnitAddItemToSlotById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _itemId = luaL_checkinteger(L, 2);\n  const _itemSlot = luaL_checkinteger(L, 3);\n  console.warn('UnitAddItemToSlotById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitRemoveItem takes unit whichUnit, item whichItem returns nothing\n */\nfunction UnitRemoveItem(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  console.warn('UnitRemoveItem was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitRemoveItemFromSlot takes unit whichUnit, integer itemSlot returns item\n */\nfunction UnitRemoveItemFromSlot(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _itemSlot = luaL_checkinteger(L, 2);\n  console.warn('UnitRemoveItemFromSlot was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native UnitHasItem takes unit whichUnit, item whichItem returns boolean\n */\nfunction UnitHasItem(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  console.warn('UnitHasItem was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitItemInSlot takes unit whichUnit, integer itemSlot returns item\n */\nfunction UnitItemInSlot(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _itemSlot = luaL_checkinteger(L, 2);\n  console.warn('UnitItemInSlot was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native UnitInventorySize takes unit whichUnit returns integer\n */\nfunction UnitInventorySize(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitInventorySize was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native UnitDropItemPoint takes unit whichUnit, item whichItem, real x, real y returns boolean\n */\nfunction UnitDropItemPoint(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('UnitDropItemPoint was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitDropItemSlot takes unit whichUnit, item whichItem, integer slot returns boolean\n */\nfunction UnitDropItemSlot(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  const _slot = luaL_checkinteger(L, 3);\n  console.warn('UnitDropItemSlot was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitDropItemTarget takes unit whichUnit, item whichItem, widget target returns boolean\n */\nfunction UnitDropItemTarget(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  const _target = lua_touserdata(L, 3);\n  console.warn('UnitDropItemTarget was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitUseItem takes unit whichUnit, item whichItem returns boolean\n */\nfunction UnitUseItem(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  console.warn('UnitUseItem was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitUseItemPoint takes unit whichUnit, item whichItem, real x, real y returns boolean\n */\nfunction UnitUseItemPoint(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('UnitUseItemPoint was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitUseItemTarget takes unit whichUnit, item whichItem, widget target returns boolean\n */\nfunction UnitUseItemTarget(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichItem = lua_touserdata(L, 2);\n  const _target = lua_touserdata(L, 3);\n  console.warn('UnitUseItemTarget was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native GetUnitX takes unit whichUnit returns real\n */\nfunction GetUnitX(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitY takes unit whichUnit returns real\n */\nfunction GetUnitY(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitLoc takes unit whichUnit returns location\n */\nfunction GetUnitLoc(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetUnitFacing takes unit whichUnit returns real\n */\nfunction GetUnitFacing(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitFacing was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitMoveSpeed takes unit whichUnit returns real\n */\nfunction GetUnitMoveSpeed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitMoveSpeed was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitDefaultMoveSpeed takes unit whichUnit returns real\n */\nfunction GetUnitDefaultMoveSpeed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitDefaultMoveSpeed was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitState takes unit whichUnit, unitstate whichUnitState returns real\n */\nfunction GetUnitState(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichUnitState = lua_touserdata(L, 2);\n  console.warn('GetUnitState was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetOwningPlayer takes unit whichUnit returns player\n */\nfunction GetOwningPlayer(C: Context, L: lua_State): number {\n  const whichUnit = <JassUnit>lua_touserdata(L, 1);\n\n  lua_pushlightuserdata(L, whichUnit.player);\n\n  return 1;\n}\n\n/**\n * constant native GetUnitTypeId takes unit whichUnit returns integer\n */\nfunction GetUnitTypeId(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitTypeId was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitRace takes unit whichUnit returns race\n */\nfunction GetUnitRace(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitRace was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetUnitName takes unit whichUnit returns string\n */\nfunction GetUnitName(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitName was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * constant native GetUnitFoodUsed takes unit whichUnit returns integer\n */\nfunction GetUnitFoodUsed(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitFoodUsed was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetUnitFoodMade takes unit whichUnit returns integer\n */\nfunction GetUnitFoodMade(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitFoodMade was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetFoodMade takes integer unitId returns integer\n */\nfunction GetFoodMade(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  console.warn('GetFoodMade was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetFoodUsed takes integer unitId returns integer\n */\nfunction GetFoodUsed(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  console.warn('GetFoodUsed was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetUnitUseFood takes unit whichUnit, boolean useFood returns nothing\n */\nfunction SetUnitUseFood(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _useFood = lua_toboolean(L, 2);\n  console.warn('SetUnitUseFood was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetUnitRallyPoint takes unit whichUnit returns location\n */\nfunction GetUnitRallyPoint(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitRallyPoint was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetUnitRallyUnit takes unit whichUnit returns unit\n */\nfunction GetUnitRallyUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitRallyUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetUnitRallyDestructable takes unit whichUnit returns destructable\n */\nfunction GetUnitRallyDestructable(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitRallyDestructable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native IsUnitInGroup takes unit whichUnit, group whichGroup returns boolean\n */\nfunction IsUnitInGroup(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichGroup = lua_touserdata(L, 2);\n  console.warn('IsUnitInGroup was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitInForce takes unit whichUnit, force whichForce returns boolean\n */\nfunction IsUnitInForce(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichForce = lua_touserdata(L, 2);\n  console.warn('IsUnitInForce was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitOwnedByPlayer takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitOwnedByPlayer(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitOwnedByPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitAlly takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitAlly(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitAlly was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitEnemy takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitEnemy(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitEnemy was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitVisible takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitVisible(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitVisible was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitDetected takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitDetected(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitDetected was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitInvisible takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitInvisible(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitInvisible was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitFogged takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitFogged(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitFogged was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitMasked takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitMasked(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitMasked was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitSelected takes unit whichUnit, player whichPlayer returns boolean\n */\nfunction IsUnitSelected(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsUnitSelected was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitRace takes unit whichUnit, race whichRace returns boolean\n */\nfunction IsUnitRace(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichRace = lua_touserdata(L, 2);\n  console.warn('IsUnitRace was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitType takes unit whichUnit, unittype whichUnitType returns boolean\n */\nfunction IsUnitType(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichUnitType = lua_touserdata(L, 2);\n  console.warn('IsUnitType was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnit takes unit whichUnit, unit whichSpecifiedUnit returns boolean\n */\nfunction IsUnit(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichSpecifiedUnit = lua_touserdata(L, 2);\n  console.warn('IsUnit was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitInRange takes unit whichUnit, unit otherUnit, real distance returns boolean\n */\nfunction IsUnitInRange(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _otherUnit = lua_touserdata(L, 2);\n  const _distance = luaL_checknumber(L, 3);\n  console.warn('IsUnitInRange was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitInRangeXY takes unit whichUnit, real x, real y, real distance returns boolean\n */\nfunction IsUnitInRangeXY(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _distance = luaL_checknumber(L, 4);\n  console.warn('IsUnitInRangeXY was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitInRangeLoc takes unit whichUnit, location whichLocation, real distance returns boolean\n */\nfunction IsUnitInRangeLoc(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  const _distance = luaL_checknumber(L, 3);\n  console.warn('IsUnitInRangeLoc was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitHidden takes unit whichUnit returns boolean\n */\nfunction IsUnitHidden(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('IsUnitHidden was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitIllusion takes unit whichUnit returns boolean\n */\nfunction IsUnitIllusion(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('IsUnitIllusion was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitInTransport takes unit whichUnit, unit whichTransport returns boolean\n */\nfunction IsUnitInTransport(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichTransport = lua_touserdata(L, 2);\n  console.warn('IsUnitInTransport was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitLoaded takes unit whichUnit returns boolean\n */\nfunction IsUnitLoaded(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('IsUnitLoaded was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsHeroUnitId takes integer unitId returns boolean\n */\nfunction IsHeroUnitId(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  console.warn('IsHeroUnitId was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsUnitIdType takes integer unitId, unittype whichUnitType returns boolean\n */\nfunction IsUnitIdType(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  const _whichUnitType = lua_touserdata(L, 2);\n  console.warn('IsUnitIdType was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitShareVision takes unit whichUnit, player whichPlayer, boolean share returns nothing\n */\nfunction UnitShareVision(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  const _share = lua_toboolean(L, 3);\n  console.warn('UnitShareVision was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitSuspendDecay takes unit whichUnit, boolean suspend returns nothing\n */\nfunction UnitSuspendDecay(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _suspend = lua_toboolean(L, 2);\n  console.warn('UnitSuspendDecay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitAddType takes unit whichUnit, unittype whichUnitType returns boolean\n */\nfunction UnitAddType(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichUnitType = lua_touserdata(L, 2);\n  console.warn('UnitAddType was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitRemoveType takes unit whichUnit, unittype whichUnitType returns boolean\n */\nfunction UnitRemoveType(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _whichUnitType = lua_touserdata(L, 2);\n  console.warn('UnitRemoveType was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitAddAbility takes unit whichUnit, integer abilityId returns boolean\n */\nfunction UnitAddAbility(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilityId = luaL_checkinteger(L, 2);\n  console.warn('UnitAddAbility was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitRemoveAbility takes unit whichUnit, integer abilityId returns boolean\n */\nfunction UnitRemoveAbility(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilityId = luaL_checkinteger(L, 2);\n  console.warn('UnitRemoveAbility was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitMakeAbilityPermanent takes unit whichUnit, boolean permanent, integer abilityId returns boolean\n */\nfunction UnitMakeAbilityPermanent(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _permanent = lua_toboolean(L, 2);\n  const _abilityId = luaL_checkinteger(L, 3);\n  console.warn('UnitMakeAbilityPermanent was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitRemoveBuffs takes unit whichUnit, boolean removePositive, boolean removeNegative returns nothing\n */\nfunction UnitRemoveBuffs(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _removePositive = lua_toboolean(L, 2);\n  const _removeNegative = lua_toboolean(L, 3);\n  console.warn('UnitRemoveBuffs was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitRemoveBuffsEx takes unit whichUnit, boolean removePositive, boolean removeNegative, boolean magic, boolean physical, boolean timedLife, boolean aura, boolean autoDispel returns nothing\n */\nfunction UnitRemoveBuffsEx(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _removePositive = lua_toboolean(L, 2);\n  const _removeNegative = lua_toboolean(L, 3);\n  const _magic = lua_toboolean(L, 4);\n  const _physical = lua_toboolean(L, 5);\n  const _timedLife = lua_toboolean(L, 6);\n  const _aura = lua_toboolean(L, 7);\n  const _autoDispel = lua_toboolean(L, 8);\n  console.warn('UnitRemoveBuffsEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitHasBuffsEx takes unit whichUnit, boolean removePositive, boolean removeNegative, boolean magic, boolean physical, boolean timedLife, boolean aura, boolean autoDispel returns boolean\n */\nfunction UnitHasBuffsEx(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _removePositive = lua_toboolean(L, 2);\n  const _removeNegative = lua_toboolean(L, 3);\n  const _magic = lua_toboolean(L, 4);\n  const _physical = lua_toboolean(L, 5);\n  const _timedLife = lua_toboolean(L, 6);\n  const _aura = lua_toboolean(L, 7);\n  const _autoDispel = lua_toboolean(L, 8);\n  console.warn('UnitHasBuffsEx was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitCountBuffsEx takes unit whichUnit, boolean removePositive, boolean removeNegative, boolean magic, boolean physical, boolean timedLife, boolean aura, boolean autoDispel returns integer\n */\nfunction UnitCountBuffsEx(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _removePositive = lua_toboolean(L, 2);\n  const _removeNegative = lua_toboolean(L, 3);\n  const _magic = lua_toboolean(L, 4);\n  const _physical = lua_toboolean(L, 5);\n  const _timedLife = lua_toboolean(L, 6);\n  const _aura = lua_toboolean(L, 7);\n  const _autoDispel = lua_toboolean(L, 8);\n  console.warn('UnitCountBuffsEx was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native UnitAddSleep takes unit whichUnit, boolean add returns nothing\n */\nfunction UnitAddSleep(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _add = lua_toboolean(L, 2);\n  console.warn('UnitAddSleep was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitCanSleep takes unit whichUnit returns boolean\n */\nfunction UnitCanSleep(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitCanSleep was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitAddSleepPerm takes unit whichUnit, boolean add returns nothing\n */\nfunction UnitAddSleepPerm(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _add = lua_toboolean(L, 2);\n  console.warn('UnitAddSleepPerm was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitCanSleepPerm takes unit whichUnit returns boolean\n */\nfunction UnitCanSleepPerm(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitCanSleepPerm was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitIsSleeping takes unit whichUnit returns boolean\n */\nfunction UnitIsSleeping(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitIsSleeping was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitWakeUp takes unit whichUnit returns nothing\n */\nfunction UnitWakeUp(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitWakeUp was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitApplyTimedLife takes unit whichUnit, integer buffId, real duration returns nothing\n */\nfunction UnitApplyTimedLife(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _buffId = luaL_checkinteger(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  console.warn('UnitApplyTimedLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitIgnoreAlarm takes unit whichUnit, boolean flag returns boolean\n */\nfunction UnitIgnoreAlarm(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('UnitIgnoreAlarm was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitIgnoreAlarmToggled takes unit whichUnit returns boolean\n */\nfunction UnitIgnoreAlarmToggled(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitIgnoreAlarmToggled was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitResetCooldown takes unit whichUnit returns nothing\n */\nfunction UnitResetCooldown(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('UnitResetCooldown was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitSetConstructionProgress takes unit whichUnit, integer constructionPercentage returns nothing\n */\nfunction UnitSetConstructionProgress(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _constructionPercentage = luaL_checkinteger(L, 2);\n  console.warn('UnitSetConstructionProgress was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitSetUpgradeProgress takes unit whichUnit, integer upgradePercentage returns nothing\n */\nfunction UnitSetUpgradeProgress(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _upgradePercentage = luaL_checkinteger(L, 2);\n  console.warn('UnitSetUpgradeProgress was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitPauseTimedLife takes unit whichUnit, boolean flag returns nothing\n */\nfunction UnitPauseTimedLife(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('UnitPauseTimedLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitSetUsesAltIcon takes unit whichUnit, boolean flag returns nothing\n */\nfunction UnitSetUsesAltIcon(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('UnitSetUsesAltIcon was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitDamagePoint takes unit whichUnit, real delay, real radius, real x, real y, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns boolean\n */\nfunction UnitDamagePoint(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _delay = luaL_checknumber(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _x = luaL_checknumber(L, 4);\n  const _y = luaL_checknumber(L, 5);\n  const _amount = luaL_checknumber(L, 6);\n  const _attack = lua_toboolean(L, 7);\n  const _ranged = lua_toboolean(L, 8);\n  const _attackType = lua_touserdata(L, 9);\n  const _damageType = lua_touserdata(L, 10);\n  const _weaponType = lua_touserdata(L, 11);\n  console.warn('UnitDamagePoint was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native UnitDamageTarget takes unit whichUnit, widget target, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns boolean\n */\nfunction UnitDamageTarget(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _target = lua_touserdata(L, 2);\n  const _amount = luaL_checknumber(L, 3);\n  const _attack = lua_toboolean(L, 4);\n  const _ranged = lua_toboolean(L, 5);\n  const _attackType = lua_touserdata(L, 6);\n  const _damageType = lua_touserdata(L, 7);\n  const _weaponType = lua_touserdata(L, 8);\n  console.warn('UnitDamageTarget was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueImmediateOrder takes unit whichUnit, string order returns boolean\n */\nfunction IssueImmediateOrder(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  console.warn('IssueImmediateOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueImmediateOrderById takes unit whichUnit, integer order returns boolean\n */\nfunction IssueImmediateOrderById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  console.warn('IssueImmediateOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssuePointOrder takes unit whichUnit, string order, real x, real y returns boolean\n */\nfunction IssuePointOrder(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('IssuePointOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssuePointOrderLoc takes unit whichUnit, string order, location whichLocation returns boolean\n */\nfunction IssuePointOrderLoc(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _whichLocation = lua_touserdata(L, 3);\n  console.warn('IssuePointOrderLoc was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssuePointOrderById takes unit whichUnit, integer order, real x, real y returns boolean\n */\nfunction IssuePointOrderById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('IssuePointOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssuePointOrderByIdLoc takes unit whichUnit, integer order, location whichLocation returns boolean\n */\nfunction IssuePointOrderByIdLoc(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _whichLocation = lua_touserdata(L, 3);\n  console.warn('IssuePointOrderByIdLoc was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueTargetOrder takes unit whichUnit, string order, widget targetWidget returns boolean\n */\nfunction IssueTargetOrder(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  console.warn('IssueTargetOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueTargetOrderById takes unit whichUnit, integer order, widget targetWidget returns boolean\n */\nfunction IssueTargetOrderById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  console.warn('IssueTargetOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueInstantPointOrder takes unit whichUnit, string order, real x, real y, widget instantTargetWidget returns boolean\n */\nfunction IssueInstantPointOrder(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  const _instantTargetWidget = lua_touserdata(L, 5);\n  console.warn('IssueInstantPointOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueInstantPointOrderById takes unit whichUnit, integer order, real x, real y, widget instantTargetWidget returns boolean\n */\nfunction IssueInstantPointOrderById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  const _instantTargetWidget = lua_touserdata(L, 5);\n  console.warn('IssueInstantPointOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueInstantTargetOrder takes unit whichUnit, string order, widget targetWidget, widget instantTargetWidget returns boolean\n */\nfunction IssueInstantTargetOrder(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkstring(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  const _instantTargetWidget = lua_touserdata(L, 4);\n  console.warn('IssueInstantTargetOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueInstantTargetOrderById takes unit whichUnit, integer order, widget targetWidget, widget instantTargetWidget returns boolean\n */\nfunction IssueInstantTargetOrderById(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _order = luaL_checkinteger(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  const _instantTargetWidget = lua_touserdata(L, 4);\n  console.warn('IssueInstantTargetOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueBuildOrder takes unit whichPeon, string unitToBuild, real x, real y returns boolean\n */\nfunction IssueBuildOrder(C: Context, L: lua_State): number {\n  const _whichPeon = lua_touserdata(L, 1);\n  const _unitToBuild = luaL_checkstring(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('IssueBuildOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueBuildOrderById takes unit whichPeon, integer unitId, real x, real y returns boolean\n */\nfunction IssueBuildOrderById(C: Context, L: lua_State): number {\n  const _whichPeon = lua_touserdata(L, 1);\n  const _unitId = luaL_checkinteger(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('IssueBuildOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueNeutralImmediateOrder takes player forWhichPlayer, unit neutralStructure, string unitToBuild returns boolean\n */\nfunction IssueNeutralImmediateOrder(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _neutralStructure = lua_touserdata(L, 2);\n  const _unitToBuild = luaL_checkstring(L, 3);\n  console.warn('IssueNeutralImmediateOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueNeutralImmediateOrderById takes player forWhichPlayer, unit neutralStructure, integer unitId returns boolean\n */\nfunction IssueNeutralImmediateOrderById(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _neutralStructure = lua_touserdata(L, 2);\n  const _unitId = luaL_checkinteger(L, 3);\n  console.warn('IssueNeutralImmediateOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueNeutralPointOrder takes player forWhichPlayer, unit neutralStructure, string unitToBuild, real x, real y returns boolean\n */\nfunction IssueNeutralPointOrder(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _neutralStructure = lua_touserdata(L, 2);\n  const _unitToBuild = luaL_checkstring(L, 3);\n  const _x = luaL_checknumber(L, 4);\n  const _y = luaL_checknumber(L, 5);\n  console.warn('IssueNeutralPointOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueNeutralPointOrderById takes player forWhichPlayer, unit neutralStructure, integer unitId, real x, real y returns boolean\n */\nfunction IssueNeutralPointOrderById(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _neutralStructure = lua_touserdata(L, 2);\n  const _unitId = luaL_checkinteger(L, 3);\n  const _x = luaL_checknumber(L, 4);\n  const _y = luaL_checknumber(L, 5);\n  console.warn('IssueNeutralPointOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueNeutralTargetOrder takes player forWhichPlayer, unit neutralStructure, string unitToBuild, widget target returns boolean\n */\nfunction IssueNeutralTargetOrder(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _neutralStructure = lua_touserdata(L, 2);\n  const _unitToBuild = luaL_checkstring(L, 3);\n  const _target = lua_touserdata(L, 4);\n  console.warn('IssueNeutralTargetOrder was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IssueNeutralTargetOrderById takes player forWhichPlayer, unit neutralStructure, integer unitId, widget target returns boolean\n */\nfunction IssueNeutralTargetOrderById(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _neutralStructure = lua_touserdata(L, 2);\n  const _unitId = luaL_checkinteger(L, 3);\n  const _target = lua_touserdata(L, 4);\n  console.warn('IssueNeutralTargetOrderById was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetUnitCurrentOrder takes unit whichUnit returns integer\n */\nfunction GetUnitCurrentOrder(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitCurrentOrder was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetResourceAmount takes unit whichUnit, integer amount returns nothing\n */\nfunction SetResourceAmount(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _amount = luaL_checkinteger(L, 2);\n  console.warn('SetResourceAmount was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddResourceAmount takes unit whichUnit, integer amount returns nothing\n */\nfunction AddResourceAmount(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _amount = luaL_checkinteger(L, 2);\n  console.warn('AddResourceAmount was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetResourceAmount takes unit whichUnit returns integer\n */\nfunction GetResourceAmount(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetResourceAmount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native WaygateGetDestinationX takes unit waygate returns real\n */\nfunction WaygateGetDestinationX(C: Context, L: lua_State): number {\n  const _waygate = lua_touserdata(L, 1);\n  console.warn('WaygateGetDestinationX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native WaygateGetDestinationY takes unit waygate returns real\n */\nfunction WaygateGetDestinationY(C: Context, L: lua_State): number {\n  const _waygate = lua_touserdata(L, 1);\n  console.warn('WaygateGetDestinationY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native WaygateSetDestination takes unit waygate, real x, real y returns nothing\n */\nfunction WaygateSetDestination(C: Context, L: lua_State): number {\n  const _waygate = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('WaygateSetDestination was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native WaygateActivate takes unit waygate, boolean activate returns nothing\n */\nfunction WaygateActivate(C: Context, L: lua_State): number {\n  const _waygate = lua_touserdata(L, 1);\n  const _activate = lua_toboolean(L, 2);\n  console.warn('WaygateActivate was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native WaygateIsActive takes unit waygate returns boolean\n */\nfunction WaygateIsActive(C: Context, L: lua_State): number {\n  const _waygate = lua_touserdata(L, 1);\n  console.warn('WaygateIsActive was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native AddItemToAllStock takes integer itemId, integer currentStock, integer stockMax returns nothing\n */\nfunction AddItemToAllStock(C: Context, L: lua_State): number {\n  const _itemId = luaL_checkinteger(L, 1);\n  const _currentStock = luaL_checkinteger(L, 2);\n  const _stockMax = luaL_checkinteger(L, 3);\n  console.warn('AddItemToAllStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddItemToStock takes unit whichUnit, integer itemId, integer currentStock, integer stockMax returns nothing\n */\nfunction AddItemToStock(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _itemId = luaL_checkinteger(L, 2);\n  const _currentStock = luaL_checkinteger(L, 3);\n  const _stockMax = luaL_checkinteger(L, 4);\n  console.warn('AddItemToStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddUnitToAllStock takes integer unitId, integer currentStock, integer stockMax returns nothing\n */\nfunction AddUnitToAllStock(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  const _currentStock = luaL_checkinteger(L, 2);\n  const _stockMax = luaL_checkinteger(L, 3);\n  console.warn('AddUnitToAllStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddUnitToStock takes unit whichUnit, integer unitId, integer currentStock, integer stockMax returns nothing\n */\nfunction AddUnitToStock(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _unitId = luaL_checkinteger(L, 2);\n  const _currentStock = luaL_checkinteger(L, 3);\n  const _stockMax = luaL_checkinteger(L, 4);\n  console.warn('AddUnitToStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveItemFromAllStock takes integer itemId returns nothing\n */\nfunction RemoveItemFromAllStock(C: Context, L: lua_State): number {\n  const _itemId = luaL_checkinteger(L, 1);\n  console.warn('RemoveItemFromAllStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveItemFromStock takes unit whichUnit, integer itemId returns nothing\n */\nfunction RemoveItemFromStock(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _itemId = luaL_checkinteger(L, 2);\n  console.warn('RemoveItemFromStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveUnitFromAllStock takes integer unitId returns nothing\n */\nfunction RemoveUnitFromAllStock(C: Context, L: lua_State): number {\n  const _unitId = luaL_checkinteger(L, 1);\n  console.warn('RemoveUnitFromAllStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveUnitFromStock takes unit whichUnit, integer unitId returns nothing\n */\nfunction RemoveUnitFromStock(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _unitId = luaL_checkinteger(L, 2);\n  console.warn('RemoveUnitFromStock was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetAllItemTypeSlots takes integer slots returns nothing\n */\nfunction SetAllItemTypeSlots(C: Context, L: lua_State): number {\n  const _slots = luaL_checkinteger(L, 1);\n  console.warn('SetAllItemTypeSlots was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetAllUnitTypeSlots takes integer slots returns nothing\n */\nfunction SetAllUnitTypeSlots(C: Context, L: lua_State): number {\n  const _slots = luaL_checkinteger(L, 1);\n  console.warn('SetAllUnitTypeSlots was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetItemTypeSlots takes unit whichUnit, integer slots returns nothing\n */\nfunction SetItemTypeSlots(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _slots = luaL_checkinteger(L, 2);\n  console.warn('SetItemTypeSlots was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitTypeSlots takes unit whichUnit, integer slots returns nothing\n */\nfunction SetUnitTypeSlots(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _slots = luaL_checkinteger(L, 2);\n  console.warn('SetUnitTypeSlots was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetUnitUserData takes unit whichUnit returns integer\n */\nfunction GetUnitUserData(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('GetUnitUserData was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetUnitUserData takes unit whichUnit, integer data returns nothing\n */\nfunction SetUnitUserData(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _data = luaL_checkinteger(L, 2);\n  console.warn('SetUnitUserData was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native Player takes integer number returns player\n */\nfunction Player(C: Context, L: lua_State): number {\n  const number = luaL_checkinteger(L, 1);\n\n  lua_pushlightuserdata(L, C.players[number]);\n\n  return 1;\n}\n\n/**\n * constant native GetLocalPlayer takes nothing returns player\n */\nfunction GetLocalPlayer(C: Context, L: lua_State): number {\n\n  console.warn('GetLocalPlayer was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native IsPlayerAlly takes player whichPlayer, player otherPlayer returns boolean\n */\nfunction IsPlayerAlly(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _otherPlayer = lua_touserdata(L, 2);\n  console.warn('IsPlayerAlly was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsPlayerEnemy takes player whichPlayer, player otherPlayer returns boolean\n */\nfunction IsPlayerEnemy(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _otherPlayer = lua_touserdata(L, 2);\n  console.warn('IsPlayerEnemy was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsPlayerInForce takes player whichPlayer, force whichForce returns boolean\n */\nfunction IsPlayerInForce(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichForce = lua_touserdata(L, 2);\n  console.warn('IsPlayerInForce was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsPlayerObserver takes player whichPlayer returns boolean\n */\nfunction IsPlayerObserver(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('IsPlayerObserver was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsVisibleToPlayer takes real x, real y, player whichPlayer returns boolean\n */\nfunction IsVisibleToPlayer(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _whichPlayer = lua_touserdata(L, 3);\n  console.warn('IsVisibleToPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsLocationVisibleToPlayer takes location whichLocation, player whichPlayer returns boolean\n */\nfunction IsLocationVisibleToPlayer(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsLocationVisibleToPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsFoggedToPlayer takes real x, real y, player whichPlayer returns boolean\n */\nfunction IsFoggedToPlayer(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _whichPlayer = lua_touserdata(L, 3);\n  console.warn('IsFoggedToPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsLocationFoggedToPlayer takes location whichLocation, player whichPlayer returns boolean\n */\nfunction IsLocationFoggedToPlayer(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsLocationFoggedToPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsMaskedToPlayer takes real x, real y, player whichPlayer returns boolean\n */\nfunction IsMaskedToPlayer(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _whichPlayer = lua_touserdata(L, 3);\n  console.warn('IsMaskedToPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native IsLocationMaskedToPlayer takes location whichLocation, player whichPlayer returns boolean\n */\nfunction IsLocationMaskedToPlayer(C: Context, L: lua_State): number {\n  const _whichLocation = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('IsLocationMaskedToPlayer was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native GetPlayerRace takes player whichPlayer returns race\n */\nfunction GetPlayerRace(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n\n  lua_pushlightuserdata(L, C.constantHandles.races[whichPlayer.racePreference]);\n\n  return 1;\n}\n\n/**\n * constant native GetPlayerId takes player whichPlayer returns integer\n */\nfunction GetPlayerId(C: Context, L: lua_State): number {\n  const whichPlayer = <JassPlayer>lua_touserdata(L, 1);\n\n  lua_pushinteger(L, whichPlayer.index);\n\n  return 1;\n}\n\n/**\n * constant native GetPlayerUnitCount takes player whichPlayer, boolean includeIncomplete returns integer\n */\nfunction GetPlayerUnitCount(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _includeIncomplete = lua_toboolean(L, 2);\n  console.warn('GetPlayerUnitCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetPlayerTypedUnitCount takes player whichPlayer, string unitName, boolean includeIncomplete, boolean includeUpgrades returns integer\n */\nfunction GetPlayerTypedUnitCount(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _unitName = luaL_checkstring(L, 2);\n  const _includeIncomplete = lua_toboolean(L, 3);\n  const _includeUpgrades = lua_toboolean(L, 4);\n  console.warn('GetPlayerTypedUnitCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetPlayerStructureCount takes player whichPlayer, boolean includeIncomplete returns integer\n */\nfunction GetPlayerStructureCount(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _includeIncomplete = lua_toboolean(L, 2);\n  console.warn('GetPlayerStructureCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetPlayerState takes player whichPlayer, playerstate whichPlayerState returns integer\n */\nfunction GetPlayerState(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichPlayerState = lua_touserdata(L, 2);\n  console.warn('GetPlayerState was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetPlayerScore takes player whichPlayer, playerscore whichPlayerScore returns integer\n */\nfunction GetPlayerScore(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichPlayerScore = lua_touserdata(L, 2);\n  console.warn('GetPlayerScore was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetPlayerAlliance takes player sourcePlayer, player otherPlayer, alliancetype whichAllianceSetting returns boolean\n */\nfunction GetPlayerAlliance(C: Context, L: lua_State): number {\n  const _sourcePlayer = lua_touserdata(L, 1);\n  const _otherPlayer = lua_touserdata(L, 2);\n  const _whichAllianceSetting = lua_touserdata(L, 3);\n  console.warn('GetPlayerAlliance was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native GetPlayerHandicap takes player whichPlayer returns real\n */\nfunction GetPlayerHandicap(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('GetPlayerHandicap was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetPlayerHandicapXP takes player whichPlayer returns real\n */\nfunction GetPlayerHandicapXP(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('GetPlayerHandicapXP was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native SetPlayerHandicap takes player whichPlayer, real handicap returns nothing\n */\nfunction SetPlayerHandicap(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _handicap = luaL_checknumber(L, 2);\n  console.warn('SetPlayerHandicap was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native SetPlayerHandicapXP takes player whichPlayer, real handicap returns nothing\n */\nfunction SetPlayerHandicapXP(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _handicap = luaL_checknumber(L, 2);\n  console.warn('SetPlayerHandicapXP was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native SetPlayerTechMaxAllowed takes player whichPlayer, integer techid, integer maximum returns nothing\n */\nfunction SetPlayerTechMaxAllowed(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  const _maximum = luaL_checkinteger(L, 3);\n  console.warn('SetPlayerTechMaxAllowed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetPlayerTechMaxAllowed takes player whichPlayer, integer techid returns integer\n */\nfunction GetPlayerTechMaxAllowed(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  console.warn('GetPlayerTechMaxAllowed was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * constant native AddPlayerTechResearched takes player whichPlayer, integer techid, integer levels returns nothing\n */\nfunction AddPlayerTechResearched(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  const _levels = luaL_checkinteger(L, 3);\n  console.warn('AddPlayerTechResearched was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native SetPlayerTechResearched takes player whichPlayer, integer techid, integer setToLevel returns nothing\n */\nfunction SetPlayerTechResearched(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  const _setToLevel = luaL_checkinteger(L, 3);\n  console.warn('SetPlayerTechResearched was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetPlayerTechResearched takes player whichPlayer, integer techid, boolean specificonly returns boolean\n */\nfunction GetPlayerTechResearched(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  const _specificonly = lua_toboolean(L, 3);\n  console.warn('GetPlayerTechResearched was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * constant native GetPlayerTechCount takes player whichPlayer, integer techid, boolean specificonly returns integer\n */\nfunction GetPlayerTechCount(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  const _specificonly = lua_toboolean(L, 3);\n  console.warn('GetPlayerTechCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetPlayerUnitsOwner takes player whichPlayer, integer newOwner returns nothing\n */\nfunction SetPlayerUnitsOwner(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _newOwner = luaL_checkinteger(L, 2);\n  console.warn('SetPlayerUnitsOwner was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CripplePlayer takes player whichPlayer, force toWhichPlayers, boolean flag returns nothing\n */\nfunction CripplePlayer(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _toWhichPlayers = lua_touserdata(L, 2);\n  const _flag = lua_toboolean(L, 3);\n  console.warn('CripplePlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerAbilityAvailable takes player whichPlayer, integer abilid, boolean avail returns nothing\n */\nfunction SetPlayerAbilityAvailable(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _abilid = luaL_checkinteger(L, 2);\n  const _avail = lua_toboolean(L, 3);\n  console.warn('SetPlayerAbilityAvailable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetPlayerState takes player whichPlayer, playerstate whichPlayerState, integer value returns nothing\n */\nfunction SetPlayerState(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichPlayerState = lua_touserdata(L, 2);\n  const _value = luaL_checkinteger(L, 3);\n  console.warn('SetPlayerState was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemovePlayer takes player whichPlayer, playergameresult gameResult returns nothing\n */\nfunction RemovePlayer(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _gameResult = lua_touserdata(L, 2);\n  console.warn('RemovePlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CachePlayerHeroData takes player whichPlayer returns nothing\n */\nfunction CachePlayerHeroData(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  console.warn('CachePlayerHeroData was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetFogStateRect takes player forWhichPlayer, fogstate whichState, rect where, boolean useSharedVision returns nothing\n */\nfunction SetFogStateRect(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _where = lua_touserdata(L, 3);\n  const _useSharedVision = lua_toboolean(L, 4);\n  console.warn('SetFogStateRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetFogStateRadius takes player forWhichPlayer, fogstate whichState, real centerx, real centerY, real radius, boolean useSharedVision returns nothing\n */\nfunction SetFogStateRadius(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _centerx = luaL_checknumber(L, 3);\n  const _centerY = luaL_checknumber(L, 4);\n  const _radius = luaL_checknumber(L, 5);\n  const _useSharedVision = lua_toboolean(L, 6);\n  console.warn('SetFogStateRadius was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetFogStateRadiusLoc takes player forWhichPlayer, fogstate whichState, location center, real radius, boolean useSharedVision returns nothing\n */\nfunction SetFogStateRadiusLoc(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _center = lua_touserdata(L, 3);\n  const _radius = luaL_checknumber(L, 4);\n  const _useSharedVision = lua_toboolean(L, 5);\n  console.warn('SetFogStateRadiusLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FogMaskEnable takes boolean enable returns nothing\n */\nfunction FogMaskEnable(C: Context, L: lua_State): number {\n  const _enable = lua_toboolean(L, 1);\n  console.warn('FogMaskEnable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsFogMaskEnabled takes nothing returns boolean\n */\nfunction IsFogMaskEnabled(C: Context, L: lua_State): number {\n\n  console.warn('IsFogMaskEnabled was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native FogEnable takes boolean enable returns nothing\n */\nfunction FogEnable(C: Context, L: lua_State): number {\n  const _enable = lua_toboolean(L, 1);\n  console.warn('FogEnable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsFogEnabled takes nothing returns boolean\n */\nfunction IsFogEnabled(C: Context, L: lua_State): number {\n\n  console.warn('IsFogEnabled was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native CreateFogModifierRect takes player forWhichPlayer, fogstate whichState, rect where, boolean useSharedVision, boolean afterUnits returns fogmodifier\n */\nfunction CreateFogModifierRect(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _where = lua_touserdata(L, 3);\n  const _useSharedVision = lua_toboolean(L, 4);\n  const _afterUnits = lua_toboolean(L, 5);\n  console.warn('CreateFogModifierRect was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateFogModifierRadius takes player forWhichPlayer, fogstate whichState, real centerx, real centerY, real radius, boolean useSharedVision, boolean afterUnits returns fogmodifier\n */\nfunction CreateFogModifierRadius(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _centerx = luaL_checknumber(L, 3);\n  const _centerY = luaL_checknumber(L, 4);\n  const _radius = luaL_checknumber(L, 5);\n  const _useSharedVision = lua_toboolean(L, 6);\n  const _afterUnits = lua_toboolean(L, 7);\n  console.warn('CreateFogModifierRadius was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateFogModifierRadiusLoc takes player forWhichPlayer, fogstate whichState, location center, real radius, boolean useSharedVision, boolean afterUnits returns fogmodifier\n */\nfunction CreateFogModifierRadiusLoc(C: Context, L: lua_State): number {\n  const _forWhichPlayer = lua_touserdata(L, 1);\n  const _whichState = lua_touserdata(L, 2);\n  const _center = lua_touserdata(L, 3);\n  const _radius = luaL_checknumber(L, 4);\n  const _useSharedVision = lua_toboolean(L, 5);\n  const _afterUnits = lua_toboolean(L, 6);\n  console.warn('CreateFogModifierRadiusLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyFogModifier takes fogmodifier whichFogModifier returns nothing\n */\nfunction DestroyFogModifier(C: Context, L: lua_State): number {\n  const _whichFogModifier = lua_touserdata(L, 1);\n  console.warn('DestroyFogModifier was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FogModifierStart takes fogmodifier whichFogModifier returns nothing\n */\nfunction FogModifierStart(C: Context, L: lua_State): number {\n  const _whichFogModifier = lua_touserdata(L, 1);\n  console.warn('FogModifierStart was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FogModifierStop takes fogmodifier whichFogModifier returns nothing\n */\nfunction FogModifierStop(C: Context, L: lua_State): number {\n  const _whichFogModifier = lua_touserdata(L, 1);\n  console.warn('FogModifierStop was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native VersionGet takes nothing returns version\n */\nfunction VersionGet(C: Context, L: lua_State): number {\n\n  console.warn('VersionGet was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native VersionCompatible takes version whichVersion returns boolean\n */\nfunction VersionCompatible(C: Context, L: lua_State): number {\n  const _whichVersion = lua_touserdata(L, 1);\n  console.warn('VersionCompatible was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native VersionSupported takes version whichVersion returns boolean\n */\nfunction VersionSupported(C: Context, L: lua_State): number {\n  const _whichVersion = lua_touserdata(L, 1);\n  console.warn('VersionSupported was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native EndGame takes boolean doScoreScreen returns nothing\n */\nfunction EndGame(C: Context, L: lua_State): number {\n  const _doScoreScreen = lua_toboolean(L, 1);\n  console.warn('EndGame was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ChangeLevel takes string newLevel, boolean doScoreScreen returns nothing\n */\nfunction ChangeLevel(C: Context, L: lua_State): number {\n  const _newLevel = luaL_checkstring(L, 1);\n  const _doScoreScreen = lua_toboolean(L, 2);\n  console.warn('ChangeLevel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RestartGame takes boolean doScoreScreen returns nothing\n */\nfunction RestartGame(C: Context, L: lua_State): number {\n  const _doScoreScreen = lua_toboolean(L, 1);\n  console.warn('RestartGame was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ReloadGame takes nothing returns nothing\n */\nfunction ReloadGame(_C: Context, _L: lua_State): number {\n\n  console.warn('ReloadGame was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCampaignMenuRace takes race r returns nothing\n */\nfunction SetCampaignMenuRace(C: Context, L: lua_State): number {\n  const _r = lua_touserdata(L, 1);\n  console.warn('SetCampaignMenuRace was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCampaignMenuRaceEx takes integer campaignIndex returns nothing\n */\nfunction SetCampaignMenuRaceEx(C: Context, L: lua_State): number {\n  const _campaignIndex = luaL_checkinteger(L, 1);\n  console.warn('SetCampaignMenuRaceEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceCampaignSelectScreen takes nothing returns nothing\n */\nfunction ForceCampaignSelectScreen(_C: Context, _L: lua_State): number {\n\n  console.warn('ForceCampaignSelectScreen was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LoadGame takes string saveFileName, boolean doScoreScreen returns nothing\n */\nfunction LoadGame(C: Context, L: lua_State): number {\n  const _saveFileName = luaL_checkstring(L, 1);\n  const _doScoreScreen = lua_toboolean(L, 2);\n  console.warn('LoadGame was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SaveGame takes string saveFileName returns nothing\n */\nfunction SaveGame(C: Context, L: lua_State): number {\n  const _saveFileName = luaL_checkstring(L, 1);\n  console.warn('SaveGame was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RenameSaveDirectory takes string sourceDirName, string destDirName returns boolean\n */\nfunction RenameSaveDirectory(C: Context, L: lua_State): number {\n  const _sourceDirName = luaL_checkstring(L, 1);\n  const _destDirName = luaL_checkstring(L, 2);\n  console.warn('RenameSaveDirectory was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native RemoveSaveDirectory takes string sourceDirName returns boolean\n */\nfunction RemoveSaveDirectory(C: Context, L: lua_State): number {\n  const _sourceDirName = luaL_checkstring(L, 1);\n  console.warn('RemoveSaveDirectory was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native CopySaveGame takes string sourceSaveName, string destSaveName returns boolean\n */\nfunction CopySaveGame(C: Context, L: lua_State): number {\n  const _sourceSaveName = luaL_checkstring(L, 1);\n  const _destSaveName = luaL_checkstring(L, 2);\n  console.warn('CopySaveGame was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveGameExists takes string saveName returns boolean\n */\nfunction SaveGameExists(C: Context, L: lua_State): number {\n  const _saveName = luaL_checkstring(L, 1);\n  console.warn('SaveGameExists was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SyncSelections takes nothing returns nothing\n */\nfunction SyncSelections(_C: Context, _L: lua_State): number {\n\n  console.warn('SyncSelections was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetFloatGameState takes fgamestate whichFloatGameState, real value returns nothing\n */\nfunction SetFloatGameState(C: Context, L: lua_State): number {\n  const _whichFloatGameState = lua_touserdata(L, 1);\n  const _value = luaL_checknumber(L, 2);\n  console.warn('SetFloatGameState was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetFloatGameState takes fgamestate whichFloatGameState returns real\n */\nfunction GetFloatGameState(C: Context, L: lua_State): number {\n  const _whichFloatGameState = lua_touserdata(L, 1);\n  console.warn('GetFloatGameState was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetIntegerGameState takes igamestate whichIntegerGameState, integer value returns nothing\n */\nfunction SetIntegerGameState(C: Context, L: lua_State): number {\n  const _whichIntegerGameState = lua_touserdata(L, 1);\n  const _value = luaL_checkinteger(L, 2);\n  console.warn('SetIntegerGameState was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * constant native GetIntegerGameState takes igamestate whichIntegerGameState returns integer\n */\nfunction GetIntegerGameState(C: Context, L: lua_State): number {\n  const _whichIntegerGameState = lua_touserdata(L, 1);\n  console.warn('GetIntegerGameState was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetTutorialCleared takes boolean cleared returns nothing\n */\nfunction SetTutorialCleared(C: Context, L: lua_State): number {\n  const _cleared = lua_toboolean(L, 1);\n  console.warn('SetTutorialCleared was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetMissionAvailable takes integer campaignNumber, integer missionNumber, boolean available returns nothing\n */\nfunction SetMissionAvailable(C: Context, L: lua_State): number {\n  const _campaignNumber = luaL_checkinteger(L, 1);\n  const _missionNumber = luaL_checkinteger(L, 2);\n  const _available = lua_toboolean(L, 3);\n  console.warn('SetMissionAvailable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCampaignAvailable takes integer campaignNumber, boolean available returns nothing\n */\nfunction SetCampaignAvailable(C: Context, L: lua_State): number {\n  const _campaignNumber = luaL_checkinteger(L, 1);\n  const _available = lua_toboolean(L, 2);\n  console.warn('SetCampaignAvailable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetOpCinematicAvailable takes integer campaignNumber, boolean available returns nothing\n */\nfunction SetOpCinematicAvailable(C: Context, L: lua_State): number {\n  const _campaignNumber = luaL_checkinteger(L, 1);\n  const _available = lua_toboolean(L, 2);\n  console.warn('SetOpCinematicAvailable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetEdCinematicAvailable takes integer campaignNumber, boolean available returns nothing\n */\nfunction SetEdCinematicAvailable(C: Context, L: lua_State): number {\n  const _campaignNumber = luaL_checkinteger(L, 1);\n  const _available = lua_toboolean(L, 2);\n  console.warn('SetEdCinematicAvailable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetDefaultDifficulty takes nothing returns gamedifficulty\n */\nfunction GetDefaultDifficulty(C: Context, L: lua_State): number {\n\n  console.warn('GetDefaultDifficulty was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SetDefaultDifficulty takes gamedifficulty g returns nothing\n */\nfunction SetDefaultDifficulty(C: Context, L: lua_State): number {\n  const _g = lua_touserdata(L, 1);\n  console.warn('SetDefaultDifficulty was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCustomCampaignButtonVisible takes integer whichButton, boolean visible returns nothing\n */\nfunction SetCustomCampaignButtonVisible(C: Context, L: lua_State): number {\n  const _whichButton = luaL_checkinteger(L, 1);\n  const _visible = lua_toboolean(L, 2);\n  console.warn('SetCustomCampaignButtonVisible was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetCustomCampaignButtonVisible takes integer whichButton returns boolean\n */\nfunction GetCustomCampaignButtonVisible(C: Context, L: lua_State): number {\n  const _whichButton = luaL_checkinteger(L, 1);\n  console.warn('GetCustomCampaignButtonVisible was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native DoNotSaveReplay takes nothing returns nothing\n */\nfunction DoNotSaveReplay(_C: Context, _L: lua_State): number {\n\n  console.warn('DoNotSaveReplay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DialogCreate takes nothing returns dialog\n */\nfunction DialogCreate(C: Context, L: lua_State): number {\n\n  console.warn('DialogCreate was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DialogDestroy takes dialog whichDialog returns nothing\n */\nfunction DialogDestroy(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  console.warn('DialogDestroy was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DialogClear takes dialog whichDialog returns nothing\n */\nfunction DialogClear(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  console.warn('DialogClear was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DialogSetMessage takes dialog whichDialog, string messageText returns nothing\n */\nfunction DialogSetMessage(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _messageText = luaL_checkstring(L, 2);\n  console.warn('DialogSetMessage was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DialogAddButton takes dialog whichDialog, string buttonText, integer hotkey returns button\n */\nfunction DialogAddButton(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _buttonText = luaL_checkstring(L, 2);\n  const _hotkey = luaL_checkinteger(L, 3);\n  console.warn('DialogAddButton was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DialogAddQuitButton takes dialog whichDialog, boolean doScoreScreen, string buttonText, integer hotkey returns button\n */\nfunction DialogAddQuitButton(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _doScoreScreen = lua_toboolean(L, 2);\n  const _buttonText = luaL_checkstring(L, 3);\n  const _hotkey = luaL_checkinteger(L, 4);\n  console.warn('DialogAddQuitButton was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DialogDisplay takes player whichPlayer, dialog whichDialog, boolean flag returns nothing\n */\nfunction DialogDisplay(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichDialog = lua_touserdata(L, 2);\n  const _flag = lua_toboolean(L, 3);\n  console.warn('DialogDisplay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ReloadGameCachesFromDisk takes nothing returns boolean\n */\nfunction ReloadGameCachesFromDisk(C: Context, L: lua_State): number {\n\n  console.warn('ReloadGameCachesFromDisk was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native InitGameCache takes string campaignFile returns gamecache\n */\nfunction InitGameCache(C: Context, L: lua_State): number {\n  const _campaignFile = luaL_checkstring(L, 1);\n  console.warn('InitGameCache was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SaveGameCache takes gamecache whichCache returns boolean\n */\nfunction SaveGameCache(C: Context, L: lua_State): number {\n  const _whichCache = lua_touserdata(L, 1);\n  console.warn('SaveGameCache was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native StoreInteger takes gamecache cache, string missionKey, string key, integer value returns nothing\n */\nfunction StoreInteger(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  const _value = luaL_checkinteger(L, 4);\n  console.warn('StoreInteger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StoreReal takes gamecache cache, string missionKey, string key, real value returns nothing\n */\nfunction StoreReal(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  const _value = luaL_checknumber(L, 4);\n  console.warn('StoreReal was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StoreBoolean takes gamecache cache, string missionKey, string key, boolean value returns nothing\n */\nfunction StoreBoolean(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  const _value = lua_toboolean(L, 4);\n  console.warn('StoreBoolean was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StoreUnit takes gamecache cache, string missionKey, string key, unit whichUnit returns boolean\n */\nfunction StoreUnit(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  const _whichUnit = lua_touserdata(L, 4);\n  console.warn('StoreUnit was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native StoreString takes gamecache cache, string missionKey, string key, string value returns boolean\n */\nfunction StoreString(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  const _value = luaL_checkstring(L, 4);\n  console.warn('StoreString was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SyncStoredInteger takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction SyncStoredInteger(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('SyncStoredInteger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SyncStoredReal takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction SyncStoredReal(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('SyncStoredReal was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SyncStoredBoolean takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction SyncStoredBoolean(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('SyncStoredBoolean was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SyncStoredUnit takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction SyncStoredUnit(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('SyncStoredUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SyncStoredString takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction SyncStoredString(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('SyncStoredString was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native HaveStoredInteger takes gamecache cache, string missionKey, string key returns boolean\n */\nfunction HaveStoredInteger(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('HaveStoredInteger was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveStoredReal takes gamecache cache, string missionKey, string key returns boolean\n */\nfunction HaveStoredReal(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('HaveStoredReal was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveStoredBoolean takes gamecache cache, string missionKey, string key returns boolean\n */\nfunction HaveStoredBoolean(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('HaveStoredBoolean was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveStoredUnit takes gamecache cache, string missionKey, string key returns boolean\n */\nfunction HaveStoredUnit(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('HaveStoredUnit was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveStoredString takes gamecache cache, string missionKey, string key returns boolean\n */\nfunction HaveStoredString(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('HaveStoredString was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native FlushGameCache takes gamecache cache returns nothing\n */\nfunction FlushGameCache(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  console.warn('FlushGameCache was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushStoredMission takes gamecache cache, string missionKey returns nothing\n */\nfunction FlushStoredMission(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  console.warn('FlushStoredMission was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushStoredInteger takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction FlushStoredInteger(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('FlushStoredInteger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushStoredReal takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction FlushStoredReal(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('FlushStoredReal was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushStoredBoolean takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction FlushStoredBoolean(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('FlushStoredBoolean was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushStoredUnit takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction FlushStoredUnit(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('FlushStoredUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushStoredString takes gamecache cache, string missionKey, string key returns nothing\n */\nfunction FlushStoredString(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('FlushStoredString was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetStoredInteger takes gamecache cache, string missionKey, string key returns integer\n */\nfunction GetStoredInteger(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('GetStoredInteger was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetStoredReal takes gamecache cache, string missionKey, string key returns real\n */\nfunction GetStoredReal(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('GetStoredReal was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetStoredBoolean takes gamecache cache, string missionKey, string key returns boolean\n */\nfunction GetStoredBoolean(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('GetStoredBoolean was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetStoredString takes gamecache cache, string missionKey, string key returns string\n */\nfunction GetStoredString(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  console.warn('GetStoredString was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native RestoreUnit takes gamecache cache, string missionKey, string key, player forWhichPlayer, real x, real y, real facing returns unit\n */\nfunction RestoreUnit(C: Context, L: lua_State): number {\n  const _cache = lua_touserdata(L, 1);\n  const _missionKey = luaL_checkstring(L, 2);\n  const _key = luaL_checkstring(L, 3);\n  const _forWhichPlayer = lua_touserdata(L, 4);\n  const _x = luaL_checknumber(L, 5);\n  const _y = luaL_checknumber(L, 6);\n  const _facing = luaL_checknumber(L, 7);\n  console.warn('RestoreUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native InitHashtable takes nothing returns hashtable\n */\nfunction InitHashtable(C: Context, L: lua_State): number {\n\n  console.warn('InitHashtable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SaveInteger takes hashtable table, integer parentKey, integer childKey, integer value returns nothing\n */\nfunction SaveInteger(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _value = luaL_checkinteger(L, 4);\n  console.warn('SaveInteger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SaveReal takes hashtable table, integer parentKey, integer childKey, real value returns nothing\n */\nfunction SaveReal(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _value = luaL_checknumber(L, 4);\n  console.warn('SaveReal was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SaveBoolean takes hashtable table, integer parentKey, integer childKey, boolean value returns nothing\n */\nfunction SaveBoolean(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _value = lua_toboolean(L, 4);\n  console.warn('SaveBoolean was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SaveStr takes hashtable table, integer parentKey, integer childKey, string value returns boolean\n */\nfunction SaveStr(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _value = luaL_checkstring(L, 4);\n  console.warn('SaveStr was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SavePlayerHandle takes hashtable table, integer parentKey, integer childKey, player whichPlayer returns boolean\n */\nfunction SavePlayerHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichPlayer = lua_touserdata(L, 4);\n  console.warn('SavePlayerHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveWidgetHandle takes hashtable table, integer parentKey, integer childKey, widget whichWidget returns boolean\n */\nfunction SaveWidgetHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichWidget = lua_touserdata(L, 4);\n  console.warn('SaveWidgetHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveDestructableHandle takes hashtable table, integer parentKey, integer childKey, destructable whichDestructable returns boolean\n */\nfunction SaveDestructableHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichDestructable = lua_touserdata(L, 4);\n  console.warn('SaveDestructableHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveItemHandle takes hashtable table, integer parentKey, integer childKey, item whichItem returns boolean\n */\nfunction SaveItemHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichItem = lua_touserdata(L, 4);\n  console.warn('SaveItemHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveUnitHandle takes hashtable table, integer parentKey, integer childKey, unit whichUnit returns boolean\n */\nfunction SaveUnitHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichUnit = lua_touserdata(L, 4);\n  console.warn('SaveUnitHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveAbilityHandle takes hashtable table, integer parentKey, integer childKey, ability whichAbility returns boolean\n */\nfunction SaveAbilityHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichAbility = lua_touserdata(L, 4);\n  console.warn('SaveAbilityHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTimerHandle takes hashtable table, integer parentKey, integer childKey, timer whichTimer returns boolean\n */\nfunction SaveTimerHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTimer = lua_touserdata(L, 4);\n  console.warn('SaveTimerHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTriggerHandle takes hashtable table, integer parentKey, integer childKey, trigger whichTrigger returns boolean\n */\nfunction SaveTriggerHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTrigger = lua_touserdata(L, 4);\n  console.warn('SaveTriggerHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTriggerConditionHandle takes hashtable table, integer parentKey, integer childKey, triggercondition whichTriggercondition returns boolean\n */\nfunction SaveTriggerConditionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTriggercondition = lua_touserdata(L, 4);\n  console.warn('SaveTriggerConditionHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTriggerActionHandle takes hashtable table, integer parentKey, integer childKey, triggeraction whichTriggeraction returns boolean\n */\nfunction SaveTriggerActionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTriggeraction = lua_touserdata(L, 4);\n  console.warn('SaveTriggerActionHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTriggerEventHandle takes hashtable table, integer parentKey, integer childKey, event whichEvent returns boolean\n */\nfunction SaveTriggerEventHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichEvent = lua_touserdata(L, 4);\n  console.warn('SaveTriggerEventHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveForceHandle takes hashtable table, integer parentKey, integer childKey, force whichForce returns boolean\n */\nfunction SaveForceHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichForce = lua_touserdata(L, 4);\n  console.warn('SaveForceHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveGroupHandle takes hashtable table, integer parentKey, integer childKey, group whichGroup returns boolean\n */\nfunction SaveGroupHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichGroup = lua_touserdata(L, 4);\n  console.warn('SaveGroupHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveLocationHandle takes hashtable table, integer parentKey, integer childKey, location whichLocation returns boolean\n */\nfunction SaveLocationHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichLocation = lua_touserdata(L, 4);\n  console.warn('SaveLocationHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveRectHandle takes hashtable table, integer parentKey, integer childKey, rect whichRect returns boolean\n */\nfunction SaveRectHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichRect = lua_touserdata(L, 4);\n  console.warn('SaveRectHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveBooleanExprHandle takes hashtable table, integer parentKey, integer childKey, boolexpr whichBoolexpr returns boolean\n */\nfunction SaveBooleanExprHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichBoolexpr = lua_touserdata(L, 4);\n  console.warn('SaveBooleanExprHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveSoundHandle takes hashtable table, integer parentKey, integer childKey, sound whichSound returns boolean\n */\nfunction SaveSoundHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichSound = lua_touserdata(L, 4);\n  console.warn('SaveSoundHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveEffectHandle takes hashtable table, integer parentKey, integer childKey, effect whichEffect returns boolean\n */\nfunction SaveEffectHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichEffect = lua_touserdata(L, 4);\n  console.warn('SaveEffectHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveUnitPoolHandle takes hashtable table, integer parentKey, integer childKey, unitpool whichUnitpool returns boolean\n */\nfunction SaveUnitPoolHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichUnitpool = lua_touserdata(L, 4);\n  console.warn('SaveUnitPoolHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveItemPoolHandle takes hashtable table, integer parentKey, integer childKey, itempool whichItempool returns boolean\n */\nfunction SaveItemPoolHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichItempool = lua_touserdata(L, 4);\n  console.warn('SaveItemPoolHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveQuestHandle takes hashtable table, integer parentKey, integer childKey, quest whichQuest returns boolean\n */\nfunction SaveQuestHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichQuest = lua_touserdata(L, 4);\n  console.warn('SaveQuestHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveQuestItemHandle takes hashtable table, integer parentKey, integer childKey, questitem whichQuestitem returns boolean\n */\nfunction SaveQuestItemHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichQuestitem = lua_touserdata(L, 4);\n  console.warn('SaveQuestItemHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveDefeatConditionHandle takes hashtable table, integer parentKey, integer childKey, defeatcondition whichDefeatcondition returns boolean\n */\nfunction SaveDefeatConditionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichDefeatcondition = lua_touserdata(L, 4);\n  console.warn('SaveDefeatConditionHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTimerDialogHandle takes hashtable table, integer parentKey, integer childKey, timerdialog whichTimerdialog returns boolean\n */\nfunction SaveTimerDialogHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTimerdialog = lua_touserdata(L, 4);\n  console.warn('SaveTimerDialogHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveLeaderboardHandle takes hashtable table, integer parentKey, integer childKey, leaderboard whichLeaderboard returns boolean\n */\nfunction SaveLeaderboardHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichLeaderboard = lua_touserdata(L, 4);\n  console.warn('SaveLeaderboardHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveMultiboardHandle takes hashtable table, integer parentKey, integer childKey, multiboard whichMultiboard returns boolean\n */\nfunction SaveMultiboardHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichMultiboard = lua_touserdata(L, 4);\n  console.warn('SaveMultiboardHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveMultiboardItemHandle takes hashtable table, integer parentKey, integer childKey, multiboarditem whichMultiboarditem returns boolean\n */\nfunction SaveMultiboardItemHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichMultiboarditem = lua_touserdata(L, 4);\n  console.warn('SaveMultiboardItemHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTrackableHandle takes hashtable table, integer parentKey, integer childKey, trackable whichTrackable returns boolean\n */\nfunction SaveTrackableHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTrackable = lua_touserdata(L, 4);\n  console.warn('SaveTrackableHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveDialogHandle takes hashtable table, integer parentKey, integer childKey, dialog whichDialog returns boolean\n */\nfunction SaveDialogHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichDialog = lua_touserdata(L, 4);\n  console.warn('SaveDialogHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveButtonHandle takes hashtable table, integer parentKey, integer childKey, button whichButton returns boolean\n */\nfunction SaveButtonHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichButton = lua_touserdata(L, 4);\n  console.warn('SaveButtonHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveTextTagHandle takes hashtable table, integer parentKey, integer childKey, texttag whichTexttag returns boolean\n */\nfunction SaveTextTagHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichTexttag = lua_touserdata(L, 4);\n  console.warn('SaveTextTagHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveLightningHandle takes hashtable table, integer parentKey, integer childKey, lightning whichLightning returns boolean\n */\nfunction SaveLightningHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichLightning = lua_touserdata(L, 4);\n  console.warn('SaveLightningHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveImageHandle takes hashtable table, integer parentKey, integer childKey, image whichImage returns boolean\n */\nfunction SaveImageHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichImage = lua_touserdata(L, 4);\n  console.warn('SaveImageHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveUbersplatHandle takes hashtable table, integer parentKey, integer childKey, ubersplat whichUbersplat returns boolean\n */\nfunction SaveUbersplatHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichUbersplat = lua_touserdata(L, 4);\n  console.warn('SaveUbersplatHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveRegionHandle takes hashtable table, integer parentKey, integer childKey, region whichRegion returns boolean\n */\nfunction SaveRegionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichRegion = lua_touserdata(L, 4);\n  console.warn('SaveRegionHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveFogStateHandle takes hashtable table, integer parentKey, integer childKey, fogstate whichFogState returns boolean\n */\nfunction SaveFogStateHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichFogState = lua_touserdata(L, 4);\n  console.warn('SaveFogStateHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveFogModifierHandle takes hashtable table, integer parentKey, integer childKey, fogmodifier whichFogModifier returns boolean\n */\nfunction SaveFogModifierHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichFogModifier = lua_touserdata(L, 4);\n  console.warn('SaveFogModifierHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveAgentHandle takes hashtable table, integer parentKey, integer childKey, agent whichAgent returns boolean\n */\nfunction SaveAgentHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichAgent = lua_touserdata(L, 4);\n  console.warn('SaveAgentHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SaveHashtableHandle takes hashtable table, integer parentKey, integer childKey, hashtable whichHashtable returns boolean\n */\nfunction SaveHashtableHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  const _whichHashtable = lua_touserdata(L, 4);\n  console.warn('SaveHashtableHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native LoadInteger takes hashtable table, integer parentKey, integer childKey returns integer\n */\nfunction LoadInteger(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadInteger was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native LoadReal takes hashtable table, integer parentKey, integer childKey returns real\n */\nfunction LoadReal(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadReal was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native LoadBoolean takes hashtable table, integer parentKey, integer childKey returns boolean\n */\nfunction LoadBoolean(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadBoolean was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native LoadStr takes hashtable table, integer parentKey, integer childKey returns string\n */\nfunction LoadStr(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadStr was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native LoadPlayerHandle takes hashtable table, integer parentKey, integer childKey returns player\n */\nfunction LoadPlayerHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadPlayerHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadWidgetHandle takes hashtable table, integer parentKey, integer childKey returns widget\n */\nfunction LoadWidgetHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadWidgetHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadDestructableHandle takes hashtable table, integer parentKey, integer childKey returns destructable\n */\nfunction LoadDestructableHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadDestructableHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadItemHandle takes hashtable table, integer parentKey, integer childKey returns item\n */\nfunction LoadItemHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadItemHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadUnitHandle takes hashtable table, integer parentKey, integer childKey returns unit\n */\nfunction LoadUnitHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadUnitHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadAbilityHandle takes hashtable table, integer parentKey, integer childKey returns ability\n */\nfunction LoadAbilityHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadAbilityHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTimerHandle takes hashtable table, integer parentKey, integer childKey returns timer\n */\nfunction LoadTimerHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTimerHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTriggerHandle takes hashtable table, integer parentKey, integer childKey returns trigger\n */\nfunction LoadTriggerHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTriggerHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTriggerConditionHandle takes hashtable table, integer parentKey, integer childKey returns triggercondition\n */\nfunction LoadTriggerConditionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTriggerConditionHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTriggerActionHandle takes hashtable table, integer parentKey, integer childKey returns triggeraction\n */\nfunction LoadTriggerActionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTriggerActionHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTriggerEventHandle takes hashtable table, integer parentKey, integer childKey returns event\n */\nfunction LoadTriggerEventHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTriggerEventHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadForceHandle takes hashtable table, integer parentKey, integer childKey returns force\n */\nfunction LoadForceHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadForceHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadGroupHandle takes hashtable table, integer parentKey, integer childKey returns group\n */\nfunction LoadGroupHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadGroupHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadLocationHandle takes hashtable table, integer parentKey, integer childKey returns location\n */\nfunction LoadLocationHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadLocationHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadRectHandle takes hashtable table, integer parentKey, integer childKey returns rect\n */\nfunction LoadRectHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadRectHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadBooleanExprHandle takes hashtable table, integer parentKey, integer childKey returns boolexpr\n */\nfunction LoadBooleanExprHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadBooleanExprHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadSoundHandle takes hashtable table, integer parentKey, integer childKey returns sound\n */\nfunction LoadSoundHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadSoundHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadEffectHandle takes hashtable table, integer parentKey, integer childKey returns effect\n */\nfunction LoadEffectHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadEffectHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadUnitPoolHandle takes hashtable table, integer parentKey, integer childKey returns unitpool\n */\nfunction LoadUnitPoolHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadUnitPoolHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadItemPoolHandle takes hashtable table, integer parentKey, integer childKey returns itempool\n */\nfunction LoadItemPoolHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadItemPoolHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadQuestHandle takes hashtable table, integer parentKey, integer childKey returns quest\n */\nfunction LoadQuestHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadQuestHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadQuestItemHandle takes hashtable table, integer parentKey, integer childKey returns questitem\n */\nfunction LoadQuestItemHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadQuestItemHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadDefeatConditionHandle takes hashtable table, integer parentKey, integer childKey returns defeatcondition\n */\nfunction LoadDefeatConditionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadDefeatConditionHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTimerDialogHandle takes hashtable table, integer parentKey, integer childKey returns timerdialog\n */\nfunction LoadTimerDialogHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTimerDialogHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadLeaderboardHandle takes hashtable table, integer parentKey, integer childKey returns leaderboard\n */\nfunction LoadLeaderboardHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadLeaderboardHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadMultiboardHandle takes hashtable table, integer parentKey, integer childKey returns multiboard\n */\nfunction LoadMultiboardHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadMultiboardHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadMultiboardItemHandle takes hashtable table, integer parentKey, integer childKey returns multiboarditem\n */\nfunction LoadMultiboardItemHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadMultiboardItemHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTrackableHandle takes hashtable table, integer parentKey, integer childKey returns trackable\n */\nfunction LoadTrackableHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTrackableHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadDialogHandle takes hashtable table, integer parentKey, integer childKey returns dialog\n */\nfunction LoadDialogHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadDialogHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadButtonHandle takes hashtable table, integer parentKey, integer childKey returns button\n */\nfunction LoadButtonHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadButtonHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadTextTagHandle takes hashtable table, integer parentKey, integer childKey returns texttag\n */\nfunction LoadTextTagHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadTextTagHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadLightningHandle takes hashtable table, integer parentKey, integer childKey returns lightning\n */\nfunction LoadLightningHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadLightningHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadImageHandle takes hashtable table, integer parentKey, integer childKey returns image\n */\nfunction LoadImageHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadImageHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadUbersplatHandle takes hashtable table, integer parentKey, integer childKey returns ubersplat\n */\nfunction LoadUbersplatHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadUbersplatHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadRegionHandle takes hashtable table, integer parentKey, integer childKey returns region\n */\nfunction LoadRegionHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadRegionHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadFogStateHandle takes hashtable table, integer parentKey, integer childKey returns fogstate\n */\nfunction LoadFogStateHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadFogStateHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadFogModifierHandle takes hashtable table, integer parentKey, integer childKey returns fogmodifier\n */\nfunction LoadFogModifierHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadFogModifierHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LoadHashtableHandle takes hashtable table, integer parentKey, integer childKey returns hashtable\n */\nfunction LoadHashtableHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('LoadHashtableHandle was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native HaveSavedInteger takes hashtable table, integer parentKey, integer childKey returns boolean\n */\nfunction HaveSavedInteger(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('HaveSavedInteger was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveSavedReal takes hashtable table, integer parentKey, integer childKey returns boolean\n */\nfunction HaveSavedReal(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('HaveSavedReal was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveSavedBoolean takes hashtable table, integer parentKey, integer childKey returns boolean\n */\nfunction HaveSavedBoolean(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('HaveSavedBoolean was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveSavedString takes hashtable table, integer parentKey, integer childKey returns boolean\n */\nfunction HaveSavedString(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('HaveSavedString was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native HaveSavedHandle takes hashtable table, integer parentKey, integer childKey returns boolean\n */\nfunction HaveSavedHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('HaveSavedHandle was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native RemoveSavedInteger takes hashtable table, integer parentKey, integer childKey returns nothing\n */\nfunction RemoveSavedInteger(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('RemoveSavedInteger was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveSavedReal takes hashtable table, integer parentKey, integer childKey returns nothing\n */\nfunction RemoveSavedReal(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('RemoveSavedReal was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveSavedBoolean takes hashtable table, integer parentKey, integer childKey returns nothing\n */\nfunction RemoveSavedBoolean(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('RemoveSavedBoolean was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveSavedString takes hashtable table, integer parentKey, integer childKey returns nothing\n */\nfunction RemoveSavedString(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('RemoveSavedString was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveSavedHandle takes hashtable table, integer parentKey, integer childKey returns nothing\n */\nfunction RemoveSavedHandle(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  const _childKey = luaL_checkinteger(L, 3);\n  console.warn('RemoveSavedHandle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushParentHashtable takes hashtable table returns nothing\n */\nfunction FlushParentHashtable(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  console.warn('FlushParentHashtable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlushChildHashtable takes hashtable table, integer parentKey returns nothing\n */\nfunction FlushChildHashtable(C: Context, L: lua_State): number {\n  const _table = lua_touserdata(L, 1);\n  const _parentKey = luaL_checkinteger(L, 2);\n  console.warn('FlushChildHashtable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetRandomInt takes integer lowBound, integer highBound returns integer\n */\nfunction GetRandomInt(C: Context, L: lua_State): number {\n  const _lowBound = luaL_checkinteger(L, 1);\n  const _highBound = luaL_checkinteger(L, 2);\n  console.warn('GetRandomInt was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetRandomReal takes real lowBound, real highBound returns real\n */\nfunction GetRandomReal(C: Context, L: lua_State): number {\n  const _lowBound = luaL_checknumber(L, 1);\n  const _highBound = luaL_checknumber(L, 2);\n  console.warn('GetRandomReal was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native CreateUnitPool takes nothing returns unitpool\n */\nfunction CreateUnitPool(C: Context, L: lua_State): number {\n\n  console.warn('CreateUnitPool was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyUnitPool takes unitpool whichPool returns nothing\n */\nfunction DestroyUnitPool(C: Context, L: lua_State): number {\n  const _whichPool = lua_touserdata(L, 1);\n  console.warn('DestroyUnitPool was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitPoolAddUnitType takes unitpool whichPool, integer unitId, real weight returns nothing\n */\nfunction UnitPoolAddUnitType(C: Context, L: lua_State): number {\n  const _whichPool = lua_touserdata(L, 1);\n  const _unitId = luaL_checkinteger(L, 2);\n  const _weight = luaL_checknumber(L, 3);\n  console.warn('UnitPoolAddUnitType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitPoolRemoveUnitType takes unitpool whichPool, integer unitId returns nothing\n */\nfunction UnitPoolRemoveUnitType(C: Context, L: lua_State): number {\n  const _whichPool = lua_touserdata(L, 1);\n  const _unitId = luaL_checkinteger(L, 2);\n  console.warn('UnitPoolRemoveUnitType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlaceRandomUnit takes unitpool whichPool, player forWhichPlayer, real x, real y, real facing returns unit\n */\nfunction PlaceRandomUnit(C: Context, L: lua_State): number {\n  const _whichPool = lua_touserdata(L, 1);\n  const _forWhichPlayer = lua_touserdata(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  const _facing = luaL_checknumber(L, 5);\n  console.warn('PlaceRandomUnit was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateItemPool takes nothing returns itempool\n */\nfunction CreateItemPool(C: Context, L: lua_State): number {\n\n  console.warn('CreateItemPool was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyItemPool takes itempool whichItemPool returns nothing\n */\nfunction DestroyItemPool(C: Context, L: lua_State): number {\n  const _whichItemPool = lua_touserdata(L, 1);\n  console.warn('DestroyItemPool was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ItemPoolAddItemType takes itempool whichItemPool, integer itemId, real weight returns nothing\n */\nfunction ItemPoolAddItemType(C: Context, L: lua_State): number {\n  const _whichItemPool = lua_touserdata(L, 1);\n  const _itemId = luaL_checkinteger(L, 2);\n  const _weight = luaL_checknumber(L, 3);\n  console.warn('ItemPoolAddItemType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ItemPoolRemoveItemType takes itempool whichItemPool, integer itemId returns nothing\n */\nfunction ItemPoolRemoveItemType(C: Context, L: lua_State): number {\n  const _whichItemPool = lua_touserdata(L, 1);\n  const _itemId = luaL_checkinteger(L, 2);\n  console.warn('ItemPoolRemoveItemType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlaceRandomItem takes itempool whichItemPool, real x, real y returns item\n */\nfunction PlaceRandomItem(C: Context, L: lua_State): number {\n  const _whichItemPool = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('PlaceRandomItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native ChooseRandomCreep takes integer level returns integer\n */\nfunction ChooseRandomCreep(C: Context, L: lua_State): number {\n  const _level = luaL_checkinteger(L, 1);\n  console.warn('ChooseRandomCreep was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native ChooseRandomNPBuilding takes nothing returns integer\n */\nfunction ChooseRandomNPBuilding(C: Context, L: lua_State): number {\n\n  console.warn('ChooseRandomNPBuilding was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native ChooseRandomItem takes integer level returns integer\n */\nfunction ChooseRandomItem(C: Context, L: lua_State): number {\n  const _level = luaL_checkinteger(L, 1);\n  console.warn('ChooseRandomItem was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native ChooseRandomItemEx takes itemtype whichType, integer level returns integer\n */\nfunction ChooseRandomItemEx(C: Context, L: lua_State): number {\n  const _whichType = lua_touserdata(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('ChooseRandomItemEx was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetRandomSeed takes integer seed returns nothing\n */\nfunction SetRandomSeed(C: Context, L: lua_State): number {\n  const _seed = luaL_checkinteger(L, 1);\n  console.warn('SetRandomSeed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTerrainFog takes real a, real b, real c, real d, real e returns nothing\n */\nfunction SetTerrainFog(C: Context, L: lua_State): number {\n  const _a = luaL_checknumber(L, 1);\n  const _b = luaL_checknumber(L, 2);\n  const _c = luaL_checknumber(L, 3);\n  const _d = luaL_checknumber(L, 4);\n  const _e = luaL_checknumber(L, 5);\n  console.warn('SetTerrainFog was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ResetTerrainFog takes nothing returns nothing\n */\nfunction ResetTerrainFog(_C: Context, _L: lua_State): number {\n\n  console.warn('ResetTerrainFog was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUnitFog takes real a, real b, real c, real d, real e returns nothing\n */\nfunction SetUnitFog(C: Context, L: lua_State): number {\n  const _a = luaL_checknumber(L, 1);\n  const _b = luaL_checknumber(L, 2);\n  const _c = luaL_checknumber(L, 3);\n  const _d = luaL_checknumber(L, 4);\n  const _e = luaL_checknumber(L, 5);\n  console.warn('SetUnitFog was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTerrainFogEx takes integer style, real zstart, real zend, real density, real red, real green, real blue returns nothing\n */\nfunction SetTerrainFogEx(C: Context, L: lua_State): number {\n  const _style = luaL_checkinteger(L, 1);\n  const _zstart = luaL_checknumber(L, 2);\n  const _zend = luaL_checknumber(L, 3);\n  const _density = luaL_checknumber(L, 4);\n  const _red = luaL_checknumber(L, 5);\n  const _green = luaL_checknumber(L, 6);\n  const _blue = luaL_checknumber(L, 7);\n  console.warn('SetTerrainFogEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisplayTextToPlayer takes player toPlayer, real x, real y, string message returns nothing\n */\nfunction DisplayTextToPlayer(C: Context, L: lua_State): number {\n  const _toPlayer = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _message = luaL_checkstring(L, 4);\n  console.warn('DisplayTextToPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisplayTimedTextToPlayer takes player toPlayer, real x, real y, real duration, string message returns nothing\n */\nfunction DisplayTimedTextToPlayer(C: Context, L: lua_State): number {\n  const _toPlayer = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _duration = luaL_checknumber(L, 4);\n  const _message = luaL_checkstring(L, 5);\n  console.warn('DisplayTimedTextToPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisplayTimedTextFromPlayer takes player toPlayer, real x, real y, real duration, string message returns nothing\n */\nfunction DisplayTimedTextFromPlayer(C: Context, L: lua_State): number {\n  const _toPlayer = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _duration = luaL_checknumber(L, 4);\n  const _message = luaL_checkstring(L, 5);\n  console.warn('DisplayTimedTextFromPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ClearTextMessages takes nothing returns nothing\n */\nfunction ClearTextMessages(_C: Context, _L: lua_State): number {\n\n  console.warn('ClearTextMessages was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetDayNightModels takes string terrainDNCFile, string unitDNCFile returns nothing\n */\nfunction SetDayNightModels(C: Context, L: lua_State): number {\n  const _terrainDNCFile = luaL_checkstring(L, 1);\n  const _unitDNCFile = luaL_checkstring(L, 2);\n  console.warn('SetDayNightModels was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSkyModel takes string skyModelFile returns nothing\n */\nfunction SetSkyModel(C: Context, L: lua_State): number {\n  const _skyModelFile = luaL_checkstring(L, 1);\n  console.warn('SetSkyModel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableUserControl takes boolean b returns nothing\n */\nfunction EnableUserControl(C: Context, L: lua_State): number {\n  const _b = lua_toboolean(L, 1);\n  console.warn('EnableUserControl was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableUserUI takes boolean b returns nothing\n */\nfunction EnableUserUI(C: Context, L: lua_State): number {\n  const _b = lua_toboolean(L, 1);\n  console.warn('EnableUserUI was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SuspendTimeOfDay takes boolean b returns nothing\n */\nfunction SuspendTimeOfDay(C: Context, L: lua_State): number {\n  const _b = lua_toboolean(L, 1);\n  console.warn('SuspendTimeOfDay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTimeOfDayScale takes real r returns nothing\n */\nfunction SetTimeOfDayScale(C: Context, L: lua_State): number {\n  const _r = luaL_checknumber(L, 1);\n  console.warn('SetTimeOfDayScale was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetTimeOfDayScale takes nothing returns real\n */\nfunction GetTimeOfDayScale(C: Context, L: lua_State): number {\n\n  console.warn('GetTimeOfDayScale was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native ShowInterface takes boolean flag, real fadeDuration returns nothing\n */\nfunction ShowInterface(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  const _fadeDuration = luaL_checknumber(L, 2);\n  console.warn('ShowInterface was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PauseGame takes boolean flag returns nothing\n */\nfunction PauseGame(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  console.warn('PauseGame was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnitAddIndicator takes unit whichUnit, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction UnitAddIndicator(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('UnitAddIndicator was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddIndicator takes widget whichWidget, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction AddIndicator(C: Context, L: lua_State): number {\n  const _whichWidget = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('AddIndicator was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PingMinimap takes real x, real y, real duration returns nothing\n */\nfunction PingMinimap(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  console.warn('PingMinimap was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PingMinimapEx takes real x, real y, real duration, integer red, integer green, integer blue, boolean extraEffects returns nothing\n */\nfunction PingMinimapEx(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  const _red = luaL_checkinteger(L, 4);\n  const _green = luaL_checkinteger(L, 5);\n  const _blue = luaL_checkinteger(L, 6);\n  const _extraEffects = lua_toboolean(L, 7);\n  console.warn('PingMinimapEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableOcclusion takes boolean flag returns nothing\n */\nfunction EnableOcclusion(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  console.warn('EnableOcclusion was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetIntroShotText takes string introText returns nothing\n */\nfunction SetIntroShotText(C: Context, L: lua_State): number {\n  const _introText = luaL_checkstring(L, 1);\n  console.warn('SetIntroShotText was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetIntroShotModel takes string introModelPath returns nothing\n */\nfunction SetIntroShotModel(C: Context, L: lua_State): number {\n  const _introModelPath = luaL_checkstring(L, 1);\n  console.warn('SetIntroShotModel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableWorldFogBoundary takes boolean b returns nothing\n */\nfunction EnableWorldFogBoundary(C: Context, L: lua_State): number {\n  const _b = lua_toboolean(L, 1);\n  console.warn('EnableWorldFogBoundary was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayModelCinematic takes string modelName returns nothing\n */\nfunction PlayModelCinematic(C: Context, L: lua_State): number {\n  const _modelName = luaL_checkstring(L, 1);\n  console.warn('PlayModelCinematic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayCinematic takes string movieName returns nothing\n */\nfunction PlayCinematic(C: Context, L: lua_State): number {\n  const _movieName = luaL_checkstring(L, 1);\n  console.warn('PlayCinematic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceUIKey takes string key returns nothing\n */\nfunction ForceUIKey(C: Context, L: lua_State): number {\n  const _key = luaL_checkstring(L, 1);\n  console.warn('ForceUIKey was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceUICancel takes nothing returns nothing\n */\nfunction ForceUICancel(_C: Context, _L: lua_State): number {\n\n  console.warn('ForceUICancel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisplayLoadDialog takes nothing returns nothing\n */\nfunction DisplayLoadDialog(_C: Context, _L: lua_State): number {\n\n  console.warn('DisplayLoadDialog was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetAltMinimapIcon takes string iconPath returns nothing\n */\nfunction SetAltMinimapIcon(C: Context, L: lua_State): number {\n  const _iconPath = luaL_checkstring(L, 1);\n  console.warn('SetAltMinimapIcon was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisableRestartMission takes boolean flag returns nothing\n */\nfunction DisableRestartMission(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  console.warn('DisableRestartMission was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateTextTag takes nothing returns texttag\n */\nfunction CreateTextTag(C: Context, L: lua_State): number {\n\n  console.warn('CreateTextTag was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyTextTag takes texttag t returns nothing\n */\nfunction DestroyTextTag(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  console.warn('DestroyTextTag was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagText takes texttag t, string s, real height returns nothing\n */\nfunction SetTextTagText(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _s = luaL_checkstring(L, 2);\n  const _height = luaL_checknumber(L, 3);\n  console.warn('SetTextTagText was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagPos takes texttag t, real x, real y, real heightOffset returns nothing\n */\nfunction SetTextTagPos(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _heightOffset = luaL_checknumber(L, 4);\n  console.warn('SetTextTagPos was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagPosUnit takes texttag t, unit whichUnit, real heightOffset returns nothing\n */\nfunction SetTextTagPosUnit(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  const _heightOffset = luaL_checknumber(L, 3);\n  console.warn('SetTextTagPosUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagColor takes texttag t, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction SetTextTagColor(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('SetTextTagColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagVelocity takes texttag t, real xvel, real yvel returns nothing\n */\nfunction SetTextTagVelocity(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _xvel = luaL_checknumber(L, 2);\n  const _yvel = luaL_checknumber(L, 3);\n  console.warn('SetTextTagVelocity was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagVisibility takes texttag t, boolean flag returns nothing\n */\nfunction SetTextTagVisibility(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetTextTagVisibility was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagSuspended takes texttag t, boolean flag returns nothing\n */\nfunction SetTextTagSuspended(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetTextTagSuspended was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagPermanent takes texttag t, boolean flag returns nothing\n */\nfunction SetTextTagPermanent(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetTextTagPermanent was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagAge takes texttag t, real age returns nothing\n */\nfunction SetTextTagAge(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _age = luaL_checknumber(L, 2);\n  console.warn('SetTextTagAge was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagLifespan takes texttag t, real lifespan returns nothing\n */\nfunction SetTextTagLifespan(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _lifespan = luaL_checknumber(L, 2);\n  console.warn('SetTextTagLifespan was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetTextTagFadepoint takes texttag t, real fadepoint returns nothing\n */\nfunction SetTextTagFadepoint(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  const _fadepoint = luaL_checknumber(L, 2);\n  console.warn('SetTextTagFadepoint was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetReservedLocalHeroButtons takes integer reserved returns nothing\n */\nfunction SetReservedLocalHeroButtons(C: Context, L: lua_State): number {\n  const _reserved = luaL_checkinteger(L, 1);\n  console.warn('SetReservedLocalHeroButtons was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetAllyColorFilterState takes nothing returns integer\n */\nfunction GetAllyColorFilterState(C: Context, L: lua_State): number {\n\n  console.warn('GetAllyColorFilterState was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetAllyColorFilterState takes integer state returns nothing\n */\nfunction SetAllyColorFilterState(C: Context, L: lua_State): number {\n  const _state = luaL_checkinteger(L, 1);\n  console.warn('SetAllyColorFilterState was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetCreepCampFilterState takes nothing returns boolean\n */\nfunction GetCreepCampFilterState(C: Context, L: lua_State): number {\n\n  console.warn('GetCreepCampFilterState was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetCreepCampFilterState takes boolean state returns nothing\n */\nfunction SetCreepCampFilterState(C: Context, L: lua_State): number {\n  const _state = lua_toboolean(L, 1);\n  console.warn('SetCreepCampFilterState was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableMinimapFilterButtons takes boolean enableAlly, boolean enableCreep returns nothing\n */\nfunction EnableMinimapFilterButtons(C: Context, L: lua_State): number {\n  const _enableAlly = lua_toboolean(L, 1);\n  const _enableCreep = lua_toboolean(L, 2);\n  console.warn('EnableMinimapFilterButtons was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableDragSelect takes boolean state, boolean ui returns nothing\n */\nfunction EnableDragSelect(C: Context, L: lua_State): number {\n  const _state = lua_toboolean(L, 1);\n  const _ui = lua_toboolean(L, 2);\n  console.warn('EnableDragSelect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnablePreSelect takes boolean state, boolean ui returns nothing\n */\nfunction EnablePreSelect(C: Context, L: lua_State): number {\n  const _state = lua_toboolean(L, 1);\n  const _ui = lua_toboolean(L, 2);\n  console.warn('EnablePreSelect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableSelect takes boolean state, boolean ui returns nothing\n */\nfunction EnableSelect(C: Context, L: lua_State): number {\n  const _state = lua_toboolean(L, 1);\n  const _ui = lua_toboolean(L, 2);\n  console.warn('EnableSelect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateTrackable takes string trackableModelPath, real x, real y, real facing returns trackable\n */\nfunction CreateTrackable(C: Context, L: lua_State): number {\n  const _trackableModelPath = luaL_checkstring(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _facing = luaL_checknumber(L, 4);\n  console.warn('CreateTrackable was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateQuest takes nothing returns quest\n */\nfunction CreateQuest(C: Context, L: lua_State): number {\n\n  console.warn('CreateQuest was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyQuest takes quest whichQuest returns nothing\n */\nfunction DestroyQuest(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('DestroyQuest was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetTitle takes quest whichQuest, string title returns nothing\n */\nfunction QuestSetTitle(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _title = luaL_checkstring(L, 2);\n  console.warn('QuestSetTitle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetDescription takes quest whichQuest, string description returns nothing\n */\nfunction QuestSetDescription(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _description = luaL_checkstring(L, 2);\n  console.warn('QuestSetDescription was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetIconPath takes quest whichQuest, string iconPath returns nothing\n */\nfunction QuestSetIconPath(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _iconPath = luaL_checkstring(L, 2);\n  console.warn('QuestSetIconPath was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetRequired takes quest whichQuest, boolean required returns nothing\n */\nfunction QuestSetRequired(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _required = lua_toboolean(L, 2);\n  console.warn('QuestSetRequired was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetCompleted takes quest whichQuest, boolean completed returns nothing\n */\nfunction QuestSetCompleted(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _completed = lua_toboolean(L, 2);\n  console.warn('QuestSetCompleted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetDiscovered takes quest whichQuest, boolean discovered returns nothing\n */\nfunction QuestSetDiscovered(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _discovered = lua_toboolean(L, 2);\n  console.warn('QuestSetDiscovered was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetFailed takes quest whichQuest, boolean failed returns nothing\n */\nfunction QuestSetFailed(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _failed = lua_toboolean(L, 2);\n  console.warn('QuestSetFailed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestSetEnabled takes quest whichQuest, boolean enabled returns nothing\n */\nfunction QuestSetEnabled(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  const _enabled = lua_toboolean(L, 2);\n  console.warn('QuestSetEnabled was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsQuestRequired takes quest whichQuest returns boolean\n */\nfunction IsQuestRequired(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('IsQuestRequired was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsQuestCompleted takes quest whichQuest returns boolean\n */\nfunction IsQuestCompleted(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('IsQuestCompleted was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsQuestDiscovered takes quest whichQuest returns boolean\n */\nfunction IsQuestDiscovered(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('IsQuestDiscovered was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsQuestFailed takes quest whichQuest returns boolean\n */\nfunction IsQuestFailed(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('IsQuestFailed was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsQuestEnabled takes quest whichQuest returns boolean\n */\nfunction IsQuestEnabled(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('IsQuestEnabled was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native QuestCreateItem takes quest whichQuest returns questitem\n */\nfunction QuestCreateItem(C: Context, L: lua_State): number {\n  const _whichQuest = lua_touserdata(L, 1);\n  console.warn('QuestCreateItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native QuestItemSetDescription takes questitem whichQuestItem, string description returns nothing\n */\nfunction QuestItemSetDescription(C: Context, L: lua_State): number {\n  const _whichQuestItem = lua_touserdata(L, 1);\n  const _description = luaL_checkstring(L, 2);\n  console.warn('QuestItemSetDescription was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native QuestItemSetCompleted takes questitem whichQuestItem, boolean completed returns nothing\n */\nfunction QuestItemSetCompleted(C: Context, L: lua_State): number {\n  const _whichQuestItem = lua_touserdata(L, 1);\n  const _completed = lua_toboolean(L, 2);\n  console.warn('QuestItemSetCompleted was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsQuestItemCompleted takes questitem whichQuestItem returns boolean\n */\nfunction IsQuestItemCompleted(C: Context, L: lua_State): number {\n  const _whichQuestItem = lua_touserdata(L, 1);\n  console.warn('IsQuestItemCompleted was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native CreateDefeatCondition takes nothing returns defeatcondition\n */\nfunction CreateDefeatCondition(C: Context, L: lua_State): number {\n\n  console.warn('CreateDefeatCondition was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyDefeatCondition takes defeatcondition whichCondition returns nothing\n */\nfunction DestroyDefeatCondition(C: Context, L: lua_State): number {\n  const _whichCondition = lua_touserdata(L, 1);\n  console.warn('DestroyDefeatCondition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DefeatConditionSetDescription takes defeatcondition whichCondition, string description returns nothing\n */\nfunction DefeatConditionSetDescription(C: Context, L: lua_State): number {\n  const _whichCondition = lua_touserdata(L, 1);\n  const _description = luaL_checkstring(L, 2);\n  console.warn('DefeatConditionSetDescription was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FlashQuestDialogButton takes nothing returns nothing\n */\nfunction FlashQuestDialogButton(_C: Context, _L: lua_State): number {\n\n  console.warn('FlashQuestDialogButton was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceQuestDialogUpdate takes nothing returns nothing\n */\nfunction ForceQuestDialogUpdate(_C: Context, _L: lua_State): number {\n\n  console.warn('ForceQuestDialogUpdate was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateTimerDialog takes timer t returns timerdialog\n */\nfunction CreateTimerDialog(C: Context, L: lua_State): number {\n  const _t = lua_touserdata(L, 1);\n  console.warn('CreateTimerDialog was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyTimerDialog takes timerdialog whichDialog returns nothing\n */\nfunction DestroyTimerDialog(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  console.warn('DestroyTimerDialog was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TimerDialogSetTitle takes timerdialog whichDialog, string title returns nothing\n */\nfunction TimerDialogSetTitle(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _title = luaL_checkstring(L, 2);\n  console.warn('TimerDialogSetTitle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TimerDialogSetTitleColor takes timerdialog whichDialog, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction TimerDialogSetTitleColor(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('TimerDialogSetTitleColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TimerDialogSetTimeColor takes timerdialog whichDialog, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction TimerDialogSetTimeColor(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('TimerDialogSetTimeColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TimerDialogSetSpeed takes timerdialog whichDialog, real speedMultFactor returns nothing\n */\nfunction TimerDialogSetSpeed(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _speedMultFactor = luaL_checknumber(L, 2);\n  console.warn('TimerDialogSetSpeed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TimerDialogDisplay takes timerdialog whichDialog, boolean display returns nothing\n */\nfunction TimerDialogDisplay(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _display = lua_toboolean(L, 2);\n  console.warn('TimerDialogDisplay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsTimerDialogDisplayed takes timerdialog whichDialog returns boolean\n */\nfunction IsTimerDialogDisplayed(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  console.warn('IsTimerDialogDisplayed was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native TimerDialogSetRealTimeRemaining takes timerdialog whichDialog, real timeRemaining returns nothing\n */\nfunction TimerDialogSetRealTimeRemaining(C: Context, L: lua_State): number {\n  const _whichDialog = lua_touserdata(L, 1);\n  const _timeRemaining = luaL_checknumber(L, 2);\n  console.warn('TimerDialogSetRealTimeRemaining was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateLeaderboard takes nothing returns leaderboard\n */\nfunction CreateLeaderboard(C: Context, L: lua_State): number {\n\n  console.warn('CreateLeaderboard was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyLeaderboard takes leaderboard lb returns nothing\n */\nfunction DestroyLeaderboard(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('DestroyLeaderboard was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardDisplay takes leaderboard lb, boolean show returns nothing\n */\nfunction LeaderboardDisplay(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _show = lua_toboolean(L, 2);\n  console.warn('LeaderboardDisplay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsLeaderboardDisplayed takes leaderboard lb returns boolean\n */\nfunction IsLeaderboardDisplayed(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('IsLeaderboardDisplayed was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native LeaderboardGetItemCount takes leaderboard lb returns integer\n */\nfunction LeaderboardGetItemCount(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('LeaderboardGetItemCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native LeaderboardSetSizeByItemCount takes leaderboard lb, integer count returns nothing\n */\nfunction LeaderboardSetSizeByItemCount(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _count = luaL_checkinteger(L, 2);\n  console.warn('LeaderboardSetSizeByItemCount was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardAddItem takes leaderboard lb, string label, integer value, player p returns nothing\n */\nfunction LeaderboardAddItem(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _label = luaL_checkstring(L, 2);\n  const _value = luaL_checkinteger(L, 3);\n  const _p = lua_touserdata(L, 4);\n  console.warn('LeaderboardAddItem was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardRemoveItem takes leaderboard lb, integer index returns nothing\n */\nfunction LeaderboardRemoveItem(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _index = luaL_checkinteger(L, 2);\n  console.warn('LeaderboardRemoveItem was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardRemovePlayerItem takes leaderboard lb, player p returns nothing\n */\nfunction LeaderboardRemovePlayerItem(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _p = lua_touserdata(L, 2);\n  console.warn('LeaderboardRemovePlayerItem was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardClear takes leaderboard lb returns nothing\n */\nfunction LeaderboardClear(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('LeaderboardClear was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSortItemsByValue takes leaderboard lb, boolean ascending returns nothing\n */\nfunction LeaderboardSortItemsByValue(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _ascending = lua_toboolean(L, 2);\n  console.warn('LeaderboardSortItemsByValue was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSortItemsByPlayer takes leaderboard lb, boolean ascending returns nothing\n */\nfunction LeaderboardSortItemsByPlayer(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _ascending = lua_toboolean(L, 2);\n  console.warn('LeaderboardSortItemsByPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSortItemsByLabel takes leaderboard lb, boolean ascending returns nothing\n */\nfunction LeaderboardSortItemsByLabel(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _ascending = lua_toboolean(L, 2);\n  console.warn('LeaderboardSortItemsByLabel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardHasPlayerItem takes leaderboard lb, player p returns boolean\n */\nfunction LeaderboardHasPlayerItem(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _p = lua_touserdata(L, 2);\n  console.warn('LeaderboardHasPlayerItem was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native LeaderboardGetPlayerIndex takes leaderboard lb, player p returns integer\n */\nfunction LeaderboardGetPlayerIndex(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _p = lua_touserdata(L, 2);\n  console.warn('LeaderboardGetPlayerIndex was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native LeaderboardSetLabel takes leaderboard lb, string label returns nothing\n */\nfunction LeaderboardSetLabel(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _label = luaL_checkstring(L, 2);\n  console.warn('LeaderboardSetLabel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardGetLabelText takes leaderboard lb returns string\n */\nfunction LeaderboardGetLabelText(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('LeaderboardGetLabelText was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native PlayerSetLeaderboard takes player toPlayer, leaderboard lb returns nothing\n */\nfunction PlayerSetLeaderboard(C: Context, L: lua_State): number {\n  const _toPlayer = lua_touserdata(L, 1);\n  const _lb = lua_touserdata(L, 2);\n  console.warn('PlayerSetLeaderboard was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayerGetLeaderboard takes player toPlayer returns leaderboard\n */\nfunction PlayerGetLeaderboard(C: Context, L: lua_State): number {\n  const _toPlayer = lua_touserdata(L, 1);\n  console.warn('PlayerGetLeaderboard was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native LeaderboardSetLabelColor takes leaderboard lb, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction LeaderboardSetLabelColor(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('LeaderboardSetLabelColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetValueColor takes leaderboard lb, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction LeaderboardSetValueColor(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('LeaderboardSetValueColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetStyle takes leaderboard lb, boolean showLabel, boolean showNames, boolean showValues, boolean showIcons returns nothing\n */\nfunction LeaderboardSetStyle(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _showLabel = lua_toboolean(L, 2);\n  const _showNames = lua_toboolean(L, 3);\n  const _showValues = lua_toboolean(L, 4);\n  const _showIcons = lua_toboolean(L, 5);\n  console.warn('LeaderboardSetStyle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetItemValue takes leaderboard lb, integer whichItem, integer val returns nothing\n */\nfunction LeaderboardSetItemValue(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _whichItem = luaL_checkinteger(L, 2);\n  const _val = luaL_checkinteger(L, 3);\n  console.warn('LeaderboardSetItemValue was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetItemLabel takes leaderboard lb, integer whichItem, string val returns nothing\n */\nfunction LeaderboardSetItemLabel(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _whichItem = luaL_checkinteger(L, 2);\n  const _val = luaL_checkstring(L, 3);\n  console.warn('LeaderboardSetItemLabel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetItemStyle takes leaderboard lb, integer whichItem, boolean showLabel, boolean showValue, boolean showIcon returns nothing\n */\nfunction LeaderboardSetItemStyle(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _whichItem = luaL_checkinteger(L, 2);\n  const _showLabel = lua_toboolean(L, 3);\n  const _showValue = lua_toboolean(L, 4);\n  const _showIcon = lua_toboolean(L, 5);\n  console.warn('LeaderboardSetItemStyle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetItemLabelColor takes leaderboard lb, integer whichItem, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction LeaderboardSetItemLabelColor(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _whichItem = luaL_checkinteger(L, 2);\n  const _red = luaL_checkinteger(L, 3);\n  const _green = luaL_checkinteger(L, 4);\n  const _blue = luaL_checkinteger(L, 5);\n  const _alpha = luaL_checkinteger(L, 6);\n  console.warn('LeaderboardSetItemLabelColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native LeaderboardSetItemValueColor takes leaderboard lb, integer whichItem, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction LeaderboardSetItemValueColor(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _whichItem = luaL_checkinteger(L, 2);\n  const _red = luaL_checkinteger(L, 3);\n  const _green = luaL_checkinteger(L, 4);\n  const _blue = luaL_checkinteger(L, 5);\n  const _alpha = luaL_checkinteger(L, 6);\n  console.warn('LeaderboardSetItemValueColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateMultiboard takes nothing returns multiboard\n */\nfunction CreateMultiboard(C: Context, L: lua_State): number {\n\n  console.warn('CreateMultiboard was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyMultiboard takes multiboard lb returns nothing\n */\nfunction DestroyMultiboard(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('DestroyMultiboard was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardDisplay takes multiboard lb, boolean show returns nothing\n */\nfunction MultiboardDisplay(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _show = lua_toboolean(L, 2);\n  console.warn('MultiboardDisplay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsMultiboardDisplayed takes multiboard lb returns boolean\n */\nfunction IsMultiboardDisplayed(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('IsMultiboardDisplayed was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native MultiboardMinimize takes multiboard lb, boolean minimize returns nothing\n */\nfunction MultiboardMinimize(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _minimize = lua_toboolean(L, 2);\n  console.warn('MultiboardMinimize was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsMultiboardMinimized takes multiboard lb returns boolean\n */\nfunction IsMultiboardMinimized(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('IsMultiboardMinimized was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native MultiboardClear takes multiboard lb returns nothing\n */\nfunction MultiboardClear(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('MultiboardClear was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetTitleText takes multiboard lb, string label returns nothing\n */\nfunction MultiboardSetTitleText(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _label = luaL_checkstring(L, 2);\n  console.warn('MultiboardSetTitleText was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardGetTitleText takes multiboard lb returns string\n */\nfunction MultiboardGetTitleText(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('MultiboardGetTitleText was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native MultiboardSetTitleTextColor takes multiboard lb, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction MultiboardSetTitleTextColor(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('MultiboardSetTitleTextColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardGetRowCount takes multiboard lb returns integer\n */\nfunction MultiboardGetRowCount(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('MultiboardGetRowCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native MultiboardGetColumnCount takes multiboard lb returns integer\n */\nfunction MultiboardGetColumnCount(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  console.warn('MultiboardGetColumnCount was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native MultiboardSetColumnCount takes multiboard lb, integer count returns nothing\n */\nfunction MultiboardSetColumnCount(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _count = luaL_checkinteger(L, 2);\n  console.warn('MultiboardSetColumnCount was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetRowCount takes multiboard lb, integer count returns nothing\n */\nfunction MultiboardSetRowCount(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _count = luaL_checkinteger(L, 2);\n  console.warn('MultiboardSetRowCount was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemsStyle takes multiboard lb, boolean showValues, boolean showIcons returns nothing\n */\nfunction MultiboardSetItemsStyle(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _showValues = lua_toboolean(L, 2);\n  const _showIcons = lua_toboolean(L, 3);\n  console.warn('MultiboardSetItemsStyle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemsValue takes multiboard lb, string value returns nothing\n */\nfunction MultiboardSetItemsValue(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _value = luaL_checkstring(L, 2);\n  console.warn('MultiboardSetItemsValue was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemsValueColor takes multiboard lb, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction MultiboardSetItemsValueColor(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('MultiboardSetItemsValueColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemsWidth takes multiboard lb, real width returns nothing\n */\nfunction MultiboardSetItemsWidth(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _width = luaL_checknumber(L, 2);\n  console.warn('MultiboardSetItemsWidth was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemsIcon takes multiboard lb, string iconPath returns nothing\n */\nfunction MultiboardSetItemsIcon(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _iconPath = luaL_checkstring(L, 2);\n  console.warn('MultiboardSetItemsIcon was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardGetItem takes multiboard lb, integer row, integer column returns multiboarditem\n */\nfunction MultiboardGetItem(C: Context, L: lua_State): number {\n  const _lb = lua_touserdata(L, 1);\n  const _row = luaL_checkinteger(L, 2);\n  const _column = luaL_checkinteger(L, 3);\n  console.warn('MultiboardGetItem was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native MultiboardReleaseItem takes multiboarditem mbi returns nothing\n */\nfunction MultiboardReleaseItem(C: Context, L: lua_State): number {\n  const _mbi = lua_touserdata(L, 1);\n  console.warn('MultiboardReleaseItem was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemStyle takes multiboarditem mbi, boolean showValue, boolean showIcon returns nothing\n */\nfunction MultiboardSetItemStyle(C: Context, L: lua_State): number {\n  const _mbi = lua_touserdata(L, 1);\n  const _showValue = lua_toboolean(L, 2);\n  const _showIcon = lua_toboolean(L, 3);\n  console.warn('MultiboardSetItemStyle was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemValue takes multiboarditem mbi, string val returns nothing\n */\nfunction MultiboardSetItemValue(C: Context, L: lua_State): number {\n  const _mbi = lua_touserdata(L, 1);\n  const _val = luaL_checkstring(L, 2);\n  console.warn('MultiboardSetItemValue was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemValueColor takes multiboarditem mbi, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction MultiboardSetItemValueColor(C: Context, L: lua_State): number {\n  const _mbi = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('MultiboardSetItemValueColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemWidth takes multiboarditem mbi, real width returns nothing\n */\nfunction MultiboardSetItemWidth(C: Context, L: lua_State): number {\n  const _mbi = lua_touserdata(L, 1);\n  const _width = luaL_checknumber(L, 2);\n  console.warn('MultiboardSetItemWidth was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSetItemIcon takes multiboarditem mbi, string iconFileName returns nothing\n */\nfunction MultiboardSetItemIcon(C: Context, L: lua_State): number {\n  const _mbi = lua_touserdata(L, 1);\n  const _iconFileName = luaL_checkstring(L, 2);\n  console.warn('MultiboardSetItemIcon was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native MultiboardSuppressDisplay takes boolean flag returns nothing\n */\nfunction MultiboardSuppressDisplay(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  console.warn('MultiboardSuppressDisplay was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraPosition takes real x, real y returns nothing\n */\nfunction SetCameraPosition(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('SetCameraPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraQuickPosition takes real x, real y returns nothing\n */\nfunction SetCameraQuickPosition(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('SetCameraQuickPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraBounds takes real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4 returns nothing\n */\nfunction SetCameraBounds(C: Context, L: lua_State): number {\n  const _x1 = luaL_checknumber(L, 1);\n  const _y1 = luaL_checknumber(L, 2);\n  const _x2 = luaL_checknumber(L, 3);\n  const _y2 = luaL_checknumber(L, 4);\n  const _x3 = luaL_checknumber(L, 5);\n  const _y3 = luaL_checknumber(L, 6);\n  const _x4 = luaL_checknumber(L, 7);\n  const _y4 = luaL_checknumber(L, 8);\n  console.warn('SetCameraBounds was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StopCamera takes nothing returns nothing\n */\nfunction StopCamera(_C: Context, _L: lua_State): number {\n\n  console.warn('StopCamera was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ResetToGameCamera takes real duration returns nothing\n */\nfunction ResetToGameCamera(C: Context, L: lua_State): number {\n  const _duration = luaL_checknumber(L, 1);\n  console.warn('ResetToGameCamera was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PanCameraTo takes real x, real y returns nothing\n */\nfunction PanCameraTo(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('PanCameraTo was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PanCameraToTimed takes real x, real y, real duration returns nothing\n */\nfunction PanCameraToTimed(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  console.warn('PanCameraToTimed was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PanCameraToWithZ takes real x, real y, real zOffsetDest returns nothing\n */\nfunction PanCameraToWithZ(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _zOffsetDest = luaL_checknumber(L, 3);\n  console.warn('PanCameraToWithZ was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PanCameraToTimedWithZ takes real x, real y, real zOffsetDest, real duration returns nothing\n */\nfunction PanCameraToTimedWithZ(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _zOffsetDest = luaL_checknumber(L, 3);\n  const _duration = luaL_checknumber(L, 4);\n  console.warn('PanCameraToTimedWithZ was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCinematicCamera takes string cameraModelFile returns nothing\n */\nfunction SetCinematicCamera(C: Context, L: lua_State): number {\n  const _cameraModelFile = luaL_checkstring(L, 1);\n  console.warn('SetCinematicCamera was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraRotateMode takes real x, real y, real radiansToSweep, real duration returns nothing\n */\nfunction SetCameraRotateMode(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _radiansToSweep = luaL_checknumber(L, 3);\n  const _duration = luaL_checknumber(L, 4);\n  console.warn('SetCameraRotateMode was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraField takes camerafield whichField, real value, real duration returns nothing\n */\nfunction SetCameraField(C: Context, L: lua_State): number {\n  const _whichField = lua_touserdata(L, 1);\n  const _value = luaL_checknumber(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  console.warn('SetCameraField was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AdjustCameraField takes camerafield whichField, real offset, real duration returns nothing\n */\nfunction AdjustCameraField(C: Context, L: lua_State): number {\n  const _whichField = lua_touserdata(L, 1);\n  const _offset = luaL_checknumber(L, 2);\n  const _duration = luaL_checknumber(L, 3);\n  console.warn('AdjustCameraField was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraTargetController takes unit whichUnit, real xoffset, real yoffset, boolean inheritOrientation returns nothing\n */\nfunction SetCameraTargetController(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _xoffset = luaL_checknumber(L, 2);\n  const _yoffset = luaL_checknumber(L, 3);\n  const _inheritOrientation = lua_toboolean(L, 4);\n  console.warn('SetCameraTargetController was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCameraOrientController takes unit whichUnit, real xoffset, real yoffset returns nothing\n */\nfunction SetCameraOrientController(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _xoffset = luaL_checknumber(L, 2);\n  const _yoffset = luaL_checknumber(L, 3);\n  console.warn('SetCameraOrientController was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateCameraSetup takes nothing returns camerasetup\n */\nfunction CreateCameraSetup(C: Context, L: lua_State): number {\n\n  console.warn('CreateCameraSetup was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CameraSetupSetField takes camerasetup whichSetup, camerafield whichField, real value, real duration returns nothing\n */\nfunction CameraSetupSetField(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _whichField = lua_touserdata(L, 2);\n  const _value = luaL_checknumber(L, 3);\n  const _duration = luaL_checknumber(L, 4);\n  console.warn('CameraSetupSetField was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetupGetField takes camerasetup whichSetup, camerafield whichField returns real\n */\nfunction CameraSetupGetField(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _whichField = lua_touserdata(L, 2);\n  console.warn('CameraSetupGetField was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native CameraSetupSetDestPosition takes camerasetup whichSetup, real x, real y, real duration returns nothing\n */\nfunction CameraSetupSetDestPosition(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _duration = luaL_checknumber(L, 4);\n  console.warn('CameraSetupSetDestPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetupGetDestPositionLoc takes camerasetup whichSetup returns location\n */\nfunction CameraSetupGetDestPositionLoc(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  console.warn('CameraSetupGetDestPositionLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CameraSetupGetDestPositionX takes camerasetup whichSetup returns real\n */\nfunction CameraSetupGetDestPositionX(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  console.warn('CameraSetupGetDestPositionX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native CameraSetupGetDestPositionY takes camerasetup whichSetup returns real\n */\nfunction CameraSetupGetDestPositionY(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  console.warn('CameraSetupGetDestPositionY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native CameraSetupApply takes camerasetup whichSetup, boolean doPan, boolean panTimed returns nothing\n */\nfunction CameraSetupApply(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _doPan = lua_toboolean(L, 2);\n  const _panTimed = lua_toboolean(L, 3);\n  console.warn('CameraSetupApply was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetupApplyWithZ takes camerasetup whichSetup, real zDestOffset returns nothing\n */\nfunction CameraSetupApplyWithZ(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _zDestOffset = luaL_checknumber(L, 2);\n  console.warn('CameraSetupApplyWithZ was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetupApplyForceDuration takes camerasetup whichSetup, boolean doPan, real forceDuration returns nothing\n */\nfunction CameraSetupApplyForceDuration(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _doPan = lua_toboolean(L, 2);\n  const _forceDuration = luaL_checknumber(L, 3);\n  console.warn('CameraSetupApplyForceDuration was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetupApplyForceDurationWithZ takes camerasetup whichSetup, real zDestOffset, real forceDuration returns nothing\n */\nfunction CameraSetupApplyForceDurationWithZ(C: Context, L: lua_State): number {\n  const _whichSetup = lua_touserdata(L, 1);\n  const _zDestOffset = luaL_checknumber(L, 2);\n  const _forceDuration = luaL_checknumber(L, 3);\n  console.warn('CameraSetupApplyForceDurationWithZ was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetTargetNoise takes real mag, real velocity returns nothing\n */\nfunction CameraSetTargetNoise(C: Context, L: lua_State): number {\n  const _mag = luaL_checknumber(L, 1);\n  const _velocity = luaL_checknumber(L, 2);\n  console.warn('CameraSetTargetNoise was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetSourceNoise takes real mag, real velocity returns nothing\n */\nfunction CameraSetSourceNoise(C: Context, L: lua_State): number {\n  const _mag = luaL_checknumber(L, 1);\n  const _velocity = luaL_checknumber(L, 2);\n  console.warn('CameraSetSourceNoise was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetTargetNoiseEx takes real mag, real velocity, boolean vertOnly returns nothing\n */\nfunction CameraSetTargetNoiseEx(C: Context, L: lua_State): number {\n  const _mag = luaL_checknumber(L, 1);\n  const _velocity = luaL_checknumber(L, 2);\n  const _vertOnly = lua_toboolean(L, 3);\n  console.warn('CameraSetTargetNoiseEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetSourceNoiseEx takes real mag, real velocity, boolean vertOnly returns nothing\n */\nfunction CameraSetSourceNoiseEx(C: Context, L: lua_State): number {\n  const _mag = luaL_checknumber(L, 1);\n  const _velocity = luaL_checknumber(L, 2);\n  const _vertOnly = lua_toboolean(L, 3);\n  console.warn('CameraSetSourceNoiseEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CameraSetSmoothingFactor takes real factor returns nothing\n */\nfunction CameraSetSmoothingFactor(C: Context, L: lua_State): number {\n  const _factor = luaL_checknumber(L, 1);\n  console.warn('CameraSetSmoothingFactor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterTexture takes string filename returns nothing\n */\nfunction SetCineFilterTexture(C: Context, L: lua_State): number {\n  const _filename = luaL_checkstring(L, 1);\n  console.warn('SetCineFilterTexture was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterBlendMode takes blendmode whichMode returns nothing\n */\nfunction SetCineFilterBlendMode(C: Context, L: lua_State): number {\n  const _whichMode = lua_touserdata(L, 1);\n  console.warn('SetCineFilterBlendMode was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterTexMapFlags takes texmapflags whichFlags returns nothing\n */\nfunction SetCineFilterTexMapFlags(C: Context, L: lua_State): number {\n  const _whichFlags = lua_touserdata(L, 1);\n  console.warn('SetCineFilterTexMapFlags was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterStartUV takes real minu, real minv, real maxu, real maxv returns nothing\n */\nfunction SetCineFilterStartUV(C: Context, L: lua_State): number {\n  const _minu = luaL_checknumber(L, 1);\n  const _minv = luaL_checknumber(L, 2);\n  const _maxu = luaL_checknumber(L, 3);\n  const _maxv = luaL_checknumber(L, 4);\n  console.warn('SetCineFilterStartUV was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterEndUV takes real minu, real minv, real maxu, real maxv returns nothing\n */\nfunction SetCineFilterEndUV(C: Context, L: lua_State): number {\n  const _minu = luaL_checknumber(L, 1);\n  const _minv = luaL_checknumber(L, 2);\n  const _maxu = luaL_checknumber(L, 3);\n  const _maxv = luaL_checknumber(L, 4);\n  console.warn('SetCineFilterEndUV was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterStartColor takes integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction SetCineFilterStartColor(C: Context, L: lua_State): number {\n  const _red = luaL_checkinteger(L, 1);\n  const _green = luaL_checkinteger(L, 2);\n  const _blue = luaL_checkinteger(L, 3);\n  const _alpha = luaL_checkinteger(L, 4);\n  console.warn('SetCineFilterStartColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterEndColor takes integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction SetCineFilterEndColor(C: Context, L: lua_State): number {\n  const _red = luaL_checkinteger(L, 1);\n  const _green = luaL_checkinteger(L, 2);\n  const _blue = luaL_checkinteger(L, 3);\n  const _alpha = luaL_checkinteger(L, 4);\n  console.warn('SetCineFilterEndColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetCineFilterDuration takes real duration returns nothing\n */\nfunction SetCineFilterDuration(C: Context, L: lua_State): number {\n  const _duration = luaL_checknumber(L, 1);\n  console.warn('SetCineFilterDuration was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native DisplayCineFilter takes boolean flag returns nothing\n */\nfunction DisplayCineFilter(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  console.warn('DisplayCineFilter was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsCineFilterDisplayed takes nothing returns boolean\n */\nfunction IsCineFilterDisplayed(C: Context, L: lua_State): number {\n\n  console.warn('IsCineFilterDisplayed was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetCinematicScene takes integer portraitUnitId, playercolor color, string speakerTitle, string text, real sceneDuration, real voiceoverDuration returns nothing\n */\nfunction SetCinematicScene(C: Context, L: lua_State): number {\n  const _portraitUnitId = luaL_checkinteger(L, 1);\n  const _color = lua_touserdata(L, 2);\n  const _speakerTitle = luaL_checkstring(L, 3);\n  const _text = luaL_checkstring(L, 4);\n  const _sceneDuration = luaL_checknumber(L, 5);\n  const _voiceoverDuration = luaL_checknumber(L, 6);\n  console.warn('SetCinematicScene was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EndCinematicScene takes nothing returns nothing\n */\nfunction EndCinematicScene(_C: Context, _L: lua_State): number {\n\n  console.warn('EndCinematicScene was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ForceCinematicSubtitles takes boolean flag returns nothing\n */\nfunction ForceCinematicSubtitles(C: Context, L: lua_State): number {\n  const _flag = lua_toboolean(L, 1);\n  console.warn('ForceCinematicSubtitles was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetCameraMargin takes integer whichMargin returns real\n */\nfunction GetCameraMargin(C: Context, L: lua_State): number {\n  const _whichMargin = luaL_checkinteger(L, 1);\n  console.warn('GetCameraMargin was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraBoundMinX takes nothing returns real\n */\nfunction GetCameraBoundMinX(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraBoundMinX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraBoundMinY takes nothing returns real\n */\nfunction GetCameraBoundMinY(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraBoundMinY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraBoundMaxX takes nothing returns real\n */\nfunction GetCameraBoundMaxX(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraBoundMaxX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraBoundMaxY takes nothing returns real\n */\nfunction GetCameraBoundMaxY(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraBoundMaxY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraField takes camerafield whichField returns real\n */\nfunction GetCameraField(C: Context, L: lua_State): number {\n  const _whichField = lua_touserdata(L, 1);\n  console.warn('GetCameraField was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraTargetPositionX takes nothing returns real\n */\nfunction GetCameraTargetPositionX(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraTargetPositionX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraTargetPositionY takes nothing returns real\n */\nfunction GetCameraTargetPositionY(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraTargetPositionY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraTargetPositionZ takes nothing returns real\n */\nfunction GetCameraTargetPositionZ(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraTargetPositionZ was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraTargetPositionLoc takes nothing returns location\n */\nfunction GetCameraTargetPositionLoc(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraTargetPositionLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * constant native GetCameraEyePositionX takes nothing returns real\n */\nfunction GetCameraEyePositionX(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraEyePositionX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraEyePositionY takes nothing returns real\n */\nfunction GetCameraEyePositionY(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraEyePositionY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraEyePositionZ takes nothing returns real\n */\nfunction GetCameraEyePositionZ(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraEyePositionZ was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * constant native GetCameraEyePositionLoc takes nothing returns location\n */\nfunction GetCameraEyePositionLoc(C: Context, L: lua_State): number {\n\n  console.warn('GetCameraEyePositionLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native NewSoundEnvironment takes string environmentName returns nothing\n */\nfunction NewSoundEnvironment(C: Context, L: lua_State): number {\n  const _environmentName = luaL_checkstring(L, 1);\n  console.warn('NewSoundEnvironment was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateSound takes string fileName, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate, string eaxSetting returns sound\n */\nfunction CreateSound(C: Context, L: lua_State): number {\n  const _fileName = luaL_checkstring(L, 1);\n  const _looping = lua_toboolean(L, 2);\n  const _is3D = lua_toboolean(L, 3);\n  const _stopwhenoutofrange = lua_toboolean(L, 4);\n  const _fadeInRate = luaL_checkinteger(L, 5);\n  const _fadeOutRate = luaL_checkinteger(L, 6);\n  const _eaxSetting = luaL_checkstring(L, 7);\n  console.warn('CreateSound was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateSoundFilenameWithLabel takes string fileName, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate, string SLKEntryName returns sound\n */\nfunction CreateSoundFilenameWithLabel(C: Context, L: lua_State): number {\n  const _fileName = luaL_checkstring(L, 1);\n  const _looping = lua_toboolean(L, 2);\n  const _is3D = lua_toboolean(L, 3);\n  const _stopwhenoutofrange = lua_toboolean(L, 4);\n  const _fadeInRate = luaL_checkinteger(L, 5);\n  const _fadeOutRate = luaL_checkinteger(L, 6);\n  const _SLKEntryName = luaL_checkstring(L, 7);\n  console.warn('CreateSoundFilenameWithLabel was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateSoundFromLabel takes string soundLabel, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate returns sound\n */\nfunction CreateSoundFromLabel(C: Context, L: lua_State): number {\n  const _soundLabel = luaL_checkstring(L, 1);\n  const _looping = lua_toboolean(L, 2);\n  const _is3D = lua_toboolean(L, 3);\n  const _stopwhenoutofrange = lua_toboolean(L, 4);\n  const _fadeInRate = luaL_checkinteger(L, 5);\n  const _fadeOutRate = luaL_checkinteger(L, 6);\n  console.warn('CreateSoundFromLabel was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native CreateMIDISound takes string soundLabel, integer fadeInRate, integer fadeOutRate returns sound\n */\nfunction CreateMIDISound(C: Context, L: lua_State): number {\n  const _soundLabel = luaL_checkstring(L, 1);\n  const _fadeInRate = luaL_checkinteger(L, 2);\n  const _fadeOutRate = luaL_checkinteger(L, 3);\n  console.warn('CreateMIDISound was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native SetSoundParamsFromLabel takes sound soundHandle, string soundLabel returns nothing\n */\nfunction SetSoundParamsFromLabel(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _soundLabel = luaL_checkstring(L, 2);\n  console.warn('SetSoundParamsFromLabel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundDistanceCutoff takes sound soundHandle, real cutoff returns nothing\n */\nfunction SetSoundDistanceCutoff(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _cutoff = luaL_checknumber(L, 2);\n  console.warn('SetSoundDistanceCutoff was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundChannel takes sound soundHandle, integer channel returns nothing\n */\nfunction SetSoundChannel(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _channel = luaL_checkinteger(L, 2);\n  console.warn('SetSoundChannel was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundVolume takes sound soundHandle, integer volume returns nothing\n */\nfunction SetSoundVolume(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _volume = luaL_checkinteger(L, 2);\n  console.warn('SetSoundVolume was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundPitch takes sound soundHandle, real pitch returns nothing\n */\nfunction SetSoundPitch(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _pitch = luaL_checknumber(L, 2);\n  console.warn('SetSoundPitch was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundPlayPosition takes sound soundHandle, integer millisecs returns nothing\n */\nfunction SetSoundPlayPosition(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _millisecs = luaL_checkinteger(L, 2);\n  console.warn('SetSoundPlayPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundDistances takes sound soundHandle, real minDist, real maxDist returns nothing\n */\nfunction SetSoundDistances(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _minDist = luaL_checknumber(L, 2);\n  const _maxDist = luaL_checknumber(L, 3);\n  console.warn('SetSoundDistances was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundConeAngles takes sound soundHandle, real inside, real outside, integer outsideVolume returns nothing\n */\nfunction SetSoundConeAngles(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _inside = luaL_checknumber(L, 2);\n  const _outside = luaL_checknumber(L, 3);\n  const _outsideVolume = luaL_checkinteger(L, 4);\n  console.warn('SetSoundConeAngles was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundConeOrientation takes sound soundHandle, real x, real y, real z returns nothing\n */\nfunction SetSoundConeOrientation(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  console.warn('SetSoundConeOrientation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundPosition takes sound soundHandle, real x, real y, real z returns nothing\n */\nfunction SetSoundPosition(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  console.warn('SetSoundPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundVelocity takes sound soundHandle, real x, real y, real z returns nothing\n */\nfunction SetSoundVelocity(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  console.warn('SetSoundVelocity was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AttachSoundToUnit takes sound soundHandle, unit whichUnit returns nothing\n */\nfunction AttachSoundToUnit(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _whichUnit = lua_touserdata(L, 2);\n  console.warn('AttachSoundToUnit was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StartSound takes sound soundHandle returns nothing\n */\nfunction StartSound(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  console.warn('StartSound was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StopSound takes sound soundHandle, boolean killWhenDone, boolean fadeOut returns nothing\n */\nfunction StopSound(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _killWhenDone = lua_toboolean(L, 2);\n  const _fadeOut = lua_toboolean(L, 3);\n  console.warn('StopSound was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native KillSoundWhenDone takes sound soundHandle returns nothing\n */\nfunction KillSoundWhenDone(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  console.warn('KillSoundWhenDone was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetMapMusic takes string musicName, boolean random, integer index returns nothing\n */\nfunction SetMapMusic(C: Context, L: lua_State): number {\n  const _musicName = luaL_checkstring(L, 1);\n  const _random = lua_toboolean(L, 2);\n  const _index = luaL_checkinteger(L, 3);\n  console.warn('SetMapMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ClearMapMusic takes nothing returns nothing\n */\nfunction ClearMapMusic(_C: Context, _L: lua_State): number {\n\n  console.warn('ClearMapMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayMusic takes string musicName returns nothing\n */\nfunction PlayMusic(C: Context, L: lua_State): number {\n  const _musicName = luaL_checkstring(L, 1);\n  console.warn('PlayMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayMusicEx takes string musicName, integer frommsecs, integer fadeinmsecs returns nothing\n */\nfunction PlayMusicEx(C: Context, L: lua_State): number {\n  const _musicName = luaL_checkstring(L, 1);\n  const _frommsecs = luaL_checkinteger(L, 2);\n  const _fadeinmsecs = luaL_checkinteger(L, 3);\n  console.warn('PlayMusicEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StopMusic takes boolean fadeOut returns nothing\n */\nfunction StopMusic(C: Context, L: lua_State): number {\n  const _fadeOut = lua_toboolean(L, 1);\n  console.warn('StopMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ResumeMusic takes nothing returns nothing\n */\nfunction ResumeMusic(_C: Context, _L: lua_State): number {\n\n  console.warn('ResumeMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayThematicMusic takes string musicFileName returns nothing\n */\nfunction PlayThematicMusic(C: Context, L: lua_State): number {\n  const _musicFileName = luaL_checkstring(L, 1);\n  console.warn('PlayThematicMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PlayThematicMusicEx takes string musicFileName, integer frommsecs returns nothing\n */\nfunction PlayThematicMusicEx(C: Context, L: lua_State): number {\n  const _musicFileName = luaL_checkstring(L, 1);\n  const _frommsecs = luaL_checkinteger(L, 2);\n  console.warn('PlayThematicMusicEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EndThematicMusic takes nothing returns nothing\n */\nfunction EndThematicMusic(_C: Context, _L: lua_State): number {\n\n  console.warn('EndThematicMusic was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetMusicVolume takes integer volume returns nothing\n */\nfunction SetMusicVolume(C: Context, L: lua_State): number {\n  const _volume = luaL_checkinteger(L, 1);\n  console.warn('SetMusicVolume was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetMusicPlayPosition takes integer millisecs returns nothing\n */\nfunction SetMusicPlayPosition(C: Context, L: lua_State): number {\n  const _millisecs = luaL_checkinteger(L, 1);\n  console.warn('SetMusicPlayPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetThematicMusicPlayPosition takes integer millisecs returns nothing\n */\nfunction SetThematicMusicPlayPosition(C: Context, L: lua_State): number {\n  const _millisecs = luaL_checkinteger(L, 1);\n  console.warn('SetThematicMusicPlayPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetSoundDuration takes sound soundHandle, integer duration returns nothing\n */\nfunction SetSoundDuration(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _duration = luaL_checkinteger(L, 2);\n  console.warn('SetSoundDuration was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetSoundDuration takes sound soundHandle returns integer\n */\nfunction GetSoundDuration(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  console.warn('GetSoundDuration was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetSoundFileDuration takes string musicFileName returns integer\n */\nfunction GetSoundFileDuration(C: Context, L: lua_State): number {\n  const _musicFileName = luaL_checkstring(L, 1);\n  console.warn('GetSoundFileDuration was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native VolumeGroupSetVolume takes volumegroup vgroup, real scale returns nothing\n */\nfunction VolumeGroupSetVolume(C: Context, L: lua_State): number {\n  const _vgroup = lua_touserdata(L, 1);\n  const _scale = luaL_checknumber(L, 2);\n  console.warn('VolumeGroupSetVolume was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native VolumeGroupReset takes nothing returns nothing\n */\nfunction VolumeGroupReset(_C: Context, _L: lua_State): number {\n\n  console.warn('VolumeGroupReset was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetSoundIsPlaying takes sound soundHandle returns boolean\n */\nfunction GetSoundIsPlaying(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  console.warn('GetSoundIsPlaying was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetSoundIsLoading takes sound soundHandle returns boolean\n */\nfunction GetSoundIsLoading(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  console.warn('GetSoundIsLoading was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native RegisterStackedSound takes sound soundHandle, boolean byPosition, real rectwidth, real rectheight returns nothing\n */\nfunction RegisterStackedSound(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _byPosition = lua_toboolean(L, 2);\n  const _rectwidth = luaL_checknumber(L, 3);\n  const _rectheight = luaL_checknumber(L, 4);\n  console.warn('RegisterStackedSound was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native UnregisterStackedSound takes sound soundHandle, boolean byPosition, real rectwidth, real rectheight returns nothing\n */\nfunction UnregisterStackedSound(C: Context, L: lua_State): number {\n  const _soundHandle = lua_touserdata(L, 1);\n  const _byPosition = lua_toboolean(L, 2);\n  const _rectwidth = luaL_checknumber(L, 3);\n  const _rectheight = luaL_checknumber(L, 4);\n  console.warn('UnregisterStackedSound was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddWeatherEffect takes rect where, integer effectID returns weathereffect\n */\nfunction AddWeatherEffect(C: Context, L: lua_State): number {\n  const _where = lua_touserdata(L, 1);\n  const _effectID = luaL_checkinteger(L, 2);\n  console.warn('AddWeatherEffect was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveWeatherEffect takes weathereffect whichEffect returns nothing\n */\nfunction RemoveWeatherEffect(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  console.warn('RemoveWeatherEffect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native EnableWeatherEffect takes weathereffect whichEffect, boolean enable returns nothing\n */\nfunction EnableWeatherEffect(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _enable = lua_toboolean(L, 2);\n  console.warn('EnableWeatherEffect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TerrainDeformCrater takes real x, real y, real radius, real depth, integer duration, boolean permanent returns terraindeformation\n */\nfunction TerrainDeformCrater(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _depth = luaL_checknumber(L, 4);\n  const _duration = luaL_checkinteger(L, 5);\n  const _permanent = lua_toboolean(L, 6);\n  console.warn('TerrainDeformCrater was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TerrainDeformRipple takes real x, real y, real radius, real depth, integer duration, integer count, real spaceWaves, real timeWaves, real radiusStartPct, boolean limitNeg returns terraindeformation\n */\nfunction TerrainDeformRipple(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _depth = luaL_checknumber(L, 4);\n  const _duration = luaL_checkinteger(L, 5);\n  const _count = luaL_checkinteger(L, 6);\n  const _spaceWaves = luaL_checknumber(L, 7);\n  const _timeWaves = luaL_checknumber(L, 8);\n  const _radiusStartPct = luaL_checknumber(L, 9);\n  const _limitNeg = lua_toboolean(L, 10);\n  console.warn('TerrainDeformRipple was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TerrainDeformWave takes real x, real y, real dirX, real dirY, real distance, real speed, real radius, real depth, integer trailTime, integer count returns terraindeformation\n */\nfunction TerrainDeformWave(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _dirX = luaL_checknumber(L, 3);\n  const _dirY = luaL_checknumber(L, 4);\n  const _distance = luaL_checknumber(L, 5);\n  const _speed = luaL_checknumber(L, 6);\n  const _radius = luaL_checknumber(L, 7);\n  const _depth = luaL_checknumber(L, 8);\n  const _trailTime = luaL_checkinteger(L, 9);\n  const _count = luaL_checkinteger(L, 10);\n  console.warn('TerrainDeformWave was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TerrainDeformRandom takes real x, real y, real radius, real minDelta, real maxDelta, integer duration, integer updateInterval returns terraindeformation\n */\nfunction TerrainDeformRandom(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _minDelta = luaL_checknumber(L, 4);\n  const _maxDelta = luaL_checknumber(L, 5);\n  const _duration = luaL_checkinteger(L, 6);\n  const _updateInterval = luaL_checkinteger(L, 7);\n  console.warn('TerrainDeformRandom was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native TerrainDeformStop takes terraindeformation deformation, integer duration returns nothing\n */\nfunction TerrainDeformStop(C: Context, L: lua_State): number {\n  const _deformation = lua_touserdata(L, 1);\n  const _duration = luaL_checkinteger(L, 2);\n  console.warn('TerrainDeformStop was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native TerrainDeformStopAll takes nothing returns nothing\n */\nfunction TerrainDeformStopAll(_C: Context, _L: lua_State): number {\n\n  console.warn('TerrainDeformStopAll was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddSpecialEffect takes string modelName, real x, real y returns effect\n */\nfunction AddSpecialEffect(C: Context, L: lua_State): number {\n  const _modelName = luaL_checkstring(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  console.warn('AddSpecialEffect was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpecialEffectLoc takes string modelName, location where returns effect\n */\nfunction AddSpecialEffectLoc(C: Context, L: lua_State): number {\n  const _modelName = luaL_checkstring(L, 1);\n  const _where = lua_touserdata(L, 2);\n  console.warn('AddSpecialEffectLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpecialEffectTarget takes string modelName, widget targetWidget, string attachPointName returns effect\n */\nfunction AddSpecialEffectTarget(C: Context, L: lua_State): number {\n  const _modelName = luaL_checkstring(L, 1);\n  const _targetWidget = lua_touserdata(L, 2);\n  const _attachPointName = luaL_checkstring(L, 3);\n  console.warn('AddSpecialEffectTarget was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyEffect takes effect whichEffect returns nothing\n */\nfunction DestroyEffect(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  console.warn('DestroyEffect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AddSpellEffect takes string abilityString, effecttype t, real x, real y returns effect\n */\nfunction AddSpellEffect(C: Context, L: lua_State): number {\n  const _abilityString = luaL_checkstring(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('AddSpellEffect was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpellEffectLoc takes string abilityString, effecttype t, location where returns effect\n */\nfunction AddSpellEffectLoc(C: Context, L: lua_State): number {\n  const _abilityString = luaL_checkstring(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _where = lua_touserdata(L, 3);\n  console.warn('AddSpellEffectLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpellEffectById takes integer abilityId, effecttype t, real x, real y returns effect\n */\nfunction AddSpellEffectById(C: Context, L: lua_State): number {\n  const _abilityId = luaL_checkinteger(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _x = luaL_checknumber(L, 3);\n  const _y = luaL_checknumber(L, 4);\n  console.warn('AddSpellEffectById was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpellEffectByIdLoc takes integer abilityId, effecttype t, location where returns effect\n */\nfunction AddSpellEffectByIdLoc(C: Context, L: lua_State): number {\n  const _abilityId = luaL_checkinteger(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _where = lua_touserdata(L, 3);\n  console.warn('AddSpellEffectByIdLoc was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpellEffectTarget takes string modelName, effecttype t, widget targetWidget, string attachPoint returns effect\n */\nfunction AddSpellEffectTarget(C: Context, L: lua_State): number {\n  const _modelName = luaL_checkstring(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  const _attachPoint = luaL_checkstring(L, 4);\n  console.warn('AddSpellEffectTarget was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddSpellEffectTargetById takes integer abilityId, effecttype t, widget targetWidget, string attachPoint returns effect\n */\nfunction AddSpellEffectTargetById(C: Context, L: lua_State): number {\n  const _abilityId = luaL_checkinteger(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _targetWidget = lua_touserdata(L, 3);\n  const _attachPoint = luaL_checkstring(L, 4);\n  console.warn('AddSpellEffectTargetById was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddLightning takes string codeName, boolean checkVisibility, real x1, real y1, real x2, real y2 returns lightning\n */\nfunction AddLightning(C: Context, L: lua_State): number {\n  const _codeName = luaL_checkstring(L, 1);\n  const _checkVisibility = lua_toboolean(L, 2);\n  const _x1 = luaL_checknumber(L, 3);\n  const _y1 = luaL_checknumber(L, 4);\n  const _x2 = luaL_checknumber(L, 5);\n  const _y2 = luaL_checknumber(L, 6);\n  console.warn('AddLightning was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native AddLightningEx takes string codeName, boolean checkVisibility, real x1, real y1, real z1, real x2, real y2, real z2 returns lightning\n */\nfunction AddLightningEx(C: Context, L: lua_State): number {\n  const _codeName = luaL_checkstring(L, 1);\n  const _checkVisibility = lua_toboolean(L, 2);\n  const _x1 = luaL_checknumber(L, 3);\n  const _y1 = luaL_checknumber(L, 4);\n  const _z1 = luaL_checknumber(L, 5);\n  const _x2 = luaL_checknumber(L, 6);\n  const _y2 = luaL_checknumber(L, 7);\n  const _z2 = luaL_checknumber(L, 8);\n  console.warn('AddLightningEx was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyLightning takes lightning whichBolt returns boolean\n */\nfunction DestroyLightning(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  console.warn('DestroyLightning was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native MoveLightning takes lightning whichBolt, boolean checkVisibility, real x1, real y1, real x2, real y2 returns boolean\n */\nfunction MoveLightning(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  const _checkVisibility = lua_toboolean(L, 2);\n  const _x1 = luaL_checknumber(L, 3);\n  const _y1 = luaL_checknumber(L, 4);\n  const _x2 = luaL_checknumber(L, 5);\n  const _y2 = luaL_checknumber(L, 6);\n  console.warn('MoveLightning was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native MoveLightningEx takes lightning whichBolt, boolean checkVisibility, real x1, real y1, real z1, real x2, real y2, real z2 returns boolean\n */\nfunction MoveLightningEx(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  const _checkVisibility = lua_toboolean(L, 2);\n  const _x1 = luaL_checknumber(L, 3);\n  const _y1 = luaL_checknumber(L, 4);\n  const _z1 = luaL_checknumber(L, 5);\n  const _x2 = luaL_checknumber(L, 6);\n  const _y2 = luaL_checknumber(L, 7);\n  const _z2 = luaL_checknumber(L, 8);\n  console.warn('MoveLightningEx was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetLightningColorA takes lightning whichBolt returns real\n */\nfunction GetLightningColorA(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  console.warn('GetLightningColorA was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetLightningColorR takes lightning whichBolt returns real\n */\nfunction GetLightningColorR(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  console.warn('GetLightningColorR was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetLightningColorG takes lightning whichBolt returns real\n */\nfunction GetLightningColorG(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  console.warn('GetLightningColorG was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native GetLightningColorB takes lightning whichBolt returns real\n */\nfunction GetLightningColorB(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  console.warn('GetLightningColorB was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native SetLightningColor takes lightning whichBolt, real r, real g, real b, real a returns boolean\n */\nfunction SetLightningColor(C: Context, L: lua_State): number {\n  const _whichBolt = lua_touserdata(L, 1);\n  const _r = luaL_checknumber(L, 2);\n  const _g = luaL_checknumber(L, 3);\n  const _b = luaL_checknumber(L, 4);\n  const _a = luaL_checknumber(L, 5);\n  console.warn('SetLightningColor was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native GetAbilityEffect takes string abilityString, effecttype t, integer index returns string\n */\nfunction GetAbilityEffect(C: Context, L: lua_State): number {\n  const _abilityString = luaL_checkstring(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _index = luaL_checkinteger(L, 3);\n  console.warn('GetAbilityEffect was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native GetAbilityEffectById takes integer abilityId, effecttype t, integer index returns string\n */\nfunction GetAbilityEffectById(C: Context, L: lua_State): number {\n  const _abilityId = luaL_checkinteger(L, 1);\n  const _t = lua_touserdata(L, 2);\n  const _index = luaL_checkinteger(L, 3);\n  console.warn('GetAbilityEffectById was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native GetAbilitySound takes string abilityString, soundtype t returns string\n */\nfunction GetAbilitySound(C: Context, L: lua_State): number {\n  const _abilityString = luaL_checkstring(L, 1);\n  const _t = lua_touserdata(L, 2);\n  console.warn('GetAbilitySound was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native GetAbilitySoundById takes integer abilityId, soundtype t returns string\n */\nfunction GetAbilitySoundById(C: Context, L: lua_State): number {\n  const _abilityId = luaL_checkinteger(L, 1);\n  const _t = lua_touserdata(L, 2);\n  console.warn('GetAbilitySoundById was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native GetTerrainCliffLevel takes real x, real y returns integer\n */\nfunction GetTerrainCliffLevel(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('GetTerrainCliffLevel was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetWaterBaseColor takes integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction SetWaterBaseColor(C: Context, L: lua_State): number {\n  const _red = luaL_checkinteger(L, 1);\n  const _green = luaL_checkinteger(L, 2);\n  const _blue = luaL_checkinteger(L, 3);\n  const _alpha = luaL_checkinteger(L, 4);\n  console.warn('SetWaterBaseColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetWaterDeforms takes boolean val returns nothing\n */\nfunction SetWaterDeforms(C: Context, L: lua_State): number {\n  const _val = lua_toboolean(L, 1);\n  console.warn('SetWaterDeforms was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetTerrainType takes real x, real y returns integer\n */\nfunction GetTerrainType(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('GetTerrainType was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native GetTerrainVariance takes real x, real y returns integer\n */\nfunction GetTerrainVariance(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('GetTerrainVariance was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native SetTerrainType takes real x, real y, integer terrainType, integer variation, integer area, integer shape returns nothing\n */\nfunction SetTerrainType(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _terrainType = luaL_checkinteger(L, 3);\n  const _variation = luaL_checkinteger(L, 4);\n  const _area = luaL_checkinteger(L, 5);\n  const _shape = luaL_checkinteger(L, 6);\n  console.warn('SetTerrainType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsTerrainPathable takes real x, real y, pathingtype t returns boolean\n */\nfunction IsTerrainPathable(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _t = lua_touserdata(L, 3);\n  console.warn('IsTerrainPathable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetTerrainPathable takes real x, real y, pathingtype t, boolean flag returns nothing\n */\nfunction SetTerrainPathable(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _t = lua_touserdata(L, 3);\n  const _flag = lua_toboolean(L, 4);\n  console.warn('SetTerrainPathable was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateImage takes string file, real sizeX, real sizeY, real sizeZ, real posX, real posY, real posZ, real originX, real originY, real originZ, integer imageType returns image\n */\nfunction CreateImage(C: Context, L: lua_State): number {\n  const _file = luaL_checkstring(L, 1);\n  const _sizeX = luaL_checknumber(L, 2);\n  const _sizeY = luaL_checknumber(L, 3);\n  const _sizeZ = luaL_checknumber(L, 4);\n  const _posX = luaL_checknumber(L, 5);\n  const _posY = luaL_checknumber(L, 6);\n  const _posZ = luaL_checknumber(L, 7);\n  const _originX = luaL_checknumber(L, 8);\n  const _originY = luaL_checknumber(L, 9);\n  const _originZ = luaL_checknumber(L, 10);\n  const _imageType = luaL_checkinteger(L, 11);\n  console.warn('CreateImage was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyImage takes image whichImage returns nothing\n */\nfunction DestroyImage(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  console.warn('DestroyImage was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ShowImage takes image whichImage, boolean flag returns nothing\n */\nfunction ShowImage(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('ShowImage was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImageConstantHeight takes image whichImage, boolean flag, real height returns nothing\n */\nfunction SetImageConstantHeight(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  const _height = luaL_checknumber(L, 3);\n  console.warn('SetImageConstantHeight was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImagePosition takes image whichImage, real x, real y, real z returns nothing\n */\nfunction SetImagePosition(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  console.warn('SetImagePosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImageColor takes image whichImage, integer red, integer green, integer blue, integer alpha returns nothing\n */\nfunction SetImageColor(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _red = luaL_checkinteger(L, 2);\n  const _green = luaL_checkinteger(L, 3);\n  const _blue = luaL_checkinteger(L, 4);\n  const _alpha = luaL_checkinteger(L, 5);\n  console.warn('SetImageColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImageRender takes image whichImage, boolean flag returns nothing\n */\nfunction SetImageRender(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetImageRender was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImageRenderAlways takes image whichImage, boolean flag returns nothing\n */\nfunction SetImageRenderAlways(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetImageRenderAlways was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImageAboveWater takes image whichImage, boolean flag, boolean useWaterAlpha returns nothing\n */\nfunction SetImageAboveWater(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  const _useWaterAlpha = lua_toboolean(L, 3);\n  console.warn('SetImageAboveWater was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetImageType takes image whichImage, integer imageType returns nothing\n */\nfunction SetImageType(C: Context, L: lua_State): number {\n  const _whichImage = lua_touserdata(L, 1);\n  const _imageType = luaL_checkinteger(L, 2);\n  console.warn('SetImageType was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateUbersplat takes real x, real y, string name, integer red, integer green, integer blue, integer alpha, boolean forcePaused, boolean noBirthTime returns ubersplat\n */\nfunction CreateUbersplat(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _name = luaL_checkstring(L, 3);\n  const _red = luaL_checkinteger(L, 4);\n  const _green = luaL_checkinteger(L, 5);\n  const _blue = luaL_checkinteger(L, 6);\n  const _alpha = luaL_checkinteger(L, 7);\n  const _forcePaused = lua_toboolean(L, 8);\n  const _noBirthTime = lua_toboolean(L, 9);\n  console.warn('CreateUbersplat was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native DestroyUbersplat takes ubersplat whichSplat returns nothing\n */\nfunction DestroyUbersplat(C: Context, L: lua_State): number {\n  const _whichSplat = lua_touserdata(L, 1);\n  console.warn('DestroyUbersplat was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ResetUbersplat takes ubersplat whichSplat returns nothing\n */\nfunction ResetUbersplat(C: Context, L: lua_State): number {\n  const _whichSplat = lua_touserdata(L, 1);\n  console.warn('ResetUbersplat was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native FinishUbersplat takes ubersplat whichSplat returns nothing\n */\nfunction FinishUbersplat(C: Context, L: lua_State): number {\n  const _whichSplat = lua_touserdata(L, 1);\n  console.warn('FinishUbersplat was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native ShowUbersplat takes ubersplat whichSplat, boolean flag returns nothing\n */\nfunction ShowUbersplat(C: Context, L: lua_State): number {\n  const _whichSplat = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('ShowUbersplat was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUbersplatRender takes ubersplat whichSplat, boolean flag returns nothing\n */\nfunction SetUbersplatRender(C: Context, L: lua_State): number {\n  const _whichSplat = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetUbersplatRender was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetUbersplatRenderAlways takes ubersplat whichSplat, boolean flag returns nothing\n */\nfunction SetUbersplatRenderAlways(C: Context, L: lua_State): number {\n  const _whichSplat = lua_touserdata(L, 1);\n  const _flag = lua_toboolean(L, 2);\n  console.warn('SetUbersplatRenderAlways was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetBlight takes player whichPlayer, real x, real y, real radius, boolean addBlight returns nothing\n */\nfunction SetBlight(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _radius = luaL_checknumber(L, 4);\n  const _addBlight = lua_toboolean(L, 5);\n  console.warn('SetBlight was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetBlightRect takes player whichPlayer, rect r, boolean addBlight returns nothing\n */\nfunction SetBlightRect(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _r = lua_touserdata(L, 2);\n  const _addBlight = lua_toboolean(L, 3);\n  console.warn('SetBlightRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetBlightPoint takes player whichPlayer, real x, real y, boolean addBlight returns nothing\n */\nfunction SetBlightPoint(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _addBlight = lua_toboolean(L, 4);\n  console.warn('SetBlightPoint was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetBlightLoc takes player whichPlayer, location whichLocation, real radius, boolean addBlight returns nothing\n */\nfunction SetBlightLoc(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _whichLocation = lua_touserdata(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _addBlight = lua_toboolean(L, 4);\n  console.warn('SetBlightLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CreateBlightedGoldmine takes player id, real x, real y, real face returns unit\n */\nfunction CreateBlightedGoldmine(C: Context, L: lua_State): number {\n  const _id = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _face = luaL_checknumber(L, 4);\n  console.warn('CreateBlightedGoldmine was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native IsPointBlighted takes real x, real y returns boolean\n */\nfunction IsPointBlighted(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('IsPointBlighted was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native SetDoodadAnimation takes real x, real y, real radius, integer doodadID, boolean nearestOnly, string animName, boolean animRandom returns nothing\n */\nfunction SetDoodadAnimation(C: Context, L: lua_State): number {\n  const _x = luaL_checknumber(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  const _radius = luaL_checknumber(L, 3);\n  const _doodadID = luaL_checkinteger(L, 4);\n  const _nearestOnly = lua_toboolean(L, 5);\n  const _animName = luaL_checkstring(L, 6);\n  const _animRandom = lua_toboolean(L, 7);\n  console.warn('SetDoodadAnimation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native SetDoodadAnimationRect takes rect r, integer doodadID, string animName, boolean animRandom returns nothing\n */\nfunction SetDoodadAnimationRect(C: Context, L: lua_State): number {\n  const _r = lua_touserdata(L, 1);\n  const _doodadID = luaL_checkinteger(L, 2);\n  const _animName = luaL_checkstring(L, 3);\n  const _animRandom = lua_toboolean(L, 4);\n  console.warn('SetDoodadAnimationRect was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StartMeleeAI takes player num, string script returns nothing\n */\nfunction StartMeleeAI(C: Context, L: lua_State): number {\n  const _num = lua_touserdata(L, 1);\n  const _script = luaL_checkstring(L, 2);\n  console.warn('StartMeleeAI was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native StartCampaignAI takes player num, string script returns nothing\n */\nfunction StartCampaignAI(C: Context, L: lua_State): number {\n  const _num = lua_touserdata(L, 1);\n  const _script = luaL_checkstring(L, 2);\n  console.warn('StartCampaignAI was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native CommandAI takes player num, integer command, integer data returns nothing\n */\nfunction CommandAI(C: Context, L: lua_State): number {\n  const _num = lua_touserdata(L, 1);\n  const _command = luaL_checkinteger(L, 2);\n  const _data = luaL_checkinteger(L, 3);\n  console.warn('CommandAI was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PauseCompAI takes player p, boolean pause returns nothing\n */\nfunction PauseCompAI(C: Context, L: lua_State): number {\n  const _p = lua_touserdata(L, 1);\n  const _pause = lua_toboolean(L, 2);\n  console.warn('PauseCompAI was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native GetAIDifficulty takes player num returns aidifficulty\n */\nfunction GetAIDifficulty(C: Context, L: lua_State): number {\n  const _num = lua_touserdata(L, 1);\n  console.warn('GetAIDifficulty was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native RemoveGuardPosition takes unit hUnit returns nothing\n */\nfunction RemoveGuardPosition(C: Context, L: lua_State): number {\n  const _hUnit = lua_touserdata(L, 1);\n  console.warn('RemoveGuardPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RecycleGuardPosition takes unit hUnit returns nothing\n */\nfunction RecycleGuardPosition(C: Context, L: lua_State): number {\n  const _hUnit = lua_touserdata(L, 1);\n  console.warn('RecycleGuardPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native RemoveAllGuardPositions takes player num returns nothing\n */\nfunction RemoveAllGuardPositions(C: Context, L: lua_State): number {\n  const _num = lua_touserdata(L, 1);\n  console.warn('RemoveAllGuardPositions was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native Cheat takes string cheatStr returns nothing\n */\nfunction Cheat(C: Context, L: lua_State): number {\n  const _cheatStr = luaL_checkstring(L, 1);\n  console.warn('Cheat was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native IsNoVictoryCheat takes nothing returns boolean\n */\nfunction IsNoVictoryCheat(C: Context, L: lua_State): number {\n\n  console.warn('IsNoVictoryCheat was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native IsNoDefeatCheat takes nothing returns boolean\n */\nfunction IsNoDefeatCheat(C: Context, L: lua_State): number {\n\n  console.warn('IsNoDefeatCheat was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native Preload takes string filename returns nothing\n */\nfunction Preload(C: Context, L: lua_State): number {\n  const _filename = luaL_checkstring(L, 1);\n  console.warn('Preload was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadEnd takes real timeout returns nothing\n */\nfunction PreloadEnd(C: Context, L: lua_State): number {\n  const _timeout = luaL_checknumber(L, 1);\n  console.warn('PreloadEnd was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadStart takes nothing returns nothing\n */\nfunction PreloadStart(_C: Context, _L: lua_State): number {\n\n  console.warn('PreloadStart was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadRefresh takes nothing returns nothing\n */\nfunction PreloadRefresh(_C: Context, _L: lua_State): number {\n\n  console.warn('PreloadRefresh was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadEndEx takes nothing returns nothing\n */\nfunction PreloadEndEx(_C: Context, _L: lua_State): number {\n\n  console.warn('PreloadEndEx was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadGenClear takes nothing returns nothing\n */\nfunction PreloadGenClear(_C: Context, _L: lua_State): number {\n\n  console.warn('PreloadGenClear was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadGenStart takes nothing returns nothing\n */\nfunction PreloadGenStart(_C: Context, _L: lua_State): number {\n\n  console.warn('PreloadGenStart was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native PreloadGenEnd takes string filename returns nothing\n */\nfunction PreloadGenEnd(C: Context, L: lua_State): number {\n  const _filename = luaL_checkstring(L, 1);\n  console.warn('PreloadGenEnd was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native Preloader takes string filename returns nothing\n */\nfunction Preloader(C: Context, L: lua_State): number {\n  const _filename = luaL_checkstring(L, 1);\n  console.warn('Preloader was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AutomationTestStart takes string testName returns nothing\n */\nfunction AutomationTestStart(C: Context, L: lua_State): number {\n  const _testName = luaL_checkstring(L, 1);\n  console.warn('AutomationTestStart was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native AutomationTestEnd takes string testName returns nothing\n */\nfunction AutomationTestEnd(C: Context, L: lua_State): number {\n  const _testName = luaL_checkstring(L, 1);\n  console.warn('AutomationTestEnd was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetTriggerPlayerMouseX takes nothing returns real\n */\nfunction BlzGetTriggerPlayerMouseX(C: Context, L: lua_State): number {\n\n  console.warn('BlzGetTriggerPlayerMouseX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetTriggerPlayerMouseY takes nothing returns real\n */\nfunction BlzGetTriggerPlayerMouseY(C: Context, L: lua_State): number {\n\n  console.warn('BlzGetTriggerPlayerMouseY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetTriggerPlayerMousePosition takes nothing returns location\n */\nfunction BlzGetTriggerPlayerMousePosition(C: Context, L: lua_State): number {\n\n  console.warn('BlzGetTriggerPlayerMousePosition was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native BlzGetTriggerPlayerMouseButton takes nothing returns mousebuttontype\n */\nfunction BlzGetTriggerPlayerMouseButton(C: Context, L: lua_State): number {\n\n  console.warn('BlzGetTriggerPlayerMouseButton was called but is not implemented :(');\n  lua_pushlightuserdata(L, { name: 'FAKE' });\n  return 1;\n}\n\n/**\n * native BlzSetAbilityTooltip takes integer abilCode, string tooltip, integer level returns nothing\n */\nfunction BlzSetAbilityTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _tooltip = luaL_checkstring(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzSetAbilityTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityActivatedTooltip takes integer abilCode, string tooltip, integer level returns nothing\n */\nfunction BlzSetAbilityActivatedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _tooltip = luaL_checkstring(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzSetAbilityActivatedTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityExtendedTooltip takes integer abilCode, string ExtendedTooltip, integer level returns nothing\n */\nfunction BlzSetAbilityExtendedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _ExtendedTooltip = luaL_checkstring(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzSetAbilityExtendedTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityActivatedExtendedTooltip takes integer abilCode, string ExtendedTooltip, integer level returns nothing\n */\nfunction BlzSetAbilityActivatedExtendedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _ExtendedTooltip = luaL_checkstring(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzSetAbilityActivatedExtendedTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityResearchTooltip takes integer abilCode, string researchTooltip, integer level returns nothing\n */\nfunction BlzSetAbilityResearchTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _researchTooltip = luaL_checkstring(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzSetAbilityResearchTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityResearchExtendedTooltip takes integer abilCode, string researchExtendedTooltip, integer level returns nothing\n */\nfunction BlzSetAbilityResearchExtendedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _researchExtendedTooltip = luaL_checkstring(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzSetAbilityResearchExtendedTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetAbilityTooltip takes integer abilCode, integer level returns string\n */\nfunction BlzGetAbilityTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzGetAbilityActivatedTooltip takes integer abilCode, integer level returns string\n */\nfunction BlzGetAbilityActivatedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityActivatedTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzGetAbilityExtendedTooltip takes integer abilCode, integer level returns string\n */\nfunction BlzGetAbilityExtendedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityExtendedTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzGetAbilityActivatedExtendedTooltip takes integer abilCode, integer level returns string\n */\nfunction BlzGetAbilityActivatedExtendedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityActivatedExtendedTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzGetAbilityResearchTooltip takes integer abilCode, integer level returns string\n */\nfunction BlzGetAbilityResearchTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityResearchTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzGetAbilityResearchExtendedTooltip takes integer abilCode, integer level returns string\n */\nfunction BlzGetAbilityResearchExtendedTooltip(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityResearchExtendedTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzSetAbilityIcon takes integer abilCode, string iconPath returns nothing\n */\nfunction BlzSetAbilityIcon(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _iconPath = luaL_checkstring(L, 2);\n  console.warn('BlzSetAbilityIcon was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetAbilityIcon takes integer abilCode returns string\n */\nfunction BlzGetAbilityIcon(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  console.warn('BlzGetAbilityIcon was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzSetAbilityActivatedIcon takes integer abilCode, string iconPath returns nothing\n */\nfunction BlzSetAbilityActivatedIcon(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _iconPath = luaL_checkstring(L, 2);\n  console.warn('BlzSetAbilityActivatedIcon was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetAbilityActivatedIcon takes integer abilCode returns string\n */\nfunction BlzGetAbilityActivatedIcon(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  console.warn('BlzGetAbilityActivatedIcon was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzGetAbilityPosX takes integer abilCode returns integer\n */\nfunction BlzGetAbilityPosX(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  console.warn('BlzGetAbilityPosX was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetAbilityPosY takes integer abilCode returns integer\n */\nfunction BlzGetAbilityPosY(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  console.warn('BlzGetAbilityPosY was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetAbilityPosX takes integer abilCode, integer x returns nothing\n */\nfunction BlzSetAbilityPosX(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _x = luaL_checkinteger(L, 2);\n  console.warn('BlzSetAbilityPosX was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityPosY takes integer abilCode, integer y returns nothing\n */\nfunction BlzSetAbilityPosY(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _y = luaL_checkinteger(L, 2);\n  console.warn('BlzSetAbilityPosY was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetAbilityActivatedPosX takes integer abilCode returns integer\n */\nfunction BlzGetAbilityActivatedPosX(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  console.warn('BlzGetAbilityActivatedPosX was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetAbilityActivatedPosY takes integer abilCode returns integer\n */\nfunction BlzGetAbilityActivatedPosY(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  console.warn('BlzGetAbilityActivatedPosY was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetAbilityActivatedPosX takes integer abilCode, integer x returns nothing\n */\nfunction BlzSetAbilityActivatedPosX(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _x = luaL_checkinteger(L, 2);\n  console.warn('BlzSetAbilityActivatedPosX was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetAbilityActivatedPosY takes integer abilCode, integer y returns nothing\n */\nfunction BlzSetAbilityActivatedPosY(C: Context, L: lua_State): number {\n  const _abilCode = luaL_checkinteger(L, 1);\n  const _y = luaL_checkinteger(L, 2);\n  console.warn('BlzSetAbilityActivatedPosY was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitMaxHP takes unit whichUnit returns integer\n */\nfunction BlzGetUnitMaxHP(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzGetUnitMaxHP was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitMaxHP takes unit whichUnit, integer hp returns nothing\n */\nfunction BlzSetUnitMaxHP(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _hp = luaL_checkinteger(L, 2);\n  console.warn('BlzSetUnitMaxHP was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitMaxMana takes unit whichUnit returns integer\n */\nfunction BlzGetUnitMaxMana(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzGetUnitMaxMana was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitMaxMana takes unit whichUnit, integer mana returns nothing\n */\nfunction BlzSetUnitMaxMana(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _mana = luaL_checkinteger(L, 2);\n  console.warn('BlzSetUnitMaxMana was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzDeleteHeroAbility takes unit whichUnit, integer abilCode returns nothing\n */\nfunction BlzDeleteHeroAbility(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilCode = luaL_checkinteger(L, 2);\n  console.warn('BlzDeleteHeroAbility was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetItemName takes item whichItem, string name returns nothing\n */\nfunction BlzSetItemName(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetItemName was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetItemDescription takes item whichItem, string name returns nothing\n */\nfunction BlzSetItemDescription(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetItemDescription was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetItemDescription takes item whichItem returns string\n */\nfunction BlzGetItemDescription(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('BlzGetItemDescription was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzSetItemTooltip takes item whichItem, string name returns nothing\n */\nfunction BlzSetItemTooltip(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetItemTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetItemTooltip takes item whichItem returns string\n */\nfunction BlzGetItemTooltip(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('BlzGetItemTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzSetItemExtendedTooltip takes item whichItem, string name returns nothing\n */\nfunction BlzSetItemExtendedTooltip(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetItemExtendedTooltip was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetItemExtendedTooltip takes item whichItem returns string\n */\nfunction BlzGetItemExtendedTooltip(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('BlzGetItemExtendedTooltip was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzSetItemIconPath takes item whichItem, string name returns nothing\n */\nfunction BlzSetItemIconPath(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetItemIconPath was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetItemIconPath takes item whichItem returns string\n */\nfunction BlzGetItemIconPath(C: Context, L: lua_State): number {\n  const _whichItem = lua_touserdata(L, 1);\n  console.warn('BlzGetItemIconPath was called but is not implemented :(');\n  lua_pushstring(L, '');\n  return 1;\n}\n\n/**\n * native BlzSetUnitName takes unit whichUnit, string name returns nothing\n */\nfunction BlzSetUnitName(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetUnitName was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetHeroProperName takes unit whichUnit, string name returns nothing\n */\nfunction BlzSetHeroProperName(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _name = luaL_checkstring(L, 2);\n  console.warn('BlzSetHeroProperName was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitBaseDamage takes unit whichUnit, integer weaponIndex returns integer\n */\nfunction BlzGetUnitBaseDamage(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _weaponIndex = luaL_checkinteger(L, 2);\n  console.warn('BlzGetUnitBaseDamage was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitBaseDamage takes unit whichUnit, integer baseDamage, integer weaponIndex returns nothing\n */\nfunction BlzSetUnitBaseDamage(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _baseDamage = luaL_checkinteger(L, 2);\n  const _weaponIndex = luaL_checkinteger(L, 3);\n  console.warn('BlzSetUnitBaseDamage was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitDiceNumber takes unit whichUnit, integer weaponIndex returns integer\n */\nfunction BlzGetUnitDiceNumber(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _weaponIndex = luaL_checkinteger(L, 2);\n  console.warn('BlzGetUnitDiceNumber was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitDiceNumber takes unit whichUnit, integer diceNumber, integer weaponIndex returns nothing\n */\nfunction BlzSetUnitDiceNumber(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _diceNumber = luaL_checkinteger(L, 2);\n  const _weaponIndex = luaL_checkinteger(L, 3);\n  console.warn('BlzSetUnitDiceNumber was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitDiceSides takes unit whichUnit, integer weaponIndex returns integer\n */\nfunction BlzGetUnitDiceSides(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _weaponIndex = luaL_checkinteger(L, 2);\n  console.warn('BlzGetUnitDiceSides was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitDiceSides takes unit whichUnit, integer diceSides, integer weaponIndex returns nothing\n */\nfunction BlzSetUnitDiceSides(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _diceSides = luaL_checkinteger(L, 2);\n  const _weaponIndex = luaL_checkinteger(L, 3);\n  console.warn('BlzSetUnitDiceSides was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitAttackCooldown takes unit whichUnit, integer weaponIndex returns real\n */\nfunction BlzGetUnitAttackCooldown(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _weaponIndex = luaL_checkinteger(L, 2);\n  console.warn('BlzGetUnitAttackCooldown was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitAttackCooldown takes unit whichUnit, real cooldown, integer weaponIndex returns nothing\n */\nfunction BlzSetUnitAttackCooldown(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _cooldown = luaL_checknumber(L, 2);\n  const _weaponIndex = luaL_checkinteger(L, 3);\n  console.warn('BlzSetUnitAttackCooldown was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectColorByPlayer takes effect whichEffect, player whichPlayer returns nothing\n */\nfunction BlzSetSpecialEffectColorByPlayer(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _whichPlayer = lua_touserdata(L, 2);\n  console.warn('BlzSetSpecialEffectColorByPlayer was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectColor takes effect whichEffect, integer r, integer g, integer b returns nothing\n */\nfunction BlzSetSpecialEffectColor(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _r = luaL_checkinteger(L, 2);\n  const _g = luaL_checkinteger(L, 3);\n  const _b = luaL_checkinteger(L, 4);\n  console.warn('BlzSetSpecialEffectColor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectAlpha takes effect whichEffect, integer alpha returns nothing\n */\nfunction BlzSetSpecialEffectAlpha(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _alpha = luaL_checkinteger(L, 2);\n  console.warn('BlzSetSpecialEffectAlpha was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectScale takes effect whichEffect, real scale returns nothing\n */\nfunction BlzSetSpecialEffectScale(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _scale = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectScale was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectPosition takes effect whichEffect, real x, real y, real z returns nothing\n */\nfunction BlzSetSpecialEffectPosition(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  const _y = luaL_checknumber(L, 3);\n  const _z = luaL_checknumber(L, 4);\n  console.warn('BlzSetSpecialEffectPosition was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectHeight takes effect whichEffect, real height returns nothing\n */\nfunction BlzSetSpecialEffectHeight(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _height = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectHeight was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectTimeScale takes effect whichEffect, real timeScale returns nothing\n */\nfunction BlzSetSpecialEffectTimeScale(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _timeScale = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectTimeScale was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectTime takes effect whichEffect, real time returns nothing\n */\nfunction BlzSetSpecialEffectTime(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _time = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectTime was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectOrientation takes effect whichEffect, real yaw, real pitch, real roll returns nothing\n */\nfunction BlzSetSpecialEffectOrientation(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _yaw = luaL_checknumber(L, 2);\n  const _pitch = luaL_checknumber(L, 3);\n  const _roll = luaL_checknumber(L, 4);\n  console.warn('BlzSetSpecialEffectOrientation was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectYaw takes effect whichEffect, real yaw returns nothing\n */\nfunction BlzSetSpecialEffectYaw(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _yaw = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectYaw was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectPitch takes effect whichEffect, real pitch returns nothing\n */\nfunction BlzSetSpecialEffectPitch(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _pitch = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectPitch was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectRoll takes effect whichEffect, real roll returns nothing\n */\nfunction BlzSetSpecialEffectRoll(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _roll = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectRoll was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectX takes effect whichEffect, real x returns nothing\n */\nfunction BlzSetSpecialEffectX(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _x = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectX was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectY takes effect whichEffect, real y returns nothing\n */\nfunction BlzSetSpecialEffectY(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _y = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectY was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectZ takes effect whichEffect, real z returns nothing\n */\nfunction BlzSetSpecialEffectZ(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _z = luaL_checknumber(L, 2);\n  console.warn('BlzSetSpecialEffectZ was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetSpecialEffectPositionLoc takes effect whichEffect, location loc returns nothing\n */\nfunction BlzSetSpecialEffectPositionLoc(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  const _loc = lua_touserdata(L, 2);\n  console.warn('BlzSetSpecialEffectPositionLoc was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetLocalSpecialEffectX takes effect whichEffect returns real\n */\nfunction BlzGetLocalSpecialEffectX(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  console.warn('BlzGetLocalSpecialEffectX was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetLocalSpecialEffectY takes effect whichEffect returns real\n */\nfunction BlzGetLocalSpecialEffectY(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  console.warn('BlzGetLocalSpecialEffectY was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetLocalSpecialEffectZ takes effect whichEffect returns real\n */\nfunction BlzGetLocalSpecialEffectZ(C: Context, L: lua_State): number {\n  const _whichEffect = lua_touserdata(L, 1);\n  console.warn('BlzGetLocalSpecialEffectZ was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetUnitArmor takes unit whichUnit returns real\n */\nfunction BlzGetUnitArmor(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzGetUnitArmor was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitArmor takes unit whichUnit, real armorAmount returns nothing\n */\nfunction BlzSetUnitArmor(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _armorAmount = luaL_checknumber(L, 2);\n  console.warn('BlzSetUnitArmor was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzUnitHideAbility takes unit whichUnit, integer abilId, boolean flag returns nothing\n */\nfunction BlzUnitHideAbility(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  const _flag = lua_toboolean(L, 3);\n  console.warn('BlzUnitHideAbility was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzUnitDisableAbility takes unit whichUnit, integer abilId, boolean flag, boolean hideUI returns nothing\n */\nfunction BlzUnitDisableAbility(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  const _flag = lua_toboolean(L, 3);\n  const _hideUI = lua_toboolean(L, 4);\n  console.warn('BlzUnitDisableAbility was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzUnitCancelTimedLife takes unit whichUnit returns nothing\n */\nfunction BlzUnitCancelTimedLife(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzUnitCancelTimedLife was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzIsUnitSelectable takes unit whichUnit returns boolean\n */\nfunction BlzIsUnitSelectable(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzIsUnitSelectable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native BlzIsUnitInvulnerable takes unit whichUnit returns boolean\n */\nfunction BlzIsUnitInvulnerable(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzIsUnitInvulnerable was called but is not implemented :(');\n  lua_pushboolean(L, false);\n  return 1;\n}\n\n/**\n * native BlzUnitInterruptAttack takes unit whichUnit returns nothing\n */\nfunction BlzUnitInterruptAttack(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzUnitInterruptAttack was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitCollisionSize takes unit whichUnit returns real\n */\nfunction BlzGetUnitCollisionSize(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzGetUnitCollisionSize was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetAbilityManaCost takes integer abilId, integer level returns integer\n */\nfunction BlzGetAbilityManaCost(C: Context, L: lua_State): number {\n  const _abilId = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityManaCost was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetAbilityCooldown takes integer abilId, integer level returns real\n */\nfunction BlzGetAbilityCooldown(C: Context, L: lua_State): number {\n  const _abilId = luaL_checkinteger(L, 1);\n  const _level = luaL_checkinteger(L, 2);\n  console.warn('BlzGetAbilityCooldown was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitAbilityCooldown takes unit whichUnit, integer abilId, integer level, real cooldown returns nothing\n */\nfunction BlzSetUnitAbilityCooldown(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  const _cooldown = luaL_checknumber(L, 4);\n  console.warn('BlzSetUnitAbilityCooldown was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitAbilityCooldown takes unit whichUnit, integer abilId, integer level returns real\n */\nfunction BlzGetUnitAbilityCooldown(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzGetUnitAbilityCooldown was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzGetUnitAbilityCooldownRemaining takes unit whichUnit, integer abilId returns real\n */\nfunction BlzGetUnitAbilityCooldownRemaining(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  console.warn('BlzGetUnitAbilityCooldownRemaining was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzEndUnitAbilityCooldown takes unit whichUnit, integer abilCode returns nothing\n */\nfunction BlzEndUnitAbilityCooldown(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilCode = luaL_checkinteger(L, 2);\n  console.warn('BlzEndUnitAbilityCooldown was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetUnitAbilityManaCost takes unit whichUnit, integer abilId, integer level returns integer\n */\nfunction BlzGetUnitAbilityManaCost(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  console.warn('BlzGetUnitAbilityManaCost was called but is not implemented :(');\n  lua_pushinteger(L, 0);\n  return 1;\n}\n\n/**\n * native BlzSetUnitAbilityManaCost takes unit whichUnit, integer abilId, integer level, integer manaCost returns nothing\n */\nfunction BlzSetUnitAbilityManaCost(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  const _abilId = luaL_checkinteger(L, 2);\n  const _level = luaL_checkinteger(L, 3);\n  const _manaCost = luaL_checkinteger(L, 4);\n  console.warn('BlzSetUnitAbilityManaCost was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzGetLocalUnitZ takes unit whichUnit returns real\n */\nfunction BlzGetLocalUnitZ(C: Context, L: lua_State): number {\n  const _whichUnit = lua_touserdata(L, 1);\n  console.warn('BlzGetLocalUnitZ was called but is not implemented :(');\n  lua_pushnumber(L, 0);\n  return 1;\n}\n\n/**\n * native BlzDecPlayerTechResearched takes player whichPlayer, integer techid, integer levels returns nothing\n */\nfunction BlzDecPlayerTechResearched(C: Context, L: lua_State): number {\n  const _whichPlayer = lua_touserdata(L, 1);\n  const _techid = luaL_checkinteger(L, 2);\n  const _levels = luaL_checkinteger(L, 3);\n  console.warn('BlzDecPlayerTechResearched was called but is not implemented :(');\n  return 0;\n}\n\n/**\n * native BlzSetEventDamage takes real damage returns nothing\n */\nfunction BlzSetEventDamage(C: Context, L: lua_State): number {\n  const _damage = luaL_checknumber(L, 1);\n  console.warn('BlzSetEventDamage was called but is not implemented :(');\n  return 0;\n}\n\nexport default function bindNatives(C: Context): void {\n  const L = C.L;\n\n  lua_register(L, 'ConvertRace', ConvertRace.bind(null, C));\n  lua_register(L, 'ConvertAllianceType', ConvertAllianceType.bind(null, C));\n  lua_register(L, 'ConvertRacePref', ConvertRacePref.bind(null, C));\n  lua_register(L, 'ConvertIGameState', ConvertIGameState.bind(null, C));\n  lua_register(L, 'ConvertFGameState', ConvertFGameState.bind(null, C));\n  lua_register(L, 'ConvertPlayerState', ConvertPlayerState.bind(null, C));\n  lua_register(L, 'ConvertPlayerScore', ConvertPlayerScore.bind(null, C));\n  lua_register(L, 'ConvertPlayerGameResult', ConvertPlayerGameResult.bind(null, C));\n  lua_register(L, 'ConvertUnitState', ConvertUnitState.bind(null, C));\n  lua_register(L, 'ConvertAIDifficulty', ConvertAIDifficulty.bind(null, C));\n  lua_register(L, 'ConvertGameEvent', ConvertGameEvent.bind(null, C));\n  lua_register(L, 'ConvertPlayerEvent', ConvertPlayerEvent.bind(null, C));\n  lua_register(L, 'ConvertPlayerUnitEvent', ConvertPlayerUnitEvent.bind(null, C));\n  lua_register(L, 'ConvertWidgetEvent', ConvertWidgetEvent.bind(null, C));\n  lua_register(L, 'ConvertDialogEvent', ConvertDialogEvent.bind(null, C));\n  lua_register(L, 'ConvertUnitEvent', ConvertUnitEvent.bind(null, C));\n  lua_register(L, 'ConvertLimitOp', ConvertLimitOp.bind(null, C));\n  lua_register(L, 'ConvertUnitType', ConvertUnitType.bind(null, C));\n  lua_register(L, 'ConvertGameSpeed', ConvertGameSpeed.bind(null, C));\n  lua_register(L, 'ConvertPlacement', ConvertPlacement.bind(null, C));\n  lua_register(L, 'ConvertStartLocPrio', ConvertStartLocPrio.bind(null, C));\n  lua_register(L, 'ConvertGameDifficulty', ConvertGameDifficulty.bind(null, C));\n  lua_register(L, 'ConvertGameType', ConvertGameType.bind(null, C));\n  lua_register(L, 'ConvertMapFlag', ConvertMapFlag.bind(null, C));\n  lua_register(L, 'ConvertMapVisibility', ConvertMapVisibility.bind(null, C));\n  lua_register(L, 'ConvertMapSetting', ConvertMapSetting.bind(null, C));\n  lua_register(L, 'ConvertMapDensity', ConvertMapDensity.bind(null, C));\n  lua_register(L, 'ConvertMapControl', ConvertMapControl.bind(null, C));\n  lua_register(L, 'ConvertPlayerColor', ConvertPlayerColor.bind(null, C));\n  lua_register(L, 'ConvertPlayerSlotState', ConvertPlayerSlotState.bind(null, C));\n  lua_register(L, 'ConvertVolumeGroup', ConvertVolumeGroup.bind(null, C));\n  lua_register(L, 'ConvertCameraField', ConvertCameraField.bind(null, C));\n  lua_register(L, 'ConvertBlendMode', ConvertBlendMode.bind(null, C));\n  lua_register(L, 'ConvertRarityControl', ConvertRarityControl.bind(null, C));\n  lua_register(L, 'ConvertTexMapFlags', ConvertTexMapFlags.bind(null, C));\n  lua_register(L, 'ConvertFogState', ConvertFogState.bind(null, C));\n  lua_register(L, 'ConvertEffectType', ConvertEffectType.bind(null, C));\n  lua_register(L, 'ConvertVersion', ConvertVersion.bind(null, C));\n  lua_register(L, 'ConvertItemType', ConvertItemType.bind(null, C));\n  lua_register(L, 'ConvertAttackType', ConvertAttackType.bind(null, C));\n  lua_register(L, 'ConvertDamageType', ConvertDamageType.bind(null, C));\n  lua_register(L, 'ConvertWeaponType', ConvertWeaponType.bind(null, C));\n  lua_register(L, 'ConvertSoundType', ConvertSoundType.bind(null, C));\n  lua_register(L, 'ConvertPathingType', ConvertPathingType.bind(null, C));\n  lua_register(L, 'ConvertMouseButtonType', ConvertMouseButtonType.bind(null, C));\n  lua_register(L, 'ConvertAnimType', ConvertAnimType.bind(null, C));\n  lua_register(L, 'ConvertSubAnimType', ConvertSubAnimType.bind(null, C));\n  lua_register(L, 'OrderId', OrderId.bind(null, C));\n  lua_register(L, 'OrderId2String', OrderId2String.bind(null, C));\n  lua_register(L, 'UnitId', UnitId.bind(null, C));\n  lua_register(L, 'UnitId2String', UnitId2String.bind(null, C));\n  lua_register(L, 'AbilityId', AbilityId.bind(null, C));\n  lua_register(L, 'AbilityId2String', AbilityId2String.bind(null, C));\n  lua_register(L, 'GetObjectName', GetObjectName.bind(null, C));\n  lua_register(L, 'GetBJMaxPlayers', GetBJMaxPlayers.bind(null, C));\n  lua_register(L, 'GetBJPlayerNeutralVictim', GetBJPlayerNeutralVictim.bind(null, C));\n  lua_register(L, 'GetBJPlayerNeutralExtra', GetBJPlayerNeutralExtra.bind(null, C));\n  lua_register(L, 'GetBJMaxPlayerSlots', GetBJMaxPlayerSlots.bind(null, C));\n  lua_register(L, 'GetPlayerNeutralPassive', GetPlayerNeutralPassive.bind(null, C));\n  lua_register(L, 'GetPlayerNeutralAggressive', GetPlayerNeutralAggressive.bind(null, C));\n  lua_register(L, 'Deg2Rad', Deg2Rad.bind(null, C));\n  lua_register(L, 'Rad2Deg', Rad2Deg.bind(null, C));\n  lua_register(L, 'Sin', Sin.bind(null, C));\n  lua_register(L, 'Cos', Cos.bind(null, C));\n  lua_register(L, 'Tan', Tan.bind(null, C));\n  lua_register(L, 'Asin', Asin.bind(null, C));\n  lua_register(L, 'Acos', Acos.bind(null, C));\n  lua_register(L, 'Atan', Atan.bind(null, C));\n  lua_register(L, 'Atan2', Atan2.bind(null, C));\n  lua_register(L, 'SquareRoot', SquareRoot.bind(null, C));\n  lua_register(L, 'Pow', Pow.bind(null, C));\n  lua_register(L, 'I2R', I2R.bind(null, C));\n  lua_register(L, 'R2I', R2I.bind(null, C));\n  lua_register(L, 'I2S', I2S.bind(null, C));\n  lua_register(L, 'R2S', R2S.bind(null, C));\n  lua_register(L, 'R2SW', R2SW.bind(null, C));\n  lua_register(L, 'S2I', S2I.bind(null, C));\n  lua_register(L, 'S2R', S2R.bind(null, C));\n  lua_register(L, 'GetHandleId', GetHandleId.bind(null, C));\n  lua_register(L, 'SubString', SubString.bind(null, C));\n  lua_register(L, 'StringLength', StringLength.bind(null, C));\n  lua_register(L, 'StringCase', StringCase.bind(null, C));\n  lua_register(L, 'StringHash', StringHash.bind(null, C));\n  lua_register(L, 'GetLocalizedString', GetLocalizedString.bind(null, C));\n  lua_register(L, 'GetLocalizedHotkey', GetLocalizedHotkey.bind(null, C));\n  lua_register(L, 'SetMapName', SetMapName.bind(null, C));\n  lua_register(L, 'SetMapDescription', SetMapDescription.bind(null, C));\n  lua_register(L, 'SetTeams', SetTeams.bind(null, C));\n  lua_register(L, 'SetPlayers', SetPlayers.bind(null, C));\n  lua_register(L, 'DefineStartLocation', DefineStartLocation.bind(null, C));\n  lua_register(L, 'DefineStartLocationLoc', DefineStartLocationLoc.bind(null, C));\n  lua_register(L, 'SetStartLocPrioCount', SetStartLocPrioCount.bind(null, C));\n  lua_register(L, 'SetStartLocPrio', SetStartLocPrio.bind(null, C));\n  lua_register(L, 'GetStartLocPrioSlot', GetStartLocPrioSlot.bind(null, C));\n  lua_register(L, 'GetStartLocPrio', GetStartLocPrio.bind(null, C));\n  lua_register(L, 'SetGameTypeSupported', SetGameTypeSupported.bind(null, C));\n  lua_register(L, 'SetMapFlag', SetMapFlag.bind(null, C));\n  lua_register(L, 'SetGamePlacement', SetGamePlacement.bind(null, C));\n  lua_register(L, 'SetGameSpeed', SetGameSpeed.bind(null, C));\n  lua_register(L, 'SetGameDifficulty', SetGameDifficulty.bind(null, C));\n  lua_register(L, 'SetResourceDensity', SetResourceDensity.bind(null, C));\n  lua_register(L, 'SetCreatureDensity', SetCreatureDensity.bind(null, C));\n  lua_register(L, 'GetTeams', GetTeams.bind(null, C));\n  lua_register(L, 'GetPlayers', GetPlayers.bind(null, C));\n  lua_register(L, 'IsGameTypeSupported', IsGameTypeSupported.bind(null, C));\n  lua_register(L, 'GetGameTypeSelected', GetGameTypeSelected.bind(null, C));\n  lua_register(L, 'IsMapFlagSet', IsMapFlagSet.bind(null, C));\n  lua_register(L, 'GetGamePlacement', GetGamePlacement.bind(null, C));\n  lua_register(L, 'GetGameSpeed', GetGameSpeed.bind(null, C));\n  lua_register(L, 'GetGameDifficulty', GetGameDifficulty.bind(null, C));\n  lua_register(L, 'GetResourceDensity', GetResourceDensity.bind(null, C));\n  lua_register(L, 'GetCreatureDensity', GetCreatureDensity.bind(null, C));\n  lua_register(L, 'GetStartLocationX', GetStartLocationX.bind(null, C));\n  lua_register(L, 'GetStartLocationY', GetStartLocationY.bind(null, C));\n  lua_register(L, 'GetStartLocationLoc', GetStartLocationLoc.bind(null, C));\n  lua_register(L, 'SetPlayerTeam', SetPlayerTeam.bind(null, C));\n  lua_register(L, 'SetPlayerStartLocation', SetPlayerStartLocation.bind(null, C));\n  lua_register(L, 'ForcePlayerStartLocation', ForcePlayerStartLocation.bind(null, C));\n  lua_register(L, 'SetPlayerColor', SetPlayerColor.bind(null, C));\n  lua_register(L, 'SetPlayerAlliance', SetPlayerAlliance.bind(null, C));\n  lua_register(L, 'SetPlayerTaxRate', SetPlayerTaxRate.bind(null, C));\n  lua_register(L, 'SetPlayerRacePreference', SetPlayerRacePreference.bind(null, C));\n  lua_register(L, 'SetPlayerRaceSelectable', SetPlayerRaceSelectable.bind(null, C));\n  lua_register(L, 'SetPlayerController', SetPlayerController.bind(null, C));\n  lua_register(L, 'SetPlayerName', SetPlayerName.bind(null, C));\n  lua_register(L, 'SetPlayerOnScoreScreen', SetPlayerOnScoreScreen.bind(null, C));\n  lua_register(L, 'GetPlayerTeam', GetPlayerTeam.bind(null, C));\n  lua_register(L, 'GetPlayerStartLocation', GetPlayerStartLocation.bind(null, C));\n  lua_register(L, 'GetPlayerColor', GetPlayerColor.bind(null, C));\n  lua_register(L, 'GetPlayerSelectable', GetPlayerSelectable.bind(null, C));\n  lua_register(L, 'GetPlayerController', GetPlayerController.bind(null, C));\n  lua_register(L, 'GetPlayerSlotState', GetPlayerSlotState.bind(null, C));\n  lua_register(L, 'GetPlayerTaxRate', GetPlayerTaxRate.bind(null, C));\n  lua_register(L, 'IsPlayerRacePrefSet', IsPlayerRacePrefSet.bind(null, C));\n  lua_register(L, 'GetPlayerName', GetPlayerName.bind(null, C));\n  lua_register(L, 'CreateTimer', CreateTimer.bind(null, C));\n  lua_register(L, 'DestroyTimer', DestroyTimer.bind(null, C));\n  lua_register(L, 'TimerStart', TimerStart.bind(null, C));\n  lua_register(L, 'TimerGetElapsed', TimerGetElapsed.bind(null, C));\n  lua_register(L, 'TimerGetRemaining', TimerGetRemaining.bind(null, C));\n  lua_register(L, 'TimerGetTimeout', TimerGetTimeout.bind(null, C));\n  lua_register(L, 'PauseTimer', PauseTimer.bind(null, C));\n  lua_register(L, 'ResumeTimer', ResumeTimer.bind(null, C));\n  lua_register(L, 'GetExpiredTimer', GetExpiredTimer.bind(null, C));\n  lua_register(L, 'CreateGroup', CreateGroup.bind(null, C));\n  lua_register(L, 'DestroyGroup', DestroyGroup.bind(null, C));\n  lua_register(L, 'GroupAddUnit', GroupAddUnit.bind(null, C));\n  lua_register(L, 'GroupRemoveUnit', GroupRemoveUnit.bind(null, C));\n  lua_register(L, 'GroupClear', GroupClear.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsOfType', GroupEnumUnitsOfType.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsOfPlayer', GroupEnumUnitsOfPlayer.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsOfTypeCounted', GroupEnumUnitsOfTypeCounted.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsInRect', GroupEnumUnitsInRect.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsInRectCounted', GroupEnumUnitsInRectCounted.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsInRange', GroupEnumUnitsInRange.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsInRangeOfLoc', GroupEnumUnitsInRangeOfLoc.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsInRangeCounted', GroupEnumUnitsInRangeCounted.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsInRangeOfLocCounted', GroupEnumUnitsInRangeOfLocCounted.bind(null, C));\n  lua_register(L, 'GroupEnumUnitsSelected', GroupEnumUnitsSelected.bind(null, C));\n  lua_register(L, 'GroupImmediateOrder', GroupImmediateOrder.bind(null, C));\n  lua_register(L, 'GroupImmediateOrderById', GroupImmediateOrderById.bind(null, C));\n  lua_register(L, 'GroupPointOrder', GroupPointOrder.bind(null, C));\n  lua_register(L, 'GroupPointOrderLoc', GroupPointOrderLoc.bind(null, C));\n  lua_register(L, 'GroupPointOrderById', GroupPointOrderById.bind(null, C));\n  lua_register(L, 'GroupPointOrderByIdLoc', GroupPointOrderByIdLoc.bind(null, C));\n  lua_register(L, 'GroupTargetOrder', GroupTargetOrder.bind(null, C));\n  lua_register(L, 'GroupTargetOrderById', GroupTargetOrderById.bind(null, C));\n  lua_register(L, 'ForGroup', ForGroup.bind(null, C));\n  lua_register(L, 'FirstOfGroup', FirstOfGroup.bind(null, C));\n  lua_register(L, 'CreateForce', CreateForce.bind(null, C));\n  lua_register(L, 'DestroyForce', DestroyForce.bind(null, C));\n  lua_register(L, 'ForceAddPlayer', ForceAddPlayer.bind(null, C));\n  lua_register(L, 'ForceRemovePlayer', ForceRemovePlayer.bind(null, C));\n  lua_register(L, 'ForceClear', ForceClear.bind(null, C));\n  lua_register(L, 'ForceEnumPlayers', ForceEnumPlayers.bind(null, C));\n  lua_register(L, 'ForceEnumPlayersCounted', ForceEnumPlayersCounted.bind(null, C));\n  lua_register(L, 'ForceEnumAllies', ForceEnumAllies.bind(null, C));\n  lua_register(L, 'ForceEnumEnemies', ForceEnumEnemies.bind(null, C));\n  lua_register(L, 'ForForce', ForForce.bind(null, C));\n  lua_register(L, 'Rect', Rect.bind(null, C));\n  lua_register(L, 'RectFromLoc', RectFromLoc.bind(null, C));\n  lua_register(L, 'RemoveRect', RemoveRect.bind(null, C));\n  lua_register(L, 'SetRect', SetRect.bind(null, C));\n  lua_register(L, 'SetRectFromLoc', SetRectFromLoc.bind(null, C));\n  lua_register(L, 'MoveRectTo', MoveRectTo.bind(null, C));\n  lua_register(L, 'MoveRectToLoc', MoveRectToLoc.bind(null, C));\n  lua_register(L, 'GetRectCenterX', GetRectCenterX.bind(null, C));\n  lua_register(L, 'GetRectCenterY', GetRectCenterY.bind(null, C));\n  lua_register(L, 'GetRectMinX', GetRectMinX.bind(null, C));\n  lua_register(L, 'GetRectMinY', GetRectMinY.bind(null, C));\n  lua_register(L, 'GetRectMaxX', GetRectMaxX.bind(null, C));\n  lua_register(L, 'GetRectMaxY', GetRectMaxY.bind(null, C));\n  lua_register(L, 'CreateRegion', CreateRegion.bind(null, C));\n  lua_register(L, 'RemoveRegion', RemoveRegion.bind(null, C));\n  lua_register(L, 'RegionAddRect', RegionAddRect.bind(null, C));\n  lua_register(L, 'RegionClearRect', RegionClearRect.bind(null, C));\n  lua_register(L, 'RegionAddCell', RegionAddCell.bind(null, C));\n  lua_register(L, 'RegionAddCellAtLoc', RegionAddCellAtLoc.bind(null, C));\n  lua_register(L, 'RegionClearCell', RegionClearCell.bind(null, C));\n  lua_register(L, 'RegionClearCellAtLoc', RegionClearCellAtLoc.bind(null, C));\n  lua_register(L, 'Location', Location.bind(null, C));\n  lua_register(L, 'RemoveLocation', RemoveLocation.bind(null, C));\n  lua_register(L, 'MoveLocation', MoveLocation.bind(null, C));\n  lua_register(L, 'GetLocationX', GetLocationX.bind(null, C));\n  lua_register(L, 'GetLocationY', GetLocationY.bind(null, C));\n  lua_register(L, 'GetLocationZ', GetLocationZ.bind(null, C));\n  lua_register(L, 'IsUnitInRegion', IsUnitInRegion.bind(null, C));\n  lua_register(L, 'IsPointInRegion', IsPointInRegion.bind(null, C));\n  lua_register(L, 'IsLocationInRegion', IsLocationInRegion.bind(null, C));\n  lua_register(L, 'GetWorldBounds', GetWorldBounds.bind(null, C));\n  lua_register(L, 'CreateTrigger', CreateTrigger.bind(null, C));\n  lua_register(L, 'DestroyTrigger', DestroyTrigger.bind(null, C));\n  lua_register(L, 'ResetTrigger', ResetTrigger.bind(null, C));\n  lua_register(L, 'EnableTrigger', EnableTrigger.bind(null, C));\n  lua_register(L, 'DisableTrigger', DisableTrigger.bind(null, C));\n  lua_register(L, 'IsTriggerEnabled', IsTriggerEnabled.bind(null, C));\n  lua_register(L, 'TriggerWaitOnSleeps', TriggerWaitOnSleeps.bind(null, C));\n  lua_register(L, 'IsTriggerWaitOnSleeps', IsTriggerWaitOnSleeps.bind(null, C));\n  lua_register(L, 'GetFilterUnit', GetFilterUnit.bind(null, C));\n  lua_register(L, 'GetEnumUnit', GetEnumUnit.bind(null, C));\n  lua_register(L, 'GetFilterDestructable', GetFilterDestructable.bind(null, C));\n  lua_register(L, 'GetEnumDestructable', GetEnumDestructable.bind(null, C));\n  lua_register(L, 'GetFilterItem', GetFilterItem.bind(null, C));\n  lua_register(L, 'GetEnumItem', GetEnumItem.bind(null, C));\n  lua_register(L, 'GetFilterPlayer', GetFilterPlayer.bind(null, C));\n  lua_register(L, 'GetEnumPlayer', GetEnumPlayer.bind(null, C));\n  lua_register(L, 'GetTriggeringTrigger', GetTriggeringTrigger.bind(null, C));\n  lua_register(L, 'GetTriggerEventId', GetTriggerEventId.bind(null, C));\n  lua_register(L, 'GetTriggerEvalCount', GetTriggerEvalCount.bind(null, C));\n  lua_register(L, 'GetTriggerExecCount', GetTriggerExecCount.bind(null, C));\n  lua_register(L, 'ExecuteFunc', ExecuteFunc.bind(null, C));\n  lua_register(L, 'And', And.bind(null, C));\n  lua_register(L, 'Or', Or.bind(null, C));\n  lua_register(L, 'Not', Not.bind(null, C));\n  lua_register(L, 'Condition', Condition.bind(null, C));\n  lua_register(L, 'DestroyCondition', DestroyCondition.bind(null, C));\n  lua_register(L, 'Filter', Filter.bind(null, C));\n  lua_register(L, 'DestroyFilter', DestroyFilter.bind(null, C));\n  lua_register(L, 'DestroyBoolExpr', DestroyBoolExpr.bind(null, C));\n  lua_register(L, 'TriggerRegisterVariableEvent', TriggerRegisterVariableEvent.bind(null, C));\n  lua_register(L, 'TriggerRegisterTimerEvent', TriggerRegisterTimerEvent.bind(null, C));\n  lua_register(L, 'TriggerRegisterTimerExpireEvent', TriggerRegisterTimerExpireEvent.bind(null, C));\n  lua_register(L, 'TriggerRegisterGameStateEvent', TriggerRegisterGameStateEvent.bind(null, C));\n  lua_register(L, 'TriggerRegisterDialogEvent', TriggerRegisterDialogEvent.bind(null, C));\n  lua_register(L, 'TriggerRegisterDialogButtonEvent', TriggerRegisterDialogButtonEvent.bind(null, C));\n  lua_register(L, 'GetEventGameState', GetEventGameState.bind(null, C));\n  lua_register(L, 'TriggerRegisterGameEvent', TriggerRegisterGameEvent.bind(null, C));\n  lua_register(L, 'GetWinningPlayer', GetWinningPlayer.bind(null, C));\n  lua_register(L, 'TriggerRegisterEnterRegion', TriggerRegisterEnterRegion.bind(null, C));\n  lua_register(L, 'GetTriggeringRegion', GetTriggeringRegion.bind(null, C));\n  lua_register(L, 'GetEnteringUnit', GetEnteringUnit.bind(null, C));\n  lua_register(L, 'TriggerRegisterLeaveRegion', TriggerRegisterLeaveRegion.bind(null, C));\n  lua_register(L, 'GetLeavingUnit', GetLeavingUnit.bind(null, C));\n  lua_register(L, 'TriggerRegisterTrackableHitEvent', TriggerRegisterTrackableHitEvent.bind(null, C));\n  lua_register(L, 'TriggerRegisterTrackableTrackEvent', TriggerRegisterTrackableTrackEvent.bind(null, C));\n  lua_register(L, 'GetTriggeringTrackable', GetTriggeringTrackable.bind(null, C));\n  lua_register(L, 'GetClickedButton', GetClickedButton.bind(null, C));\n  lua_register(L, 'GetClickedDialog', GetClickedDialog.bind(null, C));\n  lua_register(L, 'GetTournamentFinishSoonTimeRemaining', GetTournamentFinishSoonTimeRemaining.bind(null, C));\n  lua_register(L, 'GetTournamentFinishNowRule', GetTournamentFinishNowRule.bind(null, C));\n  lua_register(L, 'GetTournamentFinishNowPlayer', GetTournamentFinishNowPlayer.bind(null, C));\n  lua_register(L, 'GetTournamentScore', GetTournamentScore.bind(null, C));\n  lua_register(L, 'GetSaveBasicFilename', GetSaveBasicFilename.bind(null, C));\n  lua_register(L, 'TriggerRegisterPlayerEvent', TriggerRegisterPlayerEvent.bind(null, C));\n  lua_register(L, 'GetTriggerPlayer', GetTriggerPlayer.bind(null, C));\n  lua_register(L, 'TriggerRegisterPlayerUnitEvent', TriggerRegisterPlayerUnitEvent.bind(null, C));\n  lua_register(L, 'GetLevelingUnit', GetLevelingUnit.bind(null, C));\n  lua_register(L, 'GetLearningUnit', GetLearningUnit.bind(null, C));\n  lua_register(L, 'GetLearnedSkill', GetLearnedSkill.bind(null, C));\n  lua_register(L, 'GetLearnedSkillLevel', GetLearnedSkillLevel.bind(null, C));\n  lua_register(L, 'GetRevivableUnit', GetRevivableUnit.bind(null, C));\n  lua_register(L, 'GetRevivingUnit', GetRevivingUnit.bind(null, C));\n  lua_register(L, 'GetAttacker', GetAttacker.bind(null, C));\n  lua_register(L, 'GetRescuer', GetRescuer.bind(null, C));\n  lua_register(L, 'GetDyingUnit', GetDyingUnit.bind(null, C));\n  lua_register(L, 'GetKillingUnit', GetKillingUnit.bind(null, C));\n  lua_register(L, 'GetDecayingUnit', GetDecayingUnit.bind(null, C));\n  lua_register(L, 'GetConstructingStructure', GetConstructingStructure.bind(null, C));\n  lua_register(L, 'GetCancelledStructure', GetCancelledStructure.bind(null, C));\n  lua_register(L, 'GetConstructedStructure', GetConstructedStructure.bind(null, C));\n  lua_register(L, 'GetResearchingUnit', GetResearchingUnit.bind(null, C));\n  lua_register(L, 'GetResearched', GetResearched.bind(null, C));\n  lua_register(L, 'GetTrainedUnitType', GetTrainedUnitType.bind(null, C));\n  lua_register(L, 'GetTrainedUnit', GetTrainedUnit.bind(null, C));\n  lua_register(L, 'GetDetectedUnit', GetDetectedUnit.bind(null, C));\n  lua_register(L, 'GetSummoningUnit', GetSummoningUnit.bind(null, C));\n  lua_register(L, 'GetSummonedUnit', GetSummonedUnit.bind(null, C));\n  lua_register(L, 'GetTransportUnit', GetTransportUnit.bind(null, C));\n  lua_register(L, 'GetLoadedUnit', GetLoadedUnit.bind(null, C));\n  lua_register(L, 'GetSellingUnit', GetSellingUnit.bind(null, C));\n  lua_register(L, 'GetSoldUnit', GetSoldUnit.bind(null, C));\n  lua_register(L, 'GetBuyingUnit', GetBuyingUnit.bind(null, C));\n  lua_register(L, 'GetSoldItem', GetSoldItem.bind(null, C));\n  lua_register(L, 'GetChangingUnit', GetChangingUnit.bind(null, C));\n  lua_register(L, 'GetChangingUnitPrevOwner', GetChangingUnitPrevOwner.bind(null, C));\n  lua_register(L, 'GetManipulatingUnit', GetManipulatingUnit.bind(null, C));\n  lua_register(L, 'GetManipulatedItem', GetManipulatedItem.bind(null, C));\n  lua_register(L, 'GetOrderedUnit', GetOrderedUnit.bind(null, C));\n  lua_register(L, 'GetIssuedOrderId', GetIssuedOrderId.bind(null, C));\n  lua_register(L, 'GetOrderPointX', GetOrderPointX.bind(null, C));\n  lua_register(L, 'GetOrderPointY', GetOrderPointY.bind(null, C));\n  lua_register(L, 'GetOrderPointLoc', GetOrderPointLoc.bind(null, C));\n  lua_register(L, 'GetOrderTarget', GetOrderTarget.bind(null, C));\n  lua_register(L, 'GetOrderTargetDestructable', GetOrderTargetDestructable.bind(null, C));\n  lua_register(L, 'GetOrderTargetItem', GetOrderTargetItem.bind(null, C));\n  lua_register(L, 'GetOrderTargetUnit', GetOrderTargetUnit.bind(null, C));\n  lua_register(L, 'GetSpellAbilityUnit', GetSpellAbilityUnit.bind(null, C));\n  lua_register(L, 'GetSpellAbilityId', GetSpellAbilityId.bind(null, C));\n  lua_register(L, 'GetSpellAbility', GetSpellAbility.bind(null, C));\n  lua_register(L, 'GetSpellTargetLoc', GetSpellTargetLoc.bind(null, C));\n  lua_register(L, 'GetSpellTargetX', GetSpellTargetX.bind(null, C));\n  lua_register(L, 'GetSpellTargetY', GetSpellTargetY.bind(null, C));\n  lua_register(L, 'GetSpellTargetDestructable', GetSpellTargetDestructable.bind(null, C));\n  lua_register(L, 'GetSpellTargetItem', GetSpellTargetItem.bind(null, C));\n  lua_register(L, 'GetSpellTargetUnit', GetSpellTargetUnit.bind(null, C));\n  lua_register(L, 'TriggerRegisterPlayerAllianceChange', TriggerRegisterPlayerAllianceChange.bind(null, C));\n  lua_register(L, 'TriggerRegisterPlayerStateEvent', TriggerRegisterPlayerStateEvent.bind(null, C));\n  lua_register(L, 'GetEventPlayerState', GetEventPlayerState.bind(null, C));\n  lua_register(L, 'TriggerRegisterPlayerChatEvent', TriggerRegisterPlayerChatEvent.bind(null, C));\n  lua_register(L, 'GetEventPlayerChatString', GetEventPlayerChatString.bind(null, C));\n  lua_register(L, 'GetEventPlayerChatStringMatched', GetEventPlayerChatStringMatched.bind(null, C));\n  lua_register(L, 'TriggerRegisterDeathEvent', TriggerRegisterDeathEvent.bind(null, C));\n  lua_register(L, 'GetTriggerUnit', GetTriggerUnit.bind(null, C));\n  lua_register(L, 'TriggerRegisterUnitStateEvent', TriggerRegisterUnitStateEvent.bind(null, C));\n  lua_register(L, 'GetEventUnitState', GetEventUnitState.bind(null, C));\n  lua_register(L, 'TriggerRegisterUnitEvent', TriggerRegisterUnitEvent.bind(null, C));\n  lua_register(L, 'GetEventDamage', GetEventDamage.bind(null, C));\n  lua_register(L, 'GetEventDamageSource', GetEventDamageSource.bind(null, C));\n  lua_register(L, 'GetEventDetectingPlayer', GetEventDetectingPlayer.bind(null, C));\n  lua_register(L, 'TriggerRegisterFilterUnitEvent', TriggerRegisterFilterUnitEvent.bind(null, C));\n  lua_register(L, 'GetEventTargetUnit', GetEventTargetUnit.bind(null, C));\n  lua_register(L, 'TriggerRegisterUnitInRange', TriggerRegisterUnitInRange.bind(null, C));\n  lua_register(L, 'TriggerAddCondition', TriggerAddCondition.bind(null, C));\n  lua_register(L, 'TriggerRemoveCondition', TriggerRemoveCondition.bind(null, C));\n  lua_register(L, 'TriggerClearConditions', TriggerClearConditions.bind(null, C));\n  lua_register(L, 'TriggerAddAction', TriggerAddAction.bind(null, C));\n  lua_register(L, 'TriggerRemoveAction', TriggerRemoveAction.bind(null, C));\n  lua_register(L, 'TriggerClearActions', TriggerClearActions.bind(null, C));\n  lua_register(L, 'TriggerSleepAction', TriggerSleepAction.bind(null, C));\n  lua_register(L, 'TriggerWaitForSound', TriggerWaitForSound.bind(null, C));\n  lua_register(L, 'TriggerEvaluate', TriggerEvaluate.bind(null, C));\n  lua_register(L, 'TriggerExecute', TriggerExecute.bind(null, C));\n  lua_register(L, 'TriggerExecuteWait', TriggerExecuteWait.bind(null, C));\n  lua_register(L, 'TriggerSyncStart', TriggerSyncStart.bind(null, C));\n  lua_register(L, 'TriggerSyncReady', TriggerSyncReady.bind(null, C));\n  lua_register(L, 'GetWidgetLife', GetWidgetLife.bind(null, C));\n  lua_register(L, 'SetWidgetLife', SetWidgetLife.bind(null, C));\n  lua_register(L, 'GetWidgetX', GetWidgetX.bind(null, C));\n  lua_register(L, 'GetWidgetY', GetWidgetY.bind(null, C));\n  lua_register(L, 'GetTriggerWidget', GetTriggerWidget.bind(null, C));\n  lua_register(L, 'CreateDestructable', CreateDestructable.bind(null, C));\n  lua_register(L, 'CreateDestructableZ', CreateDestructableZ.bind(null, C));\n  lua_register(L, 'CreateDeadDestructable', CreateDeadDestructable.bind(null, C));\n  lua_register(L, 'CreateDeadDestructableZ', CreateDeadDestructableZ.bind(null, C));\n  lua_register(L, 'RemoveDestructable', RemoveDestructable.bind(null, C));\n  lua_register(L, 'KillDestructable', KillDestructable.bind(null, C));\n  lua_register(L, 'SetDestructableInvulnerable', SetDestructableInvulnerable.bind(null, C));\n  lua_register(L, 'IsDestructableInvulnerable', IsDestructableInvulnerable.bind(null, C));\n  lua_register(L, 'EnumDestructablesInRect', EnumDestructablesInRect.bind(null, C));\n  lua_register(L, 'GetDestructableTypeId', GetDestructableTypeId.bind(null, C));\n  lua_register(L, 'GetDestructableX', GetDestructableX.bind(null, C));\n  lua_register(L, 'GetDestructableY', GetDestructableY.bind(null, C));\n  lua_register(L, 'SetDestructableLife', SetDestructableLife.bind(null, C));\n  lua_register(L, 'GetDestructableLife', GetDestructableLife.bind(null, C));\n  lua_register(L, 'SetDestructableMaxLife', SetDestructableMaxLife.bind(null, C));\n  lua_register(L, 'GetDestructableMaxLife', GetDestructableMaxLife.bind(null, C));\n  lua_register(L, 'DestructableRestoreLife', DestructableRestoreLife.bind(null, C));\n  lua_register(L, 'QueueDestructableAnimation', QueueDestructableAnimation.bind(null, C));\n  lua_register(L, 'SetDestructableAnimation', SetDestructableAnimation.bind(null, C));\n  lua_register(L, 'SetDestructableAnimationSpeed', SetDestructableAnimationSpeed.bind(null, C));\n  lua_register(L, 'ShowDestructable', ShowDestructable.bind(null, C));\n  lua_register(L, 'GetDestructableOccluderHeight', GetDestructableOccluderHeight.bind(null, C));\n  lua_register(L, 'SetDestructableOccluderHeight', SetDestructableOccluderHeight.bind(null, C));\n  lua_register(L, 'GetDestructableName', GetDestructableName.bind(null, C));\n  lua_register(L, 'GetTriggerDestructable', GetTriggerDestructable.bind(null, C));\n  lua_register(L, 'CreateItem', CreateItem.bind(null, C));\n  lua_register(L, 'RemoveItem', RemoveItem.bind(null, C));\n  lua_register(L, 'GetItemPlayer', GetItemPlayer.bind(null, C));\n  lua_register(L, 'GetItemTypeId', GetItemTypeId.bind(null, C));\n  lua_register(L, 'GetItemX', GetItemX.bind(null, C));\n  lua_register(L, 'GetItemY', GetItemY.bind(null, C));\n  lua_register(L, 'SetItemPosition', SetItemPosition.bind(null, C));\n  lua_register(L, 'SetItemDropOnDeath', SetItemDropOnDeath.bind(null, C));\n  lua_register(L, 'SetItemDroppable', SetItemDroppable.bind(null, C));\n  lua_register(L, 'SetItemPawnable', SetItemPawnable.bind(null, C));\n  lua_register(L, 'SetItemPlayer', SetItemPlayer.bind(null, C));\n  lua_register(L, 'SetItemInvulnerable', SetItemInvulnerable.bind(null, C));\n  lua_register(L, 'IsItemInvulnerable', IsItemInvulnerable.bind(null, C));\n  lua_register(L, 'SetItemVisible', SetItemVisible.bind(null, C));\n  lua_register(L, 'IsItemVisible', IsItemVisible.bind(null, C));\n  lua_register(L, 'IsItemOwned', IsItemOwned.bind(null, C));\n  lua_register(L, 'IsItemPowerup', IsItemPowerup.bind(null, C));\n  lua_register(L, 'IsItemSellable', IsItemSellable.bind(null, C));\n  lua_register(L, 'IsItemPawnable', IsItemPawnable.bind(null, C));\n  lua_register(L, 'IsItemIdPowerup', IsItemIdPowerup.bind(null, C));\n  lua_register(L, 'IsItemIdSellable', IsItemIdSellable.bind(null, C));\n  lua_register(L, 'IsItemIdPawnable', IsItemIdPawnable.bind(null, C));\n  lua_register(L, 'EnumItemsInRect', EnumItemsInRect.bind(null, C));\n  lua_register(L, 'GetItemLevel', GetItemLevel.bind(null, C));\n  lua_register(L, 'GetItemType', GetItemType.bind(null, C));\n  lua_register(L, 'SetItemDropID', SetItemDropID.bind(null, C));\n  lua_register(L, 'GetItemName', GetItemName.bind(null, C));\n  lua_register(L, 'GetItemCharges', GetItemCharges.bind(null, C));\n  lua_register(L, 'SetItemCharges', SetItemCharges.bind(null, C));\n  lua_register(L, 'GetItemUserData', GetItemUserData.bind(null, C));\n  lua_register(L, 'SetItemUserData', SetItemUserData.bind(null, C));\n  lua_register(L, 'CreateUnit', CreateUnit.bind(null, C));\n  lua_register(L, 'CreateUnitByName', CreateUnitByName.bind(null, C));\n  lua_register(L, 'CreateUnitAtLoc', CreateUnitAtLoc.bind(null, C));\n  lua_register(L, 'CreateUnitAtLocByName', CreateUnitAtLocByName.bind(null, C));\n  lua_register(L, 'CreateCorpse', CreateCorpse.bind(null, C));\n  lua_register(L, 'KillUnit', KillUnit.bind(null, C));\n  lua_register(L, 'RemoveUnit', RemoveUnit.bind(null, C));\n  lua_register(L, 'ShowUnit', ShowUnit.bind(null, C));\n  lua_register(L, 'SetUnitState', SetUnitState.bind(null, C));\n  lua_register(L, 'SetUnitX', SetUnitX.bind(null, C));\n  lua_register(L, 'SetUnitY', SetUnitY.bind(null, C));\n  lua_register(L, 'SetUnitPosition', SetUnitPosition.bind(null, C));\n  lua_register(L, 'SetUnitPositionLoc', SetUnitPositionLoc.bind(null, C));\n  lua_register(L, 'SetUnitFacing', SetUnitFacing.bind(null, C));\n  lua_register(L, 'SetUnitFacingTimed', SetUnitFacingTimed.bind(null, C));\n  lua_register(L, 'SetUnitMoveSpeed', SetUnitMoveSpeed.bind(null, C));\n  lua_register(L, 'SetUnitFlyHeight', SetUnitFlyHeight.bind(null, C));\n  lua_register(L, 'SetUnitTurnSpeed', SetUnitTurnSpeed.bind(null, C));\n  lua_register(L, 'SetUnitPropWindow', SetUnitPropWindow.bind(null, C));\n  lua_register(L, 'SetUnitAcquireRange', SetUnitAcquireRange.bind(null, C));\n  lua_register(L, 'SetUnitCreepGuard', SetUnitCreepGuard.bind(null, C));\n  lua_register(L, 'GetUnitAcquireRange', GetUnitAcquireRange.bind(null, C));\n  lua_register(L, 'GetUnitTurnSpeed', GetUnitTurnSpeed.bind(null, C));\n  lua_register(L, 'GetUnitPropWindow', GetUnitPropWindow.bind(null, C));\n  lua_register(L, 'GetUnitFlyHeight', GetUnitFlyHeight.bind(null, C));\n  lua_register(L, 'GetUnitDefaultAcquireRange', GetUnitDefaultAcquireRange.bind(null, C));\n  lua_register(L, 'GetUnitDefaultTurnSpeed', GetUnitDefaultTurnSpeed.bind(null, C));\n  lua_register(L, 'GetUnitDefaultPropWindow', GetUnitDefaultPropWindow.bind(null, C));\n  lua_register(L, 'GetUnitDefaultFlyHeight', GetUnitDefaultFlyHeight.bind(null, C));\n  lua_register(L, 'SetUnitOwner', SetUnitOwner.bind(null, C));\n  lua_register(L, 'SetUnitColor', SetUnitColor.bind(null, C));\n  lua_register(L, 'SetUnitScale', SetUnitScale.bind(null, C));\n  lua_register(L, 'SetUnitTimeScale', SetUnitTimeScale.bind(null, C));\n  lua_register(L, 'SetUnitBlendTime', SetUnitBlendTime.bind(null, C));\n  lua_register(L, 'SetUnitVertexColor', SetUnitVertexColor.bind(null, C));\n  lua_register(L, 'QueueUnitAnimation', QueueUnitAnimation.bind(null, C));\n  lua_register(L, 'SetUnitAnimation', SetUnitAnimation.bind(null, C));\n  lua_register(L, 'SetUnitAnimationByIndex', SetUnitAnimationByIndex.bind(null, C));\n  lua_register(L, 'SetUnitAnimationWithRarity', SetUnitAnimationWithRarity.bind(null, C));\n  lua_register(L, 'AddUnitAnimationProperties', AddUnitAnimationProperties.bind(null, C));\n  lua_register(L, 'SetUnitLookAt', SetUnitLookAt.bind(null, C));\n  lua_register(L, 'ResetUnitLookAt', ResetUnitLookAt.bind(null, C));\n  lua_register(L, 'SetUnitRescuable', SetUnitRescuable.bind(null, C));\n  lua_register(L, 'SetUnitRescueRange', SetUnitRescueRange.bind(null, C));\n  lua_register(L, 'SetHeroStr', SetHeroStr.bind(null, C));\n  lua_register(L, 'SetHeroAgi', SetHeroAgi.bind(null, C));\n  lua_register(L, 'SetHeroInt', SetHeroInt.bind(null, C));\n  lua_register(L, 'GetHeroStr', GetHeroStr.bind(null, C));\n  lua_register(L, 'GetHeroAgi', GetHeroAgi.bind(null, C));\n  lua_register(L, 'GetHeroInt', GetHeroInt.bind(null, C));\n  lua_register(L, 'UnitStripHeroLevel', UnitStripHeroLevel.bind(null, C));\n  lua_register(L, 'GetHeroXP', GetHeroXP.bind(null, C));\n  lua_register(L, 'SetHeroXP', SetHeroXP.bind(null, C));\n  lua_register(L, 'GetHeroSkillPoints', GetHeroSkillPoints.bind(null, C));\n  lua_register(L, 'UnitModifySkillPoints', UnitModifySkillPoints.bind(null, C));\n  lua_register(L, 'AddHeroXP', AddHeroXP.bind(null, C));\n  lua_register(L, 'SetHeroLevel', SetHeroLevel.bind(null, C));\n  lua_register(L, 'GetHeroLevel', GetHeroLevel.bind(null, C));\n  lua_register(L, 'GetUnitLevel', GetUnitLevel.bind(null, C));\n  lua_register(L, 'GetHeroProperName', GetHeroProperName.bind(null, C));\n  lua_register(L, 'SuspendHeroXP', SuspendHeroXP.bind(null, C));\n  lua_register(L, 'IsSuspendedXP', IsSuspendedXP.bind(null, C));\n  lua_register(L, 'SelectHeroSkill', SelectHeroSkill.bind(null, C));\n  lua_register(L, 'GetUnitAbilityLevel', GetUnitAbilityLevel.bind(null, C));\n  lua_register(L, 'DecUnitAbilityLevel', DecUnitAbilityLevel.bind(null, C));\n  lua_register(L, 'IncUnitAbilityLevel', IncUnitAbilityLevel.bind(null, C));\n  lua_register(L, 'SetUnitAbilityLevel', SetUnitAbilityLevel.bind(null, C));\n  lua_register(L, 'ReviveHero', ReviveHero.bind(null, C));\n  lua_register(L, 'ReviveHeroLoc', ReviveHeroLoc.bind(null, C));\n  lua_register(L, 'SetUnitExploded', SetUnitExploded.bind(null, C));\n  lua_register(L, 'SetUnitInvulnerable', SetUnitInvulnerable.bind(null, C));\n  lua_register(L, 'PauseUnit', PauseUnit.bind(null, C));\n  lua_register(L, 'IsUnitPaused', IsUnitPaused.bind(null, C));\n  lua_register(L, 'SetUnitPathing', SetUnitPathing.bind(null, C));\n  lua_register(L, 'ClearSelection', ClearSelection.bind(null, C));\n  lua_register(L, 'SelectUnit', SelectUnit.bind(null, C));\n  lua_register(L, 'GetUnitPointValue', GetUnitPointValue.bind(null, C));\n  lua_register(L, 'GetUnitPointValueByType', GetUnitPointValueByType.bind(null, C));\n  lua_register(L, 'UnitAddItem', UnitAddItem.bind(null, C));\n  lua_register(L, 'UnitAddItemById', UnitAddItemById.bind(null, C));\n  lua_register(L, 'UnitAddItemToSlotById', UnitAddItemToSlotById.bind(null, C));\n  lua_register(L, 'UnitRemoveItem', UnitRemoveItem.bind(null, C));\n  lua_register(L, 'UnitRemoveItemFromSlot', UnitRemoveItemFromSlot.bind(null, C));\n  lua_register(L, 'UnitHasItem', UnitHasItem.bind(null, C));\n  lua_register(L, 'UnitItemInSlot', UnitItemInSlot.bind(null, C));\n  lua_register(L, 'UnitInventorySize', UnitInventorySize.bind(null, C));\n  lua_register(L, 'UnitDropItemPoint', UnitDropItemPoint.bind(null, C));\n  lua_register(L, 'UnitDropItemSlot', UnitDropItemSlot.bind(null, C));\n  lua_register(L, 'UnitDropItemTarget', UnitDropItemTarget.bind(null, C));\n  lua_register(L, 'UnitUseItem', UnitUseItem.bind(null, C));\n  lua_register(L, 'UnitUseItemPoint', UnitUseItemPoint.bind(null, C));\n  lua_register(L, 'UnitUseItemTarget', UnitUseItemTarget.bind(null, C));\n  lua_register(L, 'GetUnitX', GetUnitX.bind(null, C));\n  lua_register(L, 'GetUnitY', GetUnitY.bind(null, C));\n  lua_register(L, 'GetUnitLoc', GetUnitLoc.bind(null, C));\n  lua_register(L, 'GetUnitFacing', GetUnitFacing.bind(null, C));\n  lua_register(L, 'GetUnitMoveSpeed', GetUnitMoveSpeed.bind(null, C));\n  lua_register(L, 'GetUnitDefaultMoveSpeed', GetUnitDefaultMoveSpeed.bind(null, C));\n  lua_register(L, 'GetUnitState', GetUnitState.bind(null, C));\n  lua_register(L, 'GetOwningPlayer', GetOwningPlayer.bind(null, C));\n  lua_register(L, 'GetUnitTypeId', GetUnitTypeId.bind(null, C));\n  lua_register(L, 'GetUnitRace', GetUnitRace.bind(null, C));\n  lua_register(L, 'GetUnitName', GetUnitName.bind(null, C));\n  lua_register(L, 'GetUnitFoodUsed', GetUnitFoodUsed.bind(null, C));\n  lua_register(L, 'GetUnitFoodMade', GetUnitFoodMade.bind(null, C));\n  lua_register(L, 'GetFoodMade', GetFoodMade.bind(null, C));\n  lua_register(L, 'GetFoodUsed', GetFoodUsed.bind(null, C));\n  lua_register(L, 'SetUnitUseFood', SetUnitUseFood.bind(null, C));\n  lua_register(L, 'GetUnitRallyPoint', GetUnitRallyPoint.bind(null, C));\n  lua_register(L, 'GetUnitRallyUnit', GetUnitRallyUnit.bind(null, C));\n  lua_register(L, 'GetUnitRallyDestructable', GetUnitRallyDestructable.bind(null, C));\n  lua_register(L, 'IsUnitInGroup', IsUnitInGroup.bind(null, C));\n  lua_register(L, 'IsUnitInForce', IsUnitInForce.bind(null, C));\n  lua_register(L, 'IsUnitOwnedByPlayer', IsUnitOwnedByPlayer.bind(null, C));\n  lua_register(L, 'IsUnitAlly', IsUnitAlly.bind(null, C));\n  lua_register(L, 'IsUnitEnemy', IsUnitEnemy.bind(null, C));\n  lua_register(L, 'IsUnitVisible', IsUnitVisible.bind(null, C));\n  lua_register(L, 'IsUnitDetected', IsUnitDetected.bind(null, C));\n  lua_register(L, 'IsUnitInvisible', IsUnitInvisible.bind(null, C));\n  lua_register(L, 'IsUnitFogged', IsUnitFogged.bind(null, C));\n  lua_register(L, 'IsUnitMasked', IsUnitMasked.bind(null, C));\n  lua_register(L, 'IsUnitSelected', IsUnitSelected.bind(null, C));\n  lua_register(L, 'IsUnitRace', IsUnitRace.bind(null, C));\n  lua_register(L, 'IsUnitType', IsUnitType.bind(null, C));\n  lua_register(L, 'IsUnit', IsUnit.bind(null, C));\n  lua_register(L, 'IsUnitInRange', IsUnitInRange.bind(null, C));\n  lua_register(L, 'IsUnitInRangeXY', IsUnitInRangeXY.bind(null, C));\n  lua_register(L, 'IsUnitInRangeLoc', IsUnitInRangeLoc.bind(null, C));\n  lua_register(L, 'IsUnitHidden', IsUnitHidden.bind(null, C));\n  lua_register(L, 'IsUnitIllusion', IsUnitIllusion.bind(null, C));\n  lua_register(L, 'IsUnitInTransport', IsUnitInTransport.bind(null, C));\n  lua_register(L, 'IsUnitLoaded', IsUnitLoaded.bind(null, C));\n  lua_register(L, 'IsHeroUnitId', IsHeroUnitId.bind(null, C));\n  lua_register(L, 'IsUnitIdType', IsUnitIdType.bind(null, C));\n  lua_register(L, 'UnitShareVision', UnitShareVision.bind(null, C));\n  lua_register(L, 'UnitSuspendDecay', UnitSuspendDecay.bind(null, C));\n  lua_register(L, 'UnitAddType', UnitAddType.bind(null, C));\n  lua_register(L, 'UnitRemoveType', UnitRemoveType.bind(null, C));\n  lua_register(L, 'UnitAddAbility', UnitAddAbility.bind(null, C));\n  lua_register(L, 'UnitRemoveAbility', UnitRemoveAbility.bind(null, C));\n  lua_register(L, 'UnitMakeAbilityPermanent', UnitMakeAbilityPermanent.bind(null, C));\n  lua_register(L, 'UnitRemoveBuffs', UnitRemoveBuffs.bind(null, C));\n  lua_register(L, 'UnitRemoveBuffsEx', UnitRemoveBuffsEx.bind(null, C));\n  lua_register(L, 'UnitHasBuffsEx', UnitHasBuffsEx.bind(null, C));\n  lua_register(L, 'UnitCountBuffsEx', UnitCountBuffsEx.bind(null, C));\n  lua_register(L, 'UnitAddSleep', UnitAddSleep.bind(null, C));\n  lua_register(L, 'UnitCanSleep', UnitCanSleep.bind(null, C));\n  lua_register(L, 'UnitAddSleepPerm', UnitAddSleepPerm.bind(null, C));\n  lua_register(L, 'UnitCanSleepPerm', UnitCanSleepPerm.bind(null, C));\n  lua_register(L, 'UnitIsSleeping', UnitIsSleeping.bind(null, C));\n  lua_register(L, 'UnitWakeUp', UnitWakeUp.bind(null, C));\n  lua_register(L, 'UnitApplyTimedLife', UnitApplyTimedLife.bind(null, C));\n  lua_register(L, 'UnitIgnoreAlarm', UnitIgnoreAlarm.bind(null, C));\n  lua_register(L, 'UnitIgnoreAlarmToggled', UnitIgnoreAlarmToggled.bind(null, C));\n  lua_register(L, 'UnitResetCooldown', UnitResetCooldown.bind(null, C));\n  lua_register(L, 'UnitSetConstructionProgress', UnitSetConstructionProgress.bind(null, C));\n  lua_register(L, 'UnitSetUpgradeProgress', UnitSetUpgradeProgress.bind(null, C));\n  lua_register(L, 'UnitPauseTimedLife', UnitPauseTimedLife.bind(null, C));\n  lua_register(L, 'UnitSetUsesAltIcon', UnitSetUsesAltIcon.bind(null, C));\n  lua_register(L, 'UnitDamagePoint', UnitDamagePoint.bind(null, C));\n  lua_register(L, 'UnitDamageTarget', UnitDamageTarget.bind(null, C));\n  lua_register(L, 'IssueImmediateOrder', IssueImmediateOrder.bind(null, C));\n  lua_register(L, 'IssueImmediateOrderById', IssueImmediateOrderById.bind(null, C));\n  lua_register(L, 'IssuePointOrder', IssuePointOrder.bind(null, C));\n  lua_register(L, 'IssuePointOrderLoc', IssuePointOrderLoc.bind(null, C));\n  lua_register(L, 'IssuePointOrderById', IssuePointOrderById.bind(null, C));\n  lua_register(L, 'IssuePointOrderByIdLoc', IssuePointOrderByIdLoc.bind(null, C));\n  lua_register(L, 'IssueTargetOrder', IssueTargetOrder.bind(null, C));\n  lua_register(L, 'IssueTargetOrderById', IssueTargetOrderById.bind(null, C));\n  lua_register(L, 'IssueInstantPointOrder', IssueInstantPointOrder.bind(null, C));\n  lua_register(L, 'IssueInstantPointOrderById', IssueInstantPointOrderById.bind(null, C));\n  lua_register(L, 'IssueInstantTargetOrder', IssueInstantTargetOrder.bind(null, C));\n  lua_register(L, 'IssueInstantTargetOrderById', IssueInstantTargetOrderById.bind(null, C));\n  lua_register(L, 'IssueBuildOrder', IssueBuildOrder.bind(null, C));\n  lua_register(L, 'IssueBuildOrderById', IssueBuildOrderById.bind(null, C));\n  lua_register(L, 'IssueNeutralImmediateOrder', IssueNeutralImmediateOrder.bind(null, C));\n  lua_register(L, 'IssueNeutralImmediateOrderById', IssueNeutralImmediateOrderById.bind(null, C));\n  lua_register(L, 'IssueNeutralPointOrder', IssueNeutralPointOrder.bind(null, C));\n  lua_register(L, 'IssueNeutralPointOrderById', IssueNeutralPointOrderById.bind(null, C));\n  lua_register(L, 'IssueNeutralTargetOrder', IssueNeutralTargetOrder.bind(null, C));\n  lua_register(L, 'IssueNeutralTargetOrderById', IssueNeutralTargetOrderById.bind(null, C));\n  lua_register(L, 'GetUnitCurrentOrder', GetUnitCurrentOrder.bind(null, C));\n  lua_register(L, 'SetResourceAmount', SetResourceAmount.bind(null, C));\n  lua_register(L, 'AddResourceAmount', AddResourceAmount.bind(null, C));\n  lua_register(L, 'GetResourceAmount', GetResourceAmount.bind(null, C));\n  lua_register(L, 'WaygateGetDestinationX', WaygateGetDestinationX.bind(null, C));\n  lua_register(L, 'WaygateGetDestinationY', WaygateGetDestinationY.bind(null, C));\n  lua_register(L, 'WaygateSetDestination', WaygateSetDestination.bind(null, C));\n  lua_register(L, 'WaygateActivate', WaygateActivate.bind(null, C));\n  lua_register(L, 'WaygateIsActive', WaygateIsActive.bind(null, C));\n  lua_register(L, 'AddItemToAllStock', AddItemToAllStock.bind(null, C));\n  lua_register(L, 'AddItemToStock', AddItemToStock.bind(null, C));\n  lua_register(L, 'AddUnitToAllStock', AddUnitToAllStock.bind(null, C));\n  lua_register(L, 'AddUnitToStock', AddUnitToStock.bind(null, C));\n  lua_register(L, 'RemoveItemFromAllStock', RemoveItemFromAllStock.bind(null, C));\n  lua_register(L, 'RemoveItemFromStock', RemoveItemFromStock.bind(null, C));\n  lua_register(L, 'RemoveUnitFromAllStock', RemoveUnitFromAllStock.bind(null, C));\n  lua_register(L, 'RemoveUnitFromStock', RemoveUnitFromStock.bind(null, C));\n  lua_register(L, 'SetAllItemTypeSlots', SetAllItemTypeSlots.bind(null, C));\n  lua_register(L, 'SetAllUnitTypeSlots', SetAllUnitTypeSlots.bind(null, C));\n  lua_register(L, 'SetItemTypeSlots', SetItemTypeSlots.bind(null, C));\n  lua_register(L, 'SetUnitTypeSlots', SetUnitTypeSlots.bind(null, C));\n  lua_register(L, 'GetUnitUserData', GetUnitUserData.bind(null, C));\n  lua_register(L, 'SetUnitUserData', SetUnitUserData.bind(null, C));\n  lua_register(L, 'Player', Player.bind(null, C));\n  lua_register(L, 'GetLocalPlayer', GetLocalPlayer.bind(null, C));\n  lua_register(L, 'IsPlayerAlly', IsPlayerAlly.bind(null, C));\n  lua_register(L, 'IsPlayerEnemy', IsPlayerEnemy.bind(null, C));\n  lua_register(L, 'IsPlayerInForce', IsPlayerInForce.bind(null, C));\n  lua_register(L, 'IsPlayerObserver', IsPlayerObserver.bind(null, C));\n  lua_register(L, 'IsVisibleToPlayer', IsVisibleToPlayer.bind(null, C));\n  lua_register(L, 'IsLocationVisibleToPlayer', IsLocationVisibleToPlayer.bind(null, C));\n  lua_register(L, 'IsFoggedToPlayer', IsFoggedToPlayer.bind(null, C));\n  lua_register(L, 'IsLocationFoggedToPlayer', IsLocationFoggedToPlayer.bind(null, C));\n  lua_register(L, 'IsMaskedToPlayer', IsMaskedToPlayer.bind(null, C));\n  lua_register(L, 'IsLocationMaskedToPlayer', IsLocationMaskedToPlayer.bind(null, C));\n  lua_register(L, 'GetPlayerRace', GetPlayerRace.bind(null, C));\n  lua_register(L, 'GetPlayerId', GetPlayerId.bind(null, C));\n  lua_register(L, 'GetPlayerUnitCount', GetPlayerUnitCount.bind(null, C));\n  lua_register(L, 'GetPlayerTypedUnitCount', GetPlayerTypedUnitCount.bind(null, C));\n  lua_register(L, 'GetPlayerStructureCount', GetPlayerStructureCount.bind(null, C));\n  lua_register(L, 'GetPlayerState', GetPlayerState.bind(null, C));\n  lua_register(L, 'GetPlayerScore', GetPlayerScore.bind(null, C));\n  lua_register(L, 'GetPlayerAlliance', GetPlayerAlliance.bind(null, C));\n  lua_register(L, 'GetPlayerHandicap', GetPlayerHandicap.bind(null, C));\n  lua_register(L, 'GetPlayerHandicapXP', GetPlayerHandicapXP.bind(null, C));\n  lua_register(L, 'SetPlayerHandicap', SetPlayerHandicap.bind(null, C));\n  lua_register(L, 'SetPlayerHandicapXP', SetPlayerHandicapXP.bind(null, C));\n  lua_register(L, 'SetPlayerTechMaxAllowed', SetPlayerTechMaxAllowed.bind(null, C));\n  lua_register(L, 'GetPlayerTechMaxAllowed', GetPlayerTechMaxAllowed.bind(null, C));\n  lua_register(L, 'AddPlayerTechResearched', AddPlayerTechResearched.bind(null, C));\n  lua_register(L, 'SetPlayerTechResearched', SetPlayerTechResearched.bind(null, C));\n  lua_register(L, 'GetPlayerTechResearched', GetPlayerTechResearched.bind(null, C));\n  lua_register(L, 'GetPlayerTechCount', GetPlayerTechCount.bind(null, C));\n  lua_register(L, 'SetPlayerUnitsOwner', SetPlayerUnitsOwner.bind(null, C));\n  lua_register(L, 'CripplePlayer', CripplePlayer.bind(null, C));\n  lua_register(L, 'SetPlayerAbilityAvailable', SetPlayerAbilityAvailable.bind(null, C));\n  lua_register(L, 'SetPlayerState', SetPlayerState.bind(null, C));\n  lua_register(L, 'RemovePlayer', RemovePlayer.bind(null, C));\n  lua_register(L, 'CachePlayerHeroData', CachePlayerHeroData.bind(null, C));\n  lua_register(L, 'SetFogStateRect', SetFogStateRect.bind(null, C));\n  lua_register(L, 'SetFogStateRadius', SetFogStateRadius.bind(null, C));\n  lua_register(L, 'SetFogStateRadiusLoc', SetFogStateRadiusLoc.bind(null, C));\n  lua_register(L, 'FogMaskEnable', FogMaskEnable.bind(null, C));\n  lua_register(L, 'IsFogMaskEnabled', IsFogMaskEnabled.bind(null, C));\n  lua_register(L, 'FogEnable', FogEnable.bind(null, C));\n  lua_register(L, 'IsFogEnabled', IsFogEnabled.bind(null, C));\n  lua_register(L, 'CreateFogModifierRect', CreateFogModifierRect.bind(null, C));\n  lua_register(L, 'CreateFogModifierRadius', CreateFogModifierRadius.bind(null, C));\n  lua_register(L, 'CreateFogModifierRadiusLoc', CreateFogModifierRadiusLoc.bind(null, C));\n  lua_register(L, 'DestroyFogModifier', DestroyFogModifier.bind(null, C));\n  lua_register(L, 'FogModifierStart', FogModifierStart.bind(null, C));\n  lua_register(L, 'FogModifierStop', FogModifierStop.bind(null, C));\n  lua_register(L, 'VersionGet', VersionGet.bind(null, C));\n  lua_register(L, 'VersionCompatible', VersionCompatible.bind(null, C));\n  lua_register(L, 'VersionSupported', VersionSupported.bind(null, C));\n  lua_register(L, 'EndGame', EndGame.bind(null, C));\n  lua_register(L, 'ChangeLevel', ChangeLevel.bind(null, C));\n  lua_register(L, 'RestartGame', RestartGame.bind(null, C));\n  lua_register(L, 'ReloadGame', ReloadGame.bind(null, C));\n  lua_register(L, 'SetCampaignMenuRace', SetCampaignMenuRace.bind(null, C));\n  lua_register(L, 'SetCampaignMenuRaceEx', SetCampaignMenuRaceEx.bind(null, C));\n  lua_register(L, 'ForceCampaignSelectScreen', ForceCampaignSelectScreen.bind(null, C));\n  lua_register(L, 'LoadGame', LoadGame.bind(null, C));\n  lua_register(L, 'SaveGame', SaveGame.bind(null, C));\n  lua_register(L, 'RenameSaveDirectory', RenameSaveDirectory.bind(null, C));\n  lua_register(L, 'RemoveSaveDirectory', RemoveSaveDirectory.bind(null, C));\n  lua_register(L, 'CopySaveGame', CopySaveGame.bind(null, C));\n  lua_register(L, 'SaveGameExists', SaveGameExists.bind(null, C));\n  lua_register(L, 'SyncSelections', SyncSelections.bind(null, C));\n  lua_register(L, 'SetFloatGameState', SetFloatGameState.bind(null, C));\n  lua_register(L, 'GetFloatGameState', GetFloatGameState.bind(null, C));\n  lua_register(L, 'SetIntegerGameState', SetIntegerGameState.bind(null, C));\n  lua_register(L, 'GetIntegerGameState', GetIntegerGameState.bind(null, C));\n  lua_register(L, 'SetTutorialCleared', SetTutorialCleared.bind(null, C));\n  lua_register(L, 'SetMissionAvailable', SetMissionAvailable.bind(null, C));\n  lua_register(L, 'SetCampaignAvailable', SetCampaignAvailable.bind(null, C));\n  lua_register(L, 'SetOpCinematicAvailable', SetOpCinematicAvailable.bind(null, C));\n  lua_register(L, 'SetEdCinematicAvailable', SetEdCinematicAvailable.bind(null, C));\n  lua_register(L, 'GetDefaultDifficulty', GetDefaultDifficulty.bind(null, C));\n  lua_register(L, 'SetDefaultDifficulty', SetDefaultDifficulty.bind(null, C));\n  lua_register(L, 'SetCustomCampaignButtonVisible', SetCustomCampaignButtonVisible.bind(null, C));\n  lua_register(L, 'GetCustomCampaignButtonVisible', GetCustomCampaignButtonVisible.bind(null, C));\n  lua_register(L, 'DoNotSaveReplay', DoNotSaveReplay.bind(null, C));\n  lua_register(L, 'DialogCreate', DialogCreate.bind(null, C));\n  lua_register(L, 'DialogDestroy', DialogDestroy.bind(null, C));\n  lua_register(L, 'DialogClear', DialogClear.bind(null, C));\n  lua_register(L, 'DialogSetMessage', DialogSetMessage.bind(null, C));\n  lua_register(L, 'DialogAddButton', DialogAddButton.bind(null, C));\n  lua_register(L, 'DialogAddQuitButton', DialogAddQuitButton.bind(null, C));\n  lua_register(L, 'DialogDisplay', DialogDisplay.bind(null, C));\n  lua_register(L, 'ReloadGameCachesFromDisk', ReloadGameCachesFromDisk.bind(null, C));\n  lua_register(L, 'InitGameCache', InitGameCache.bind(null, C));\n  lua_register(L, 'SaveGameCache', SaveGameCache.bind(null, C));\n  lua_register(L, 'StoreInteger', StoreInteger.bind(null, C));\n  lua_register(L, 'StoreReal', StoreReal.bind(null, C));\n  lua_register(L, 'StoreBoolean', StoreBoolean.bind(null, C));\n  lua_register(L, 'StoreUnit', StoreUnit.bind(null, C));\n  lua_register(L, 'StoreString', StoreString.bind(null, C));\n  lua_register(L, 'SyncStoredInteger', SyncStoredInteger.bind(null, C));\n  lua_register(L, 'SyncStoredReal', SyncStoredReal.bind(null, C));\n  lua_register(L, 'SyncStoredBoolean', SyncStoredBoolean.bind(null, C));\n  lua_register(L, 'SyncStoredUnit', SyncStoredUnit.bind(null, C));\n  lua_register(L, 'SyncStoredString', SyncStoredString.bind(null, C));\n  lua_register(L, 'HaveStoredInteger', HaveStoredInteger.bind(null, C));\n  lua_register(L, 'HaveStoredReal', HaveStoredReal.bind(null, C));\n  lua_register(L, 'HaveStoredBoolean', HaveStoredBoolean.bind(null, C));\n  lua_register(L, 'HaveStoredUnit', HaveStoredUnit.bind(null, C));\n  lua_register(L, 'HaveStoredString', HaveStoredString.bind(null, C));\n  lua_register(L, 'FlushGameCache', FlushGameCache.bind(null, C));\n  lua_register(L, 'FlushStoredMission', FlushStoredMission.bind(null, C));\n  lua_register(L, 'FlushStoredInteger', FlushStoredInteger.bind(null, C));\n  lua_register(L, 'FlushStoredReal', FlushStoredReal.bind(null, C));\n  lua_register(L, 'FlushStoredBoolean', FlushStoredBoolean.bind(null, C));\n  lua_register(L, 'FlushStoredUnit', FlushStoredUnit.bind(null, C));\n  lua_register(L, 'FlushStoredString', FlushStoredString.bind(null, C));\n  lua_register(L, 'GetStoredInteger', GetStoredInteger.bind(null, C));\n  lua_register(L, 'GetStoredReal', GetStoredReal.bind(null, C));\n  lua_register(L, 'GetStoredBoolean', GetStoredBoolean.bind(null, C));\n  lua_register(L, 'GetStoredString', GetStoredString.bind(null, C));\n  lua_register(L, 'RestoreUnit', RestoreUnit.bind(null, C));\n  lua_register(L, 'InitHashtable', InitHashtable.bind(null, C));\n  lua_register(L, 'SaveInteger', SaveInteger.bind(null, C));\n  lua_register(L, 'SaveReal', SaveReal.bind(null, C));\n  lua_register(L, 'SaveBoolean', SaveBoolean.bind(null, C));\n  lua_register(L, 'SaveStr', SaveStr.bind(null, C));\n  lua_register(L, 'SavePlayerHandle', SavePlayerHandle.bind(null, C));\n  lua_register(L, 'SaveWidgetHandle', SaveWidgetHandle.bind(null, C));\n  lua_register(L, 'SaveDestructableHandle', SaveDestructableHandle.bind(null, C));\n  lua_register(L, 'SaveItemHandle', SaveItemHandle.bind(null, C));\n  lua_register(L, 'SaveUnitHandle', SaveUnitHandle.bind(null, C));\n  lua_register(L, 'SaveAbilityHandle', SaveAbilityHandle.bind(null, C));\n  lua_register(L, 'SaveTimerHandle', SaveTimerHandle.bind(null, C));\n  lua_register(L, 'SaveTriggerHandle', SaveTriggerHandle.bind(null, C));\n  lua_register(L, 'SaveTriggerConditionHandle', SaveTriggerConditionHandle.bind(null, C));\n  lua_register(L, 'SaveTriggerActionHandle', SaveTriggerActionHandle.bind(null, C));\n  lua_register(L, 'SaveTriggerEventHandle', SaveTriggerEventHandle.bind(null, C));\n  lua_register(L, 'SaveForceHandle', SaveForceHandle.bind(null, C));\n  lua_register(L, 'SaveGroupHandle', SaveGroupHandle.bind(null, C));\n  lua_register(L, 'SaveLocationHandle', SaveLocationHandle.bind(null, C));\n  lua_register(L, 'SaveRectHandle', SaveRectHandle.bind(null, C));\n  lua_register(L, 'SaveBooleanExprHandle', SaveBooleanExprHandle.bind(null, C));\n  lua_register(L, 'SaveSoundHandle', SaveSoundHandle.bind(null, C));\n  lua_register(L, 'SaveEffectHandle', SaveEffectHandle.bind(null, C));\n  lua_register(L, 'SaveUnitPoolHandle', SaveUnitPoolHandle.bind(null, C));\n  lua_register(L, 'SaveItemPoolHandle', SaveItemPoolHandle.bind(null, C));\n  lua_register(L, 'SaveQuestHandle', SaveQuestHandle.bind(null, C));\n  lua_register(L, 'SaveQuestItemHandle', SaveQuestItemHandle.bind(null, C));\n  lua_register(L, 'SaveDefeatConditionHandle', SaveDefeatConditionHandle.bind(null, C));\n  lua_register(L, 'SaveTimerDialogHandle', SaveTimerDialogHandle.bind(null, C));\n  lua_register(L, 'SaveLeaderboardHandle', SaveLeaderboardHandle.bind(null, C));\n  lua_register(L, 'SaveMultiboardHandle', SaveMultiboardHandle.bind(null, C));\n  lua_register(L, 'SaveMultiboardItemHandle', SaveMultiboardItemHandle.bind(null, C));\n  lua_register(L, 'SaveTrackableHandle', SaveTrackableHandle.bind(null, C));\n  lua_register(L, 'SaveDialogHandle', SaveDialogHandle.bind(null, C));\n  lua_register(L, 'SaveButtonHandle', SaveButtonHandle.bind(null, C));\n  lua_register(L, 'SaveTextTagHandle', SaveTextTagHandle.bind(null, C));\n  lua_register(L, 'SaveLightningHandle', SaveLightningHandle.bind(null, C));\n  lua_register(L, 'SaveImageHandle', SaveImageHandle.bind(null, C));\n  lua_register(L, 'SaveUbersplatHandle', SaveUbersplatHandle.bind(null, C));\n  lua_register(L, 'SaveRegionHandle', SaveRegionHandle.bind(null, C));\n  lua_register(L, 'SaveFogStateHandle', SaveFogStateHandle.bind(null, C));\n  lua_register(L, 'SaveFogModifierHandle', SaveFogModifierHandle.bind(null, C));\n  lua_register(L, 'SaveAgentHandle', SaveAgentHandle.bind(null, C));\n  lua_register(L, 'SaveHashtableHandle', SaveHashtableHandle.bind(null, C));\n  lua_register(L, 'LoadInteger', LoadInteger.bind(null, C));\n  lua_register(L, 'LoadReal', LoadReal.bind(null, C));\n  lua_register(L, 'LoadBoolean', LoadBoolean.bind(null, C));\n  lua_register(L, 'LoadStr', LoadStr.bind(null, C));\n  lua_register(L, 'LoadPlayerHandle', LoadPlayerHandle.bind(null, C));\n  lua_register(L, 'LoadWidgetHandle', LoadWidgetHandle.bind(null, C));\n  lua_register(L, 'LoadDestructableHandle', LoadDestructableHandle.bind(null, C));\n  lua_register(L, 'LoadItemHandle', LoadItemHandle.bind(null, C));\n  lua_register(L, 'LoadUnitHandle', LoadUnitHandle.bind(null, C));\n  lua_register(L, 'LoadAbilityHandle', LoadAbilityHandle.bind(null, C));\n  lua_register(L, 'LoadTimerHandle', LoadTimerHandle.bind(null, C));\n  lua_register(L, 'LoadTriggerHandle', LoadTriggerHandle.bind(null, C));\n  lua_register(L, 'LoadTriggerConditionHandle', LoadTriggerConditionHandle.bind(null, C));\n  lua_register(L, 'LoadTriggerActionHandle', LoadTriggerActionHandle.bind(null, C));\n  lua_register(L, 'LoadTriggerEventHandle', LoadTriggerEventHandle.bind(null, C));\n  lua_register(L, 'LoadForceHandle', LoadForceHandle.bind(null, C));\n  lua_register(L, 'LoadGroupHandle', LoadGroupHandle.bind(null, C));\n  lua_register(L, 'LoadLocationHandle', LoadLocationHandle.bind(null, C));\n  lua_register(L, 'LoadRectHandle', LoadRectHandle.bind(null, C));\n  lua_register(L, 'LoadBooleanExprHandle', LoadBooleanExprHandle.bind(null, C));\n  lua_register(L, 'LoadSoundHandle', LoadSoundHandle.bind(null, C));\n  lua_register(L, 'LoadEffectHandle', LoadEffectHandle.bind(null, C));\n  lua_register(L, 'LoadUnitPoolHandle', LoadUnitPoolHandle.bind(null, C));\n  lua_register(L, 'LoadItemPoolHandle', LoadItemPoolHandle.bind(null, C));\n  lua_register(L, 'LoadQuestHandle', LoadQuestHandle.bind(null, C));\n  lua_register(L, 'LoadQuestItemHandle', LoadQuestItemHandle.bind(null, C));\n  lua_register(L, 'LoadDefeatConditionHandle', LoadDefeatConditionHandle.bind(null, C));\n  lua_register(L, 'LoadTimerDialogHandle', LoadTimerDialogHandle.bind(null, C));\n  lua_register(L, 'LoadLeaderboardHandle', LoadLeaderboardHandle.bind(null, C));\n  lua_register(L, 'LoadMultiboardHandle', LoadMultiboardHandle.bind(null, C));\n  lua_register(L, 'LoadMultiboardItemHandle', LoadMultiboardItemHandle.bind(null, C));\n  lua_register(L, 'LoadTrackableHandle', LoadTrackableHandle.bind(null, C));\n  lua_register(L, 'LoadDialogHandle', LoadDialogHandle.bind(null, C));\n  lua_register(L, 'LoadButtonHandle', LoadButtonHandle.bind(null, C));\n  lua_register(L, 'LoadTextTagHandle', LoadTextTagHandle.bind(null, C));\n  lua_register(L, 'LoadLightningHandle', LoadLightningHandle.bind(null, C));\n  lua_register(L, 'LoadImageHandle', LoadImageHandle.bind(null, C));\n  lua_register(L, 'LoadUbersplatHandle', LoadUbersplatHandle.bind(null, C));\n  lua_register(L, 'LoadRegionHandle', LoadRegionHandle.bind(null, C));\n  lua_register(L, 'LoadFogStateHandle', LoadFogStateHandle.bind(null, C));\n  lua_register(L, 'LoadFogModifierHandle', LoadFogModifierHandle.bind(null, C));\n  lua_register(L, 'LoadHashtableHandle', LoadHashtableHandle.bind(null, C));\n  lua_register(L, 'HaveSavedInteger', HaveSavedInteger.bind(null, C));\n  lua_register(L, 'HaveSavedReal', HaveSavedReal.bind(null, C));\n  lua_register(L, 'HaveSavedBoolean', HaveSavedBoolean.bind(null, C));\n  lua_register(L, 'HaveSavedString', HaveSavedString.bind(null, C));\n  lua_register(L, 'HaveSavedHandle', HaveSavedHandle.bind(null, C));\n  lua_register(L, 'RemoveSavedInteger', RemoveSavedInteger.bind(null, C));\n  lua_register(L, 'RemoveSavedReal', RemoveSavedReal.bind(null, C));\n  lua_register(L, 'RemoveSavedBoolean', RemoveSavedBoolean.bind(null, C));\n  lua_register(L, 'RemoveSavedString', RemoveSavedString.bind(null, C));\n  lua_register(L, 'RemoveSavedHandle', RemoveSavedHandle.bind(null, C));\n  lua_register(L, 'FlushParentHashtable', FlushParentHashtable.bind(null, C));\n  lua_register(L, 'FlushChildHashtable', FlushChildHashtable.bind(null, C));\n  lua_register(L, 'GetRandomInt', GetRandomInt.bind(null, C));\n  lua_register(L, 'GetRandomReal', GetRandomReal.bind(null, C));\n  lua_register(L, 'CreateUnitPool', CreateUnitPool.bind(null, C));\n  lua_register(L, 'DestroyUnitPool', DestroyUnitPool.bind(null, C));\n  lua_register(L, 'UnitPoolAddUnitType', UnitPoolAddUnitType.bind(null, C));\n  lua_register(L, 'UnitPoolRemoveUnitType', UnitPoolRemoveUnitType.bind(null, C));\n  lua_register(L, 'PlaceRandomUnit', PlaceRandomUnit.bind(null, C));\n  lua_register(L, 'CreateItemPool', CreateItemPool.bind(null, C));\n  lua_register(L, 'DestroyItemPool', DestroyItemPool.bind(null, C));\n  lua_register(L, 'ItemPoolAddItemType', ItemPoolAddItemType.bind(null, C));\n  lua_register(L, 'ItemPoolRemoveItemType', ItemPoolRemoveItemType.bind(null, C));\n  lua_register(L, 'PlaceRandomItem', PlaceRandomItem.bind(null, C));\n  lua_register(L, 'ChooseRandomCreep', ChooseRandomCreep.bind(null, C));\n  lua_register(L, 'ChooseRandomNPBuilding', ChooseRandomNPBuilding.bind(null, C));\n  lua_register(L, 'ChooseRandomItem', ChooseRandomItem.bind(null, C));\n  lua_register(L, 'ChooseRandomItemEx', ChooseRandomItemEx.bind(null, C));\n  lua_register(L, 'SetRandomSeed', SetRandomSeed.bind(null, C));\n  lua_register(L, 'SetTerrainFog', SetTerrainFog.bind(null, C));\n  lua_register(L, 'ResetTerrainFog', ResetTerrainFog.bind(null, C));\n  lua_register(L, 'SetUnitFog', SetUnitFog.bind(null, C));\n  lua_register(L, 'SetTerrainFogEx', SetTerrainFogEx.bind(null, C));\n  lua_register(L, 'DisplayTextToPlayer', DisplayTextToPlayer.bind(null, C));\n  lua_register(L, 'DisplayTimedTextToPlayer', DisplayTimedTextToPlayer.bind(null, C));\n  lua_register(L, 'DisplayTimedTextFromPlayer', DisplayTimedTextFromPlayer.bind(null, C));\n  lua_register(L, 'ClearTextMessages', ClearTextMessages.bind(null, C));\n  lua_register(L, 'SetDayNightModels', SetDayNightModels.bind(null, C));\n  lua_register(L, 'SetSkyModel', SetSkyModel.bind(null, C));\n  lua_register(L, 'EnableUserControl', EnableUserControl.bind(null, C));\n  lua_register(L, 'EnableUserUI', EnableUserUI.bind(null, C));\n  lua_register(L, 'SuspendTimeOfDay', SuspendTimeOfDay.bind(null, C));\n  lua_register(L, 'SetTimeOfDayScale', SetTimeOfDayScale.bind(null, C));\n  lua_register(L, 'GetTimeOfDayScale', GetTimeOfDayScale.bind(null, C));\n  lua_register(L, 'ShowInterface', ShowInterface.bind(null, C));\n  lua_register(L, 'PauseGame', PauseGame.bind(null, C));\n  lua_register(L, 'UnitAddIndicator', UnitAddIndicator.bind(null, C));\n  lua_register(L, 'AddIndicator', AddIndicator.bind(null, C));\n  lua_register(L, 'PingMinimap', PingMinimap.bind(null, C));\n  lua_register(L, 'PingMinimapEx', PingMinimapEx.bind(null, C));\n  lua_register(L, 'EnableOcclusion', EnableOcclusion.bind(null, C));\n  lua_register(L, 'SetIntroShotText', SetIntroShotText.bind(null, C));\n  lua_register(L, 'SetIntroShotModel', SetIntroShotModel.bind(null, C));\n  lua_register(L, 'EnableWorldFogBoundary', EnableWorldFogBoundary.bind(null, C));\n  lua_register(L, 'PlayModelCinematic', PlayModelCinematic.bind(null, C));\n  lua_register(L, 'PlayCinematic', PlayCinematic.bind(null, C));\n  lua_register(L, 'ForceUIKey', ForceUIKey.bind(null, C));\n  lua_register(L, 'ForceUICancel', ForceUICancel.bind(null, C));\n  lua_register(L, 'DisplayLoadDialog', DisplayLoadDialog.bind(null, C));\n  lua_register(L, 'SetAltMinimapIcon', SetAltMinimapIcon.bind(null, C));\n  lua_register(L, 'DisableRestartMission', DisableRestartMission.bind(null, C));\n  lua_register(L, 'CreateTextTag', CreateTextTag.bind(null, C));\n  lua_register(L, 'DestroyTextTag', DestroyTextTag.bind(null, C));\n  lua_register(L, 'SetTextTagText', SetTextTagText.bind(null, C));\n  lua_register(L, 'SetTextTagPos', SetTextTagPos.bind(null, C));\n  lua_register(L, 'SetTextTagPosUnit', SetTextTagPosUnit.bind(null, C));\n  lua_register(L, 'SetTextTagColor', SetTextTagColor.bind(null, C));\n  lua_register(L, 'SetTextTagVelocity', SetTextTagVelocity.bind(null, C));\n  lua_register(L, 'SetTextTagVisibility', SetTextTagVisibility.bind(null, C));\n  lua_register(L, 'SetTextTagSuspended', SetTextTagSuspended.bind(null, C));\n  lua_register(L, 'SetTextTagPermanent', SetTextTagPermanent.bind(null, C));\n  lua_register(L, 'SetTextTagAge', SetTextTagAge.bind(null, C));\n  lua_register(L, 'SetTextTagLifespan', SetTextTagLifespan.bind(null, C));\n  lua_register(L, 'SetTextTagFadepoint', SetTextTagFadepoint.bind(null, C));\n  lua_register(L, 'SetReservedLocalHeroButtons', SetReservedLocalHeroButtons.bind(null, C));\n  lua_register(L, 'GetAllyColorFilterState', GetAllyColorFilterState.bind(null, C));\n  lua_register(L, 'SetAllyColorFilterState', SetAllyColorFilterState.bind(null, C));\n  lua_register(L, 'GetCreepCampFilterState', GetCreepCampFilterState.bind(null, C));\n  lua_register(L, 'SetCreepCampFilterState', SetCreepCampFilterState.bind(null, C));\n  lua_register(L, 'EnableMinimapFilterButtons', EnableMinimapFilterButtons.bind(null, C));\n  lua_register(L, 'EnableDragSelect', EnableDragSelect.bind(null, C));\n  lua_register(L, 'EnablePreSelect', EnablePreSelect.bind(null, C));\n  lua_register(L, 'EnableSelect', EnableSelect.bind(null, C));\n  lua_register(L, 'CreateTrackable', CreateTrackable.bind(null, C));\n  lua_register(L, 'CreateQuest', CreateQuest.bind(null, C));\n  lua_register(L, 'DestroyQuest', DestroyQuest.bind(null, C));\n  lua_register(L, 'QuestSetTitle', QuestSetTitle.bind(null, C));\n  lua_register(L, 'QuestSetDescription', QuestSetDescription.bind(null, C));\n  lua_register(L, 'QuestSetIconPath', QuestSetIconPath.bind(null, C));\n  lua_register(L, 'QuestSetRequired', QuestSetRequired.bind(null, C));\n  lua_register(L, 'QuestSetCompleted', QuestSetCompleted.bind(null, C));\n  lua_register(L, 'QuestSetDiscovered', QuestSetDiscovered.bind(null, C));\n  lua_register(L, 'QuestSetFailed', QuestSetFailed.bind(null, C));\n  lua_register(L, 'QuestSetEnabled', QuestSetEnabled.bind(null, C));\n  lua_register(L, 'IsQuestRequired', IsQuestRequired.bind(null, C));\n  lua_register(L, 'IsQuestCompleted', IsQuestCompleted.bind(null, C));\n  lua_register(L, 'IsQuestDiscovered', IsQuestDiscovered.bind(null, C));\n  lua_register(L, 'IsQuestFailed', IsQuestFailed.bind(null, C));\n  lua_register(L, 'IsQuestEnabled', IsQuestEnabled.bind(null, C));\n  lua_register(L, 'QuestCreateItem', QuestCreateItem.bind(null, C));\n  lua_register(L, 'QuestItemSetDescription', QuestItemSetDescription.bind(null, C));\n  lua_register(L, 'QuestItemSetCompleted', QuestItemSetCompleted.bind(null, C));\n  lua_register(L, 'IsQuestItemCompleted', IsQuestItemCompleted.bind(null, C));\n  lua_register(L, 'CreateDefeatCondition', CreateDefeatCondition.bind(null, C));\n  lua_register(L, 'DestroyDefeatCondition', DestroyDefeatCondition.bind(null, C));\n  lua_register(L, 'DefeatConditionSetDescription', DefeatConditionSetDescription.bind(null, C));\n  lua_register(L, 'FlashQuestDialogButton', FlashQuestDialogButton.bind(null, C));\n  lua_register(L, 'ForceQuestDialogUpdate', ForceQuestDialogUpdate.bind(null, C));\n  lua_register(L, 'CreateTimerDialog', CreateTimerDialog.bind(null, C));\n  lua_register(L, 'DestroyTimerDialog', DestroyTimerDialog.bind(null, C));\n  lua_register(L, 'TimerDialogSetTitle', TimerDialogSetTitle.bind(null, C));\n  lua_register(L, 'TimerDialogSetTitleColor', TimerDialogSetTitleColor.bind(null, C));\n  lua_register(L, 'TimerDialogSetTimeColor', TimerDialogSetTimeColor.bind(null, C));\n  lua_register(L, 'TimerDialogSetSpeed', TimerDialogSetSpeed.bind(null, C));\n  lua_register(L, 'TimerDialogDisplay', TimerDialogDisplay.bind(null, C));\n  lua_register(L, 'IsTimerDialogDisplayed', IsTimerDialogDisplayed.bind(null, C));\n  lua_register(L, 'TimerDialogSetRealTimeRemaining', TimerDialogSetRealTimeRemaining.bind(null, C));\n  lua_register(L, 'CreateLeaderboard', CreateLeaderboard.bind(null, C));\n  lua_register(L, 'DestroyLeaderboard', DestroyLeaderboard.bind(null, C));\n  lua_register(L, 'LeaderboardDisplay', LeaderboardDisplay.bind(null, C));\n  lua_register(L, 'IsLeaderboardDisplayed', IsLeaderboardDisplayed.bind(null, C));\n  lua_register(L, 'LeaderboardGetItemCount', LeaderboardGetItemCount.bind(null, C));\n  lua_register(L, 'LeaderboardSetSizeByItemCount', LeaderboardSetSizeByItemCount.bind(null, C));\n  lua_register(L, 'LeaderboardAddItem', LeaderboardAddItem.bind(null, C));\n  lua_register(L, 'LeaderboardRemoveItem', LeaderboardRemoveItem.bind(null, C));\n  lua_register(L, 'LeaderboardRemovePlayerItem', LeaderboardRemovePlayerItem.bind(null, C));\n  lua_register(L, 'LeaderboardClear', LeaderboardClear.bind(null, C));\n  lua_register(L, 'LeaderboardSortItemsByValue', LeaderboardSortItemsByValue.bind(null, C));\n  lua_register(L, 'LeaderboardSortItemsByPlayer', LeaderboardSortItemsByPlayer.bind(null, C));\n  lua_register(L, 'LeaderboardSortItemsByLabel', LeaderboardSortItemsByLabel.bind(null, C));\n  lua_register(L, 'LeaderboardHasPlayerItem', LeaderboardHasPlayerItem.bind(null, C));\n  lua_register(L, 'LeaderboardGetPlayerIndex', LeaderboardGetPlayerIndex.bind(null, C));\n  lua_register(L, 'LeaderboardSetLabel', LeaderboardSetLabel.bind(null, C));\n  lua_register(L, 'LeaderboardGetLabelText', LeaderboardGetLabelText.bind(null, C));\n  lua_register(L, 'PlayerSetLeaderboard', PlayerSetLeaderboard.bind(null, C));\n  lua_register(L, 'PlayerGetLeaderboard', PlayerGetLeaderboard.bind(null, C));\n  lua_register(L, 'LeaderboardSetLabelColor', LeaderboardSetLabelColor.bind(null, C));\n  lua_register(L, 'LeaderboardSetValueColor', LeaderboardSetValueColor.bind(null, C));\n  lua_register(L, 'LeaderboardSetStyle', LeaderboardSetStyle.bind(null, C));\n  lua_register(L, 'LeaderboardSetItemValue', LeaderboardSetItemValue.bind(null, C));\n  lua_register(L, 'LeaderboardSetItemLabel', LeaderboardSetItemLabel.bind(null, C));\n  lua_register(L, 'LeaderboardSetItemStyle', LeaderboardSetItemStyle.bind(null, C));\n  lua_register(L, 'LeaderboardSetItemLabelColor', LeaderboardSetItemLabelColor.bind(null, C));\n  lua_register(L, 'LeaderboardSetItemValueColor', LeaderboardSetItemValueColor.bind(null, C));\n  lua_register(L, 'CreateMultiboard', CreateMultiboard.bind(null, C));\n  lua_register(L, 'DestroyMultiboard', DestroyMultiboard.bind(null, C));\n  lua_register(L, 'MultiboardDisplay', MultiboardDisplay.bind(null, C));\n  lua_register(L, 'IsMultiboardDisplayed', IsMultiboardDisplayed.bind(null, C));\n  lua_register(L, 'MultiboardMinimize', MultiboardMinimize.bind(null, C));\n  lua_register(L, 'IsMultiboardMinimized', IsMultiboardMinimized.bind(null, C));\n  lua_register(L, 'MultiboardClear', MultiboardClear.bind(null, C));\n  lua_register(L, 'MultiboardSetTitleText', MultiboardSetTitleText.bind(null, C));\n  lua_register(L, 'MultiboardGetTitleText', MultiboardGetTitleText.bind(null, C));\n  lua_register(L, 'MultiboardSetTitleTextColor', MultiboardSetTitleTextColor.bind(null, C));\n  lua_register(L, 'MultiboardGetRowCount', MultiboardGetRowCount.bind(null, C));\n  lua_register(L, 'MultiboardGetColumnCount', MultiboardGetColumnCount.bind(null, C));\n  lua_register(L, 'MultiboardSetColumnCount', MultiboardSetColumnCount.bind(null, C));\n  lua_register(L, 'MultiboardSetRowCount', MultiboardSetRowCount.bind(null, C));\n  lua_register(L, 'MultiboardSetItemsStyle', MultiboardSetItemsStyle.bind(null, C));\n  lua_register(L, 'MultiboardSetItemsValue', MultiboardSetItemsValue.bind(null, C));\n  lua_register(L, 'MultiboardSetItemsValueColor', MultiboardSetItemsValueColor.bind(null, C));\n  lua_register(L, 'MultiboardSetItemsWidth', MultiboardSetItemsWidth.bind(null, C));\n  lua_register(L, 'MultiboardSetItemsIcon', MultiboardSetItemsIcon.bind(null, C));\n  lua_register(L, 'MultiboardGetItem', MultiboardGetItem.bind(null, C));\n  lua_register(L, 'MultiboardReleaseItem', MultiboardReleaseItem.bind(null, C));\n  lua_register(L, 'MultiboardSetItemStyle', MultiboardSetItemStyle.bind(null, C));\n  lua_register(L, 'MultiboardSetItemValue', MultiboardSetItemValue.bind(null, C));\n  lua_register(L, 'MultiboardSetItemValueColor', MultiboardSetItemValueColor.bind(null, C));\n  lua_register(L, 'MultiboardSetItemWidth', MultiboardSetItemWidth.bind(null, C));\n  lua_register(L, 'MultiboardSetItemIcon', MultiboardSetItemIcon.bind(null, C));\n  lua_register(L, 'MultiboardSuppressDisplay', MultiboardSuppressDisplay.bind(null, C));\n  lua_register(L, 'SetCameraPosition', SetCameraPosition.bind(null, C));\n  lua_register(L, 'SetCameraQuickPosition', SetCameraQuickPosition.bind(null, C));\n  lua_register(L, 'SetCameraBounds', SetCameraBounds.bind(null, C));\n  lua_register(L, 'StopCamera', StopCamera.bind(null, C));\n  lua_register(L, 'ResetToGameCamera', ResetToGameCamera.bind(null, C));\n  lua_register(L, 'PanCameraTo', PanCameraTo.bind(null, C));\n  lua_register(L, 'PanCameraToTimed', PanCameraToTimed.bind(null, C));\n  lua_register(L, 'PanCameraToWithZ', PanCameraToWithZ.bind(null, C));\n  lua_register(L, 'PanCameraToTimedWithZ', PanCameraToTimedWithZ.bind(null, C));\n  lua_register(L, 'SetCinematicCamera', SetCinematicCamera.bind(null, C));\n  lua_register(L, 'SetCameraRotateMode', SetCameraRotateMode.bind(null, C));\n  lua_register(L, 'SetCameraField', SetCameraField.bind(null, C));\n  lua_register(L, 'AdjustCameraField', AdjustCameraField.bind(null, C));\n  lua_register(L, 'SetCameraTargetController', SetCameraTargetController.bind(null, C));\n  lua_register(L, 'SetCameraOrientController', SetCameraOrientController.bind(null, C));\n  lua_register(L, 'CreateCameraSetup', CreateCameraSetup.bind(null, C));\n  lua_register(L, 'CameraSetupSetField', CameraSetupSetField.bind(null, C));\n  lua_register(L, 'CameraSetupGetField', CameraSetupGetField.bind(null, C));\n  lua_register(L, 'CameraSetupSetDestPosition', CameraSetupSetDestPosition.bind(null, C));\n  lua_register(L, 'CameraSetupGetDestPositionLoc', CameraSetupGetDestPositionLoc.bind(null, C));\n  lua_register(L, 'CameraSetupGetDestPositionX', CameraSetupGetDestPositionX.bind(null, C));\n  lua_register(L, 'CameraSetupGetDestPositionY', CameraSetupGetDestPositionY.bind(null, C));\n  lua_register(L, 'CameraSetupApply', CameraSetupApply.bind(null, C));\n  lua_register(L, 'CameraSetupApplyWithZ', CameraSetupApplyWithZ.bind(null, C));\n  lua_register(L, 'CameraSetupApplyForceDuration', CameraSetupApplyForceDuration.bind(null, C));\n  lua_register(L, 'CameraSetupApplyForceDurationWithZ', CameraSetupApplyForceDurationWithZ.bind(null, C));\n  lua_register(L, 'CameraSetTargetNoise', CameraSetTargetNoise.bind(null, C));\n  lua_register(L, 'CameraSetSourceNoise', CameraSetSourceNoise.bind(null, C));\n  lua_register(L, 'CameraSetTargetNoiseEx', CameraSetTargetNoiseEx.bind(null, C));\n  lua_register(L, 'CameraSetSourceNoiseEx', CameraSetSourceNoiseEx.bind(null, C));\n  lua_register(L, 'CameraSetSmoothingFactor', CameraSetSmoothingFactor.bind(null, C));\n  lua_register(L, 'SetCineFilterTexture', SetCineFilterTexture.bind(null, C));\n  lua_register(L, 'SetCineFilterBlendMode', SetCineFilterBlendMode.bind(null, C));\n  lua_register(L, 'SetCineFilterTexMapFlags', SetCineFilterTexMapFlags.bind(null, C));\n  lua_register(L, 'SetCineFilterStartUV', SetCineFilterStartUV.bind(null, C));\n  lua_register(L, 'SetCineFilterEndUV', SetCineFilterEndUV.bind(null, C));\n  lua_register(L, 'SetCineFilterStartColor', SetCineFilterStartColor.bind(null, C));\n  lua_register(L, 'SetCineFilterEndColor', SetCineFilterEndColor.bind(null, C));\n  lua_register(L, 'SetCineFilterDuration', SetCineFilterDuration.bind(null, C));\n  lua_register(L, 'DisplayCineFilter', DisplayCineFilter.bind(null, C));\n  lua_register(L, 'IsCineFilterDisplayed', IsCineFilterDisplayed.bind(null, C));\n  lua_register(L, 'SetCinematicScene', SetCinematicScene.bind(null, C));\n  lua_register(L, 'EndCinematicScene', EndCinematicScene.bind(null, C));\n  lua_register(L, 'ForceCinematicSubtitles', ForceCinematicSubtitles.bind(null, C));\n  lua_register(L, 'GetCameraMargin', GetCameraMargin.bind(null, C));\n  lua_register(L, 'GetCameraBoundMinX', GetCameraBoundMinX.bind(null, C));\n  lua_register(L, 'GetCameraBoundMinY', GetCameraBoundMinY.bind(null, C));\n  lua_register(L, 'GetCameraBoundMaxX', GetCameraBoundMaxX.bind(null, C));\n  lua_register(L, 'GetCameraBoundMaxY', GetCameraBoundMaxY.bind(null, C));\n  lua_register(L, 'GetCameraField', GetCameraField.bind(null, C));\n  lua_register(L, 'GetCameraTargetPositionX', GetCameraTargetPositionX.bind(null, C));\n  lua_register(L, 'GetCameraTargetPositionY', GetCameraTargetPositionY.bind(null, C));\n  lua_register(L, 'GetCameraTargetPositionZ', GetCameraTargetPositionZ.bind(null, C));\n  lua_register(L, 'GetCameraTargetPositionLoc', GetCameraTargetPositionLoc.bind(null, C));\n  lua_register(L, 'GetCameraEyePositionX', GetCameraEyePositionX.bind(null, C));\n  lua_register(L, 'GetCameraEyePositionY', GetCameraEyePositionY.bind(null, C));\n  lua_register(L, 'GetCameraEyePositionZ', GetCameraEyePositionZ.bind(null, C));\n  lua_register(L, 'GetCameraEyePositionLoc', GetCameraEyePositionLoc.bind(null, C));\n  lua_register(L, 'NewSoundEnvironment', NewSoundEnvironment.bind(null, C));\n  lua_register(L, 'CreateSound', CreateSound.bind(null, C));\n  lua_register(L, 'CreateSoundFilenameWithLabel', CreateSoundFilenameWithLabel.bind(null, C));\n  lua_register(L, 'CreateSoundFromLabel', CreateSoundFromLabel.bind(null, C));\n  lua_register(L, 'CreateMIDISound', CreateMIDISound.bind(null, C));\n  lua_register(L, 'SetSoundParamsFromLabel', SetSoundParamsFromLabel.bind(null, C));\n  lua_register(L, 'SetSoundDistanceCutoff', SetSoundDistanceCutoff.bind(null, C));\n  lua_register(L, 'SetSoundChannel', SetSoundChannel.bind(null, C));\n  lua_register(L, 'SetSoundVolume', SetSoundVolume.bind(null, C));\n  lua_register(L, 'SetSoundPitch', SetSoundPitch.bind(null, C));\n  lua_register(L, 'SetSoundPlayPosition', SetSoundPlayPosition.bind(null, C));\n  lua_register(L, 'SetSoundDistances', SetSoundDistances.bind(null, C));\n  lua_register(L, 'SetSoundConeAngles', SetSoundConeAngles.bind(null, C));\n  lua_register(L, 'SetSoundConeOrientation', SetSoundConeOrientation.bind(null, C));\n  lua_register(L, 'SetSoundPosition', SetSoundPosition.bind(null, C));\n  lua_register(L, 'SetSoundVelocity', SetSoundVelocity.bind(null, C));\n  lua_register(L, 'AttachSoundToUnit', AttachSoundToUnit.bind(null, C));\n  lua_register(L, 'StartSound', StartSound.bind(null, C));\n  lua_register(L, 'StopSound', StopSound.bind(null, C));\n  lua_register(L, 'KillSoundWhenDone', KillSoundWhenDone.bind(null, C));\n  lua_register(L, 'SetMapMusic', SetMapMusic.bind(null, C));\n  lua_register(L, 'ClearMapMusic', ClearMapMusic.bind(null, C));\n  lua_register(L, 'PlayMusic', PlayMusic.bind(null, C));\n  lua_register(L, 'PlayMusicEx', PlayMusicEx.bind(null, C));\n  lua_register(L, 'StopMusic', StopMusic.bind(null, C));\n  lua_register(L, 'ResumeMusic', ResumeMusic.bind(null, C));\n  lua_register(L, 'PlayThematicMusic', PlayThematicMusic.bind(null, C));\n  lua_register(L, 'PlayThematicMusicEx', PlayThematicMusicEx.bind(null, C));\n  lua_register(L, 'EndThematicMusic', EndThematicMusic.bind(null, C));\n  lua_register(L, 'SetMusicVolume', SetMusicVolume.bind(null, C));\n  lua_register(L, 'SetMusicPlayPosition', SetMusicPlayPosition.bind(null, C));\n  lua_register(L, 'SetThematicMusicPlayPosition', SetThematicMusicPlayPosition.bind(null, C));\n  lua_register(L, 'SetSoundDuration', SetSoundDuration.bind(null, C));\n  lua_register(L, 'GetSoundDuration', GetSoundDuration.bind(null, C));\n  lua_register(L, 'GetSoundFileDuration', GetSoundFileDuration.bind(null, C));\n  lua_register(L, 'VolumeGroupSetVolume', VolumeGroupSetVolume.bind(null, C));\n  lua_register(L, 'VolumeGroupReset', VolumeGroupReset.bind(null, C));\n  lua_register(L, 'GetSoundIsPlaying', GetSoundIsPlaying.bind(null, C));\n  lua_register(L, 'GetSoundIsLoading', GetSoundIsLoading.bind(null, C));\n  lua_register(L, 'RegisterStackedSound', RegisterStackedSound.bind(null, C));\n  lua_register(L, 'UnregisterStackedSound', UnregisterStackedSound.bind(null, C));\n  lua_register(L, 'AddWeatherEffect', AddWeatherEffect.bind(null, C));\n  lua_register(L, 'RemoveWeatherEffect', RemoveWeatherEffect.bind(null, C));\n  lua_register(L, 'EnableWeatherEffect', EnableWeatherEffect.bind(null, C));\n  lua_register(L, 'TerrainDeformCrater', TerrainDeformCrater.bind(null, C));\n  lua_register(L, 'TerrainDeformRipple', TerrainDeformRipple.bind(null, C));\n  lua_register(L, 'TerrainDeformWave', TerrainDeformWave.bind(null, C));\n  lua_register(L, 'TerrainDeformRandom', TerrainDeformRandom.bind(null, C));\n  lua_register(L, 'TerrainDeformStop', TerrainDeformStop.bind(null, C));\n  lua_register(L, 'TerrainDeformStopAll', TerrainDeformStopAll.bind(null, C));\n  lua_register(L, 'AddSpecialEffect', AddSpecialEffect.bind(null, C));\n  lua_register(L, 'AddSpecialEffectLoc', AddSpecialEffectLoc.bind(null, C));\n  lua_register(L, 'AddSpecialEffectTarget', AddSpecialEffectTarget.bind(null, C));\n  lua_register(L, 'DestroyEffect', DestroyEffect.bind(null, C));\n  lua_register(L, 'AddSpellEffect', AddSpellEffect.bind(null, C));\n  lua_register(L, 'AddSpellEffectLoc', AddSpellEffectLoc.bind(null, C));\n  lua_register(L, 'AddSpellEffectById', AddSpellEffectById.bind(null, C));\n  lua_register(L, 'AddSpellEffectByIdLoc', AddSpellEffectByIdLoc.bind(null, C));\n  lua_register(L, 'AddSpellEffectTarget', AddSpellEffectTarget.bind(null, C));\n  lua_register(L, 'AddSpellEffectTargetById', AddSpellEffectTargetById.bind(null, C));\n  lua_register(L, 'AddLightning', AddLightning.bind(null, C));\n  lua_register(L, 'AddLightningEx', AddLightningEx.bind(null, C));\n  lua_register(L, 'DestroyLightning', DestroyLightning.bind(null, C));\n  lua_register(L, 'MoveLightning', MoveLightning.bind(null, C));\n  lua_register(L, 'MoveLightningEx', MoveLightningEx.bind(null, C));\n  lua_register(L, 'GetLightningColorA', GetLightningColorA.bind(null, C));\n  lua_register(L, 'GetLightningColorR', GetLightningColorR.bind(null, C));\n  lua_register(L, 'GetLightningColorG', GetLightningColorG.bind(null, C));\n  lua_register(L, 'GetLightningColorB', GetLightningColorB.bind(null, C));\n  lua_register(L, 'SetLightningColor', SetLightningColor.bind(null, C));\n  lua_register(L, 'GetAbilityEffect', GetAbilityEffect.bind(null, C));\n  lua_register(L, 'GetAbilityEffectById', GetAbilityEffectById.bind(null, C));\n  lua_register(L, 'GetAbilitySound', GetAbilitySound.bind(null, C));\n  lua_register(L, 'GetAbilitySoundById', GetAbilitySoundById.bind(null, C));\n  lua_register(L, 'GetTerrainCliffLevel', GetTerrainCliffLevel.bind(null, C));\n  lua_register(L, 'SetWaterBaseColor', SetWaterBaseColor.bind(null, C));\n  lua_register(L, 'SetWaterDeforms', SetWaterDeforms.bind(null, C));\n  lua_register(L, 'GetTerrainType', GetTerrainType.bind(null, C));\n  lua_register(L, 'GetTerrainVariance', GetTerrainVariance.bind(null, C));\n  lua_register(L, 'SetTerrainType', SetTerrainType.bind(null, C));\n  lua_register(L, 'IsTerrainPathable', IsTerrainPathable.bind(null, C));\n  lua_register(L, 'SetTerrainPathable', SetTerrainPathable.bind(null, C));\n  lua_register(L, 'CreateImage', CreateImage.bind(null, C));\n  lua_register(L, 'DestroyImage', DestroyImage.bind(null, C));\n  lua_register(L, 'ShowImage', ShowImage.bind(null, C));\n  lua_register(L, 'SetImageConstantHeight', SetImageConstantHeight.bind(null, C));\n  lua_register(L, 'SetImagePosition', SetImagePosition.bind(null, C));\n  lua_register(L, 'SetImageColor', SetImageColor.bind(null, C));\n  lua_register(L, 'SetImageRender', SetImageRender.bind(null, C));\n  lua_register(L, 'SetImageRenderAlways', SetImageRenderAlways.bind(null, C));\n  lua_register(L, 'SetImageAboveWater', SetImageAboveWater.bind(null, C));\n  lua_register(L, 'SetImageType', SetImageType.bind(null, C));\n  lua_register(L, 'CreateUbersplat', CreateUbersplat.bind(null, C));\n  lua_register(L, 'DestroyUbersplat', DestroyUbersplat.bind(null, C));\n  lua_register(L, 'ResetUbersplat', ResetUbersplat.bind(null, C));\n  lua_register(L, 'FinishUbersplat', FinishUbersplat.bind(null, C));\n  lua_register(L, 'ShowUbersplat', ShowUbersplat.bind(null, C));\n  lua_register(L, 'SetUbersplatRender', SetUbersplatRender.bind(null, C));\n  lua_register(L, 'SetUbersplatRenderAlways', SetUbersplatRenderAlways.bind(null, C));\n  lua_register(L, 'SetBlight', SetBlight.bind(null, C));\n  lua_register(L, 'SetBlightRect', SetBlightRect.bind(null, C));\n  lua_register(L, 'SetBlightPoint', SetBlightPoint.bind(null, C));\n  lua_register(L, 'SetBlightLoc', SetBlightLoc.bind(null, C));\n  lua_register(L, 'CreateBlightedGoldmine', CreateBlightedGoldmine.bind(null, C));\n  lua_register(L, 'IsPointBlighted', IsPointBlighted.bind(null, C));\n  lua_register(L, 'SetDoodadAnimation', SetDoodadAnimation.bind(null, C));\n  lua_register(L, 'SetDoodadAnimationRect', SetDoodadAnimationRect.bind(null, C));\n  lua_register(L, 'StartMeleeAI', StartMeleeAI.bind(null, C));\n  lua_register(L, 'StartCampaignAI', StartCampaignAI.bind(null, C));\n  lua_register(L, 'CommandAI', CommandAI.bind(null, C));\n  lua_register(L, 'PauseCompAI', PauseCompAI.bind(null, C));\n  lua_register(L, 'GetAIDifficulty', GetAIDifficulty.bind(null, C));\n  lua_register(L, 'RemoveGuardPosition', RemoveGuardPosition.bind(null, C));\n  lua_register(L, 'RecycleGuardPosition', RecycleGuardPosition.bind(null, C));\n  lua_register(L, 'RemoveAllGuardPositions', RemoveAllGuardPositions.bind(null, C));\n  lua_register(L, 'Cheat', Cheat.bind(null, C));\n  lua_register(L, 'IsNoVictoryCheat', IsNoVictoryCheat.bind(null, C));\n  lua_register(L, 'IsNoDefeatCheat', IsNoDefeatCheat.bind(null, C));\n  lua_register(L, 'Preload', Preload.bind(null, C));\n  lua_register(L, 'PreloadEnd', PreloadEnd.bind(null, C));\n  lua_register(L, 'PreloadStart', PreloadStart.bind(null, C));\n  lua_register(L, 'PreloadRefresh', PreloadRefresh.bind(null, C));\n  lua_register(L, 'PreloadEndEx', PreloadEndEx.bind(null, C));\n  lua_register(L, 'PreloadGenClear', PreloadGenClear.bind(null, C));\n  lua_register(L, 'PreloadGenStart', PreloadGenStart.bind(null, C));\n  lua_register(L, 'PreloadGenEnd', PreloadGenEnd.bind(null, C));\n  lua_register(L, 'Preloader', Preloader.bind(null, C));\n  lua_register(L, 'AutomationTestStart', AutomationTestStart.bind(null, C));\n  lua_register(L, 'AutomationTestEnd', AutomationTestEnd.bind(null, C));\n  lua_register(L, 'BlzGetTriggerPlayerMouseX', BlzGetTriggerPlayerMouseX.bind(null, C));\n  lua_register(L, 'BlzGetTriggerPlayerMouseY', BlzGetTriggerPlayerMouseY.bind(null, C));\n  lua_register(L, 'BlzGetTriggerPlayerMousePosition', BlzGetTriggerPlayerMousePosition.bind(null, C));\n  lua_register(L, 'BlzGetTriggerPlayerMouseButton', BlzGetTriggerPlayerMouseButton.bind(null, C));\n  lua_register(L, 'BlzSetAbilityTooltip', BlzSetAbilityTooltip.bind(null, C));\n  lua_register(L, 'BlzSetAbilityActivatedTooltip', BlzSetAbilityActivatedTooltip.bind(null, C));\n  lua_register(L, 'BlzSetAbilityExtendedTooltip', BlzSetAbilityExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzSetAbilityActivatedExtendedTooltip', BlzSetAbilityActivatedExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzSetAbilityResearchTooltip', BlzSetAbilityResearchTooltip.bind(null, C));\n  lua_register(L, 'BlzSetAbilityResearchExtendedTooltip', BlzSetAbilityResearchExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzGetAbilityTooltip', BlzGetAbilityTooltip.bind(null, C));\n  lua_register(L, 'BlzGetAbilityActivatedTooltip', BlzGetAbilityActivatedTooltip.bind(null, C));\n  lua_register(L, 'BlzGetAbilityExtendedTooltip', BlzGetAbilityExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzGetAbilityActivatedExtendedTooltip', BlzGetAbilityActivatedExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzGetAbilityResearchTooltip', BlzGetAbilityResearchTooltip.bind(null, C));\n  lua_register(L, 'BlzGetAbilityResearchExtendedTooltip', BlzGetAbilityResearchExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzSetAbilityIcon', BlzSetAbilityIcon.bind(null, C));\n  lua_register(L, 'BlzGetAbilityIcon', BlzGetAbilityIcon.bind(null, C));\n  lua_register(L, 'BlzSetAbilityActivatedIcon', BlzSetAbilityActivatedIcon.bind(null, C));\n  lua_register(L, 'BlzGetAbilityActivatedIcon', BlzGetAbilityActivatedIcon.bind(null, C));\n  lua_register(L, 'BlzGetAbilityPosX', BlzGetAbilityPosX.bind(null, C));\n  lua_register(L, 'BlzGetAbilityPosY', BlzGetAbilityPosY.bind(null, C));\n  lua_register(L, 'BlzSetAbilityPosX', BlzSetAbilityPosX.bind(null, C));\n  lua_register(L, 'BlzSetAbilityPosY', BlzSetAbilityPosY.bind(null, C));\n  lua_register(L, 'BlzGetAbilityActivatedPosX', BlzGetAbilityActivatedPosX.bind(null, C));\n  lua_register(L, 'BlzGetAbilityActivatedPosY', BlzGetAbilityActivatedPosY.bind(null, C));\n  lua_register(L, 'BlzSetAbilityActivatedPosX', BlzSetAbilityActivatedPosX.bind(null, C));\n  lua_register(L, 'BlzSetAbilityActivatedPosY', BlzSetAbilityActivatedPosY.bind(null, C));\n  lua_register(L, 'BlzGetUnitMaxHP', BlzGetUnitMaxHP.bind(null, C));\n  lua_register(L, 'BlzSetUnitMaxHP', BlzSetUnitMaxHP.bind(null, C));\n  lua_register(L, 'BlzGetUnitMaxMana', BlzGetUnitMaxMana.bind(null, C));\n  lua_register(L, 'BlzSetUnitMaxMana', BlzSetUnitMaxMana.bind(null, C));\n  lua_register(L, 'BlzDeleteHeroAbility', BlzDeleteHeroAbility.bind(null, C));\n  lua_register(L, 'BlzSetItemName', BlzSetItemName.bind(null, C));\n  lua_register(L, 'BlzSetItemDescription', BlzSetItemDescription.bind(null, C));\n  lua_register(L, 'BlzGetItemDescription', BlzGetItemDescription.bind(null, C));\n  lua_register(L, 'BlzSetItemTooltip', BlzSetItemTooltip.bind(null, C));\n  lua_register(L, 'BlzGetItemTooltip', BlzGetItemTooltip.bind(null, C));\n  lua_register(L, 'BlzSetItemExtendedTooltip', BlzSetItemExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzGetItemExtendedTooltip', BlzGetItemExtendedTooltip.bind(null, C));\n  lua_register(L, 'BlzSetItemIconPath', BlzSetItemIconPath.bind(null, C));\n  lua_register(L, 'BlzGetItemIconPath', BlzGetItemIconPath.bind(null, C));\n  lua_register(L, 'BlzSetUnitName', BlzSetUnitName.bind(null, C));\n  lua_register(L, 'BlzSetHeroProperName', BlzSetHeroProperName.bind(null, C));\n  lua_register(L, 'BlzGetUnitBaseDamage', BlzGetUnitBaseDamage.bind(null, C));\n  lua_register(L, 'BlzSetUnitBaseDamage', BlzSetUnitBaseDamage.bind(null, C));\n  lua_register(L, 'BlzGetUnitDiceNumber', BlzGetUnitDiceNumber.bind(null, C));\n  lua_register(L, 'BlzSetUnitDiceNumber', BlzSetUnitDiceNumber.bind(null, C));\n  lua_register(L, 'BlzGetUnitDiceSides', BlzGetUnitDiceSides.bind(null, C));\n  lua_register(L, 'BlzSetUnitDiceSides', BlzSetUnitDiceSides.bind(null, C));\n  lua_register(L, 'BlzGetUnitAttackCooldown', BlzGetUnitAttackCooldown.bind(null, C));\n  lua_register(L, 'BlzSetUnitAttackCooldown', BlzSetUnitAttackCooldown.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectColorByPlayer', BlzSetSpecialEffectColorByPlayer.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectColor', BlzSetSpecialEffectColor.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectAlpha', BlzSetSpecialEffectAlpha.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectScale', BlzSetSpecialEffectScale.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectPosition', BlzSetSpecialEffectPosition.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectHeight', BlzSetSpecialEffectHeight.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectTimeScale', BlzSetSpecialEffectTimeScale.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectTime', BlzSetSpecialEffectTime.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectOrientation', BlzSetSpecialEffectOrientation.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectYaw', BlzSetSpecialEffectYaw.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectPitch', BlzSetSpecialEffectPitch.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectRoll', BlzSetSpecialEffectRoll.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectX', BlzSetSpecialEffectX.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectY', BlzSetSpecialEffectY.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectZ', BlzSetSpecialEffectZ.bind(null, C));\n  lua_register(L, 'BlzSetSpecialEffectPositionLoc', BlzSetSpecialEffectPositionLoc.bind(null, C));\n  lua_register(L, 'BlzGetLocalSpecialEffectX', BlzGetLocalSpecialEffectX.bind(null, C));\n  lua_register(L, 'BlzGetLocalSpecialEffectY', BlzGetLocalSpecialEffectY.bind(null, C));\n  lua_register(L, 'BlzGetLocalSpecialEffectZ', BlzGetLocalSpecialEffectZ.bind(null, C));\n  lua_register(L, 'BlzGetUnitArmor', BlzGetUnitArmor.bind(null, C));\n  lua_register(L, 'BlzSetUnitArmor', BlzSetUnitArmor.bind(null, C));\n  lua_register(L, 'BlzUnitHideAbility', BlzUnitHideAbility.bind(null, C));\n  lua_register(L, 'BlzUnitDisableAbility', BlzUnitDisableAbility.bind(null, C));\n  lua_register(L, 'BlzUnitCancelTimedLife', BlzUnitCancelTimedLife.bind(null, C));\n  lua_register(L, 'BlzIsUnitSelectable', BlzIsUnitSelectable.bind(null, C));\n  lua_register(L, 'BlzIsUnitInvulnerable', BlzIsUnitInvulnerable.bind(null, C));\n  lua_register(L, 'BlzUnitInterruptAttack', BlzUnitInterruptAttack.bind(null, C));\n  lua_register(L, 'BlzGetUnitCollisionSize', BlzGetUnitCollisionSize.bind(null, C));\n  lua_register(L, 'BlzGetAbilityManaCost', BlzGetAbilityManaCost.bind(null, C));\n  lua_register(L, 'BlzGetAbilityCooldown', BlzGetAbilityCooldown.bind(null, C));\n  lua_register(L, 'BlzSetUnitAbilityCooldown', BlzSetUnitAbilityCooldown.bind(null, C));\n  lua_register(L, 'BlzGetUnitAbilityCooldown', BlzGetUnitAbilityCooldown.bind(null, C));\n  lua_register(L, 'BlzGetUnitAbilityCooldownRemaining', BlzGetUnitAbilityCooldownRemaining.bind(null, C));\n  lua_register(L, 'BlzEndUnitAbilityCooldown', BlzEndUnitAbilityCooldown.bind(null, C));\n  lua_register(L, 'BlzGetUnitAbilityManaCost', BlzGetUnitAbilityManaCost.bind(null, C));\n  lua_register(L, 'BlzSetUnitAbilityManaCost', BlzSetUnitAbilityManaCost.bind(null, C));\n  lua_register(L, 'BlzGetLocalUnitZ', BlzGetLocalUnitZ.bind(null, C));\n  lua_register(L, 'BlzDecPlayerTechResearched', BlzDecPlayerTechResearched.bind(null, C));\n  lua_register(L, 'BlzSetEventDamage', BlzSetEventDamage.bind(null, C));\n}\n"
  },
  {
    "path": "src/utils/jass2/thread.ts",
    "content": "import { lua_newthread, lua_State } from 'fengari/src/lstate';\nimport JassTrigger from './types/trigger';\nimport JassTimer from './types/timer';\nimport JassUnit from './types/unit';\n\n/**\n * A thread.\n */\nexport default class Thread {\n  L: lua_State;\n  sleep = 0;\n  expiredTimer: JassTimer | null;\n  triggerUnit: JassUnit | null;\n  triggeringTrigger: JassTrigger | null;\n\n  constructor(L: lua_State, data: { expiredTimer?: JassTimer, triggerUnit?: JassUnit, triggeringTrigger?: JassTrigger }) {\n    this.L = lua_newthread(L);\n    this.expiredTimer = data.expiredTimer || null;\n    this.triggerUnit = data.triggerUnit || null;\n    this.triggeringTrigger = data.triggeringTrigger || null;\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/tokenstream.ts",
    "content": "import { stringToBase256 } from '../../common/typecast';\n\nexport default class TokenStream {\n  buffer: string;\n  index: number;\n\n  constructor(buffer: string) {\n    this.buffer = buffer;\n    this.index = 0;\n  }\n\n  read(): string | undefined {\n    const buffer = this.buffer;\n    const length = buffer.length;\n    let inComment = false;\n    let inString = false;\n    let inIdString = false;\n    let token = '';\n\n    while (this.index < length) {\n      const c = buffer[this.index++];\n\n      if (inComment) {\n        if (c === '\\n') {\n          inComment = false;\n          this.index--;\n        }\n      } else if (inString) {\n        if (c === '\\\\') {\n          token += c + buffer[this.index++];\n        } else if (c === '\\n') {\n          token += '\\\\n';\n        } else if (c === '\\r') {\n          token += '\\\\r';\n        } else {\n          token += c;\n        }\n\n        if (c === '\"') {\n          return token;\n        }\n      } else if (inIdString) {\n        token += c;\n\n        if (c === \"'\") {\n          return token;\n        }\n      } else if (c === ' ' || c === '\\t') {\n        if (token.length) {\n          return token;\n        }\n      } else if (c === '(' || c === ')' || c === '[' || c === ']' || c === '=' || c === '\\r' || c === '\\n' || c === ',' || c === '!' || c === '-' || c === '<' || c === '>' || c === '+' || c === '*' || c === '/') {\n        if (token.length) {\n          this.index--;\n          return token;\n        } else {\n          const c2 = buffer[this.index];\n\n          if (c === '=' && c2 === '=') {\n            this.index++;\n            return '==';\n          } else if (c === '\\r') {\n            if (c2 === '\\n') {\n              this.index++;\n            }\n\n            return '\\n';\n          } else if (c === '!' && c2 === '=') {\n            this.index++;\n            return '!=';\n          } else if (c === '/' && c2 === '/') {\n            if (token.length) {\n              this.index--;\n              return token;\n            } else {\n              inComment = true;\n            }\n          } else {\n            return c;\n          }\n        }\n      } else if (c === '\"') {\n        if (token.length) {\n          this.index--;\n          return token;\n        } else {\n          token += c;\n          inString = true;\n        }\n      } else if (c === \"'\") {\n        if (token.length) {\n          this.index--;\n          return token;\n        } else {\n          token += c;\n          inIdString = true;\n        }\n      } else {\n        token += c;\n      }\n\n      if (this.index === length) {\n        return token;\n      }\n    }\n\n    return;\n  }\n\n  /**\n   * Reads the next token without advancing the stream.\n   */\n  peek(): string | undefined {\n    const index = this.index;\n    const value = this.read();\n\n    this.index = index;\n\n    return value;\n  }\n\n  readSafe(): string {\n    const token = this.read();\n\n    if (token === undefined) {\n      throw new Error('Premature end of stream reached');\n    }\n\n    if (token === 'null') {\n      return 'nil';\n    } else if (token === '!=') {\n      return '~=';\n    } else if (token[0] === \"'\") {\n      return `${stringToBase256(token.slice(1, token.indexOf(\"'\", 1)))}`;\n    } else if (token === 'break' || token === 'do' || token === 'end' || token === 'for' || token === 'goto' || token === 'in' || token === 'nil' || token === 'repeat' || token === 'until' || token === 'while') { // Lua reserved keywords\n      return token + '_';\n    } else if (token === 'and' || token === 'or') {\n      return ' ' + token + ' ';\n    } else if (token[0] === '$') {\n      return '0x' + token.slice(1);\n    }\n\n    return token;\n  }\n\n  readUntil(delimiter: string): string {\n    let tokens = '';\n    let token;\n\n    while ((token = this.readSafe()) !== delimiter) {\n      tokens += token;\n    }\n\n    return tokens;\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/agent.ts",
    "content": "import JassHandle from './handle';\n\n/**\n * type agent\n */\nexport default class JassAgent extends JassHandle {}\n"
  },
  {
    "path": "src/utils/jass2/types/aidifficulty.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type aidifficulty\n */\nexport default class JassAiDifficulty extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/alliancetype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type alliancetype\n */\nexport default class JassAllianceType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/animtype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type animtype\n */\nexport default class JassAnimType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/attacktype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type attacktype\n */\nexport default class JassAttackType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/blendmode.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type blendmode\n */\nexport default class JassBlendMode extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/camerafield.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type camerafield\n */\nexport default class JassCameraField extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/camerasetup.ts",
    "content": "import JassHandle from './handle';\nimport JassLocation from './location';\n\n/**\n * type camerasetup\n */\nexport default class JassCameraSetup extends JassHandle {\n  targetDistance = 0;\n  farZ = 0;\n  angleOfAttack = 0;\n  fieldOfView = 0;\n  roll = 0;\n  rotation = 0;\n  zOffset = 0;\n  destPosition = new JassLocation(0, 0);\n}\n"
  },
  {
    "path": "src/utils/jass2/types/damagetype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type damagetype\n */\nexport default class JassDamageType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/dialogevent.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type dialogevent\n */\nexport default class JassDialogEvent extends JassEventId {}\n"
  },
  {
    "path": "src/utils/jass2/types/effecttype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type effecttype\n */\nexport default class JassEffectType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/enum.ts",
    "content": "import JassHandle from './handle';\n\n/**\n * Parent class for all enum types.\n */\nexport default class JassEnum extends JassHandle {\n  id: number;\n\n  constructor(value: number) {\n    super();\n\n    this.id = value;\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/eventid.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type eventid\n */\nexport default class JassEventId extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/fgamestate.ts",
    "content": "import JassGameState from './gamestate';\n\n/**\n * type fgamestate\n */\nexport default class JassFGameState extends JassGameState {}\n"
  },
  {
    "path": "src/utils/jass2/types/fogstate.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type fogstate\n */\nexport default class JassFogState extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/force.ts",
    "content": "import JassAgent from './agent';\nimport JassPlayer from './player';\n\n/**\n * type force\n */\nexport default class JassForce extends JassAgent {\n  players: Set<JassPlayer> = new Set();\n}\n"
  },
  {
    "path": "src/utils/jass2/types/gamedifficulty.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type gamedifficulty\n */\nexport default class JassGameDifficulty extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/gameevent.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type gameevent\n */\nexport default class JassGameEvent extends JassEventId {}\n"
  },
  {
    "path": "src/utils/jass2/types/gamespeed.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type gamespeed\n */\nexport default class JassGameSpeed extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/gamestate.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type gamestate\n */\nexport default class JassGameState extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/gametype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type gametype\n */\nexport default class JassGameType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/group.ts",
    "content": "import JassAgent from './agent';\nimport JassUnit from './unit';\n\n/**\n * type group\n */\nexport default class JassGroup extends JassAgent {\n  units: Set<JassUnit> = new Set();\n}\n"
  },
  {
    "path": "src/utils/jass2/types/handle.ts",
    "content": "/**\n * type handle\n */\nexport default class JassHandle {\n  handleId = -1;\n}\n"
  },
  {
    "path": "src/utils/jass2/types/hashtable.ts",
    "content": "import JassAgent from './agent';\n\n/**\n * type unit\n */\nexport default class JassHashTable extends JassAgent {\n  table: Map<number, Map<number, unknown>> = new Map();\n\n  save(parentKey: number, childKey: number, value: unknown): void {\n    const table = this.table;\n    let childTable = table.get(parentKey);\n\n    if (!childTable) {\n      childTable = new Map();\n\n      table.set(parentKey, childTable);\n    }\n\n    childTable.set(childKey, value);\n  }\n\n  load(parentKey: number, childKey: number, defaultValue?: unknown): unknown {\n    const table = this.table;\n    const childTable = table.get(parentKey);\n\n    if (childTable) {\n      const value = childTable.get(childKey);\n\n      if (value !== undefined) {\n        return value;\n      }\n    }\n\n    return defaultValue;\n  }\n\n  have(parentKey: number, childKey: number): boolean {\n    const table = this.table;\n    const childTable = table.get(parentKey);\n\n    if (!childTable) {\n      return false;\n    }\n\n    return childTable.has(childKey);\n  }\n\n  remove(parentKey: number, childKey: number): void {\n    const table = this.table;\n    const childTable = table.get(parentKey);\n\n    if (childTable) {\n      childTable.delete(childKey);\n\n      if (!childTable.size) {\n        table.delete(parentKey);\n      }\n    }\n  }\n\n  flush(): void {\n    this.table.clear();\n  }\n\n  flushChild(parentKey: number): void {\n    const child = this.table.get(parentKey);\n\n    if (child) {\n      child.clear();\n    }\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/igamestate.ts",
    "content": "import JassGameState from './gamestate';\n\n/**\n * type igamestate\n */\nexport default class JassIGameState extends JassGameState {}\n"
  },
  {
    "path": "src/utils/jass2/types/index.ts",
    "content": "import JassHandle from './handle';\nimport JassAgent from './agent';\n// import JassEvent from './event';\nimport JassPlayer from './player';\nimport JassWidget from './widget';\nimport JassUnit from './unit';\n// import JassDestructable from './destructable';\n// import JassItem from './item';\n// import JassAbility from './ability';\n// import JassBuff from './buff';\nimport JassForce from './force';\nimport JassGroup from './group';\nimport JassTrigger from './trigger';\n// import JassTriggerCondition from './triggercondition';\n// import JassTriggerAction from './triggeraction';\nimport JassTimer from './timer';\nimport JassLocation from './location';\nimport JassRegion from './region';\nimport JassRect from './rect';\n// import JassBoolexpr from './boolexpr';\n// import JassSound from './sound';\n// import JassConditionFunc from './conditionfunc';\n// import JassFilterFunc from './filterfunc';\n// import JassUnitPool from './unitpool';\n// import JassItemPool from './itempool';\nimport JassRace from './race';\nimport JassAllianceType from './alliancetype';\nimport JassRacePreference from './racepreference';\nimport JassGameState from './gamestate';\nimport JassIGameState from './igamestate';\nimport JassFGameState from './fgamestate';\nimport JassPlayerState from './playerstate';\nimport JassPlayerScore from './playerscore';\nimport JassPlayerGameResult from './playergameresult';\nimport JassUnitState from './unitstate';\nimport JassAiDifficulty from './aidifficulty';\nimport JassEventId from './eventid';\nimport JassGameEvent from './gameevent';\nimport JassPlayerEvent from './playerevent';\nimport JassPlayerUnitEvent from './playerunitevent';\nimport JassUnitEvent from './unitevent';\nimport JassLimitOp from './limitop';\nimport JassWidgetEvent from './widgetevent';\nimport JassDialogEvent from './dialogevent';\nimport JassUnitType from './unittype';\nimport JassGameSpeed from './gamespeed';\nimport JassGameDifficulty from './gamedifficulty';\nimport JassGameType from './gametype';\nimport JassMapFlag from './mapflag';\nimport JassMapVisibility from './mapvisibility';\nimport JassMapSetting from './mapsetting';\nimport JassMapDensity from './mapdensity';\nimport JassMapControl from './mapcontrol';\nimport JassPlayerSlotState from './playerslotstate';\nimport JassVolumeGroup from './volumegroup';\nimport JassCameraField from './camerafield';\nimport JassCameraSetup from './camerasetup';\nimport JassPlayerColor from './playercolor';\nimport JassPlacement from './placement';\nimport JassStartLocPrio from './startlocprio';\nimport JassRarityControl from './raritycontrol';\nimport JassBlendMode from './blendmode';\nimport JassTexMapFlags from './texmapflags';\n// import JassEffect from './effect';\nimport JassEffectType from './effecttype';\nimport JassWeatherEffect from './weathereffect';\n// import JassTerrainDeformation from './terraindeformation';\nimport JassFogState from './fogstate';\n// import JassFogModifier from './fogmodifier';\n// import JassDialog from './dialog';\n// import JassButton from './button';\n// import JassQuest from './quest';\n// import JassQuestItem from './questitem';\n// import JassDefeatCondition from './defeatcondition';\n// import JassTimerDialog from './timerdialog';\n// import JassLeaderboard from './leaderboard';\n// import JassMultiboard from './multiboard';\n// import JassMultiboardItem from './multiboarditem';\n// import JassTrackable from './trackable';\n// import JassGameCache from './gamecache';\nimport JassVersion from './version';\nimport JassItemType from './itemtype';\n// import JassTextTag from './texttag';\nimport JassAttackType from './attacktype';\nimport JassDamageType from './damagetype';\nimport JassWeaponType from './weapontype';\nimport JassSoundType from './soundtype';\n// import JassLightning from './lightning';\nimport JassPathingType from './pathingtype';\n// import JassImage from './image';\n// import JassUbersplat from './ubersplat';\nimport JassHashtable from './hashtable';\n\nexport {\n  JassHandle,\n  JassAgent,\n  // JassEvent,\n  JassPlayer,\n  JassWidget,\n  JassUnit,\n  // JassDestructable,\n  // JassItem,\n  // JassAbility,\n  // JassBuff,\n  JassForce,\n  JassGroup,\n  JassTrigger,\n  // JassTriggerCondition,\n  // JassTriggerAction,\n  JassTimer,\n  JassLocation,\n  JassRegion,\n  JassRect,\n  // JassBoolexpr,\n  // JassSound,\n  // JassConditionFunc,\n  // JassFilterFunc,\n  // JassUnitPool,\n  // JassItemPool,\n  JassRace,\n  JassAllianceType,\n  JassRacePreference,\n  JassGameState,\n  JassIGameState,\n  JassFGameState,\n  JassPlayerState,\n  JassPlayerScore,\n  JassPlayerGameResult,\n  JassUnitState,\n  JassAiDifficulty,\n  JassEventId,\n  JassGameEvent,\n  JassPlayerEvent,\n  JassPlayerUnitEvent,\n  JassUnitEvent,\n  JassLimitOp,\n  JassWidgetEvent,\n  JassDialogEvent,\n  JassUnitType,\n  JassGameSpeed,\n  JassGameDifficulty,\n  JassGameType,\n  JassMapFlag,\n  JassMapVisibility,\n  JassMapSetting,\n  JassMapDensity,\n  JassMapControl,\n  JassPlayerSlotState,\n  JassVolumeGroup,\n  JassCameraField,\n  JassCameraSetup,\n  JassPlayerColor,\n  JassPlacement,\n  JassStartLocPrio,\n  JassRarityControl,\n  JassBlendMode,\n  JassTexMapFlags,\n  // JassEffect,\n  JassEffectType,\n  JassWeatherEffect,\n  // JassTerrainDeformation,\n  JassFogState,\n  // JassFogModifier,\n  // JassDialog,\n  // JassButton,\n  // JassQuest,\n  // JassQuestItem,\n  // JassDefeatCondition,\n  // JassTimerDialog,\n  // JassLeaderboard,\n  // JassMultiboard,\n  // JassMultiboardItem,\n  // JassTrackable,\n  // JassGameCache,\n  JassVersion,\n  JassItemType,\n  // JassTextTag,\n  JassAttackType,\n  JassDamageType,\n  JassWeaponType,\n  JassSoundType,\n  // JassLightning,\n  JassPathingType,\n  // JassImage,\n  // JassUbersplat,\n  JassHashtable\n};\n"
  },
  {
    "path": "src/utils/jass2/types/itemtype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type itemtype\n */\nexport default class JassItemType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/limitop.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type limitop\n */\nexport default class JassLimitOp extends JassEventId {}\n"
  },
  {
    "path": "src/utils/jass2/types/location.ts",
    "content": "import JassAgent from './agent';\n\n/**\n * type location\n */\nexport default class JassLocation extends JassAgent {\n  x: number;\n  y: number;\n  z = 0;\n\n  constructor(x: number, y: number) {\n    super();\n\n    this.x = x;\n    this.y = y;\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/mapcontrol.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type mapcontrol\n */\nexport default class JassMapControl extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/mapdensity.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type mapdensity\n */\nexport default class JassMapDensity extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/mapflag.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type mapflag\n */\nexport default class JassMapFlag extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/mapsetting.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type mapflag\n */\nexport default class JassMapFlag extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/mapvisibility.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type mapvisibility\n */\nexport default class JassMapVisibility extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/mousebuttontype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type buttontype\n */\nexport default class JassMouseButtonType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/pathingtype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type pathingtype\n */\nexport default class JassPathingType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/placement.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type placement\n */\nexport default class JassPlacement extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/player.ts",
    "content": "import JassAgent from './agent';\n\nexport interface Alliance {\n  passive: boolean,\n  helpRequest: boolean,\n  helpResponse: boolean,\n  sharedXp: boolean,\n  sharedSpells: boolean,\n  sharedVision: boolean,\n  sharedControl: boolean,\n  sharedAdvancedControl: boolean,\n  rescuable: boolean,\n  sharedVisionForced: boolean,\n}\n\n/**\n * type player\n */\nexport default class JassPlayer extends JassAgent {\n  index: number;\n  name: string;\n  team = -1;\n  startLocation = -1;\n  forcedStartLocation = -1;\n  color = -1;\n  race = 0;\n  racePreference = -1;\n  raceSelectable = false;\n  controller = -1;\n  alliances: Map<number, Alliance> = new Map();\n\n  constructor(index: number, maxPlayers: number) {\n    super();\n\n    this.index = index;\n    this.name = `Player ${index}`;\n\n    for (let i = 0; i < maxPlayers; i++) {\n      if (i !== index) {\n        this.alliances.set(i, {\n          passive: false,\n          helpRequest: false,\n          helpResponse: false,\n          sharedXp: false,\n          sharedSpells: false,\n          sharedVision: false,\n          sharedControl: false,\n          sharedAdvancedControl: false,\n          rescuable: false,\n          sharedVisionForced: false,\n        });\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/playercolor.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type playercolor\n */\nexport default class JassPlayerColor extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/playerevent.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type playerevent\n */\nexport default class JassPlayerEvent extends JassEventId {}\n"
  },
  {
    "path": "src/utils/jass2/types/playergameresult.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type playergameresult\n */\nexport default class JassPlayerGameResult extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/playerscore.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type playerscore\n */\nexport default class JassPlayerScore extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/playerslotstate.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type playerslotstate\n */\nexport default class JassPlayerSlotState extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/playerstate.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type playerstate\n */\nexport default class JassPlayerState extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/playerunitevent.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type playerunitevent\n */\nexport default class JassPlayerUnitEvent extends JassEventId {}\n"
  },
  {
    "path": "src/utils/jass2/types/race.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type race\n */\nexport default class JassRace extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/racepreference.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type racepreference\n */\nexport default class JassRacePreference extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/raritycontrol.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type raritycontrol\n */\nexport default class JassRarityControl extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/rect.ts",
    "content": "import JassAgent from './agent';\n\n/**\n * type rect\n */\nexport default class JassRect extends JassAgent {\n  center: Float32Array;\n  min: Float32Array;\n  max: Float32Array;\n\n  constructor(minx: number, miny: number, maxx: number, maxy: number) {\n    super();\n\n    this.center = new Float32Array([maxx - minx, maxy - miny]);\n    this.min = new Float32Array([minx, miny]);\n    this.max = new Float32Array([maxx, maxy]);\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/region.ts",
    "content": "import JassAgent from './agent';\nimport JassRect from './rect';\n\n/**\n * type region\n */\nexport default class JassRegion extends JassAgent {\n  rects: Set<JassRect> = new Set();\n}\n"
  },
  {
    "path": "src/utils/jass2/types/soundtype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type soundtype\n */\nexport default class JassSoundType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/startlocprio.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type startlocprio\n */\nexport default class JassStartLocPrio extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/subanimtype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type subanimtype\n */\nexport default class JassSubAnimType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/texmapflags.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type texmapflags\n */\nexport default class JassTexMapFlags extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/timer.ts",
    "content": "import JassAgent from './agent';\n\n/**\n * type timer\n */\nexport default class JassTimer extends JassAgent {\n  elapsed = 0;\n  timeout = 0;\n  periodic = false;\n  handlerFunc = -1;\n}\n"
  },
  {
    "path": "src/utils/jass2/types/trigger.ts",
    "content": "import JassAgent from './agent';\n\n/**\n * type trigger\n */\nexport default class JassTrigger extends JassAgent {\n  events: number[] = [];\n  conditions: number[] = [];\n  actions: number[] = [];\n  enabled = true;\n}\n"
  },
  {
    "path": "src/utils/jass2/types/unit.ts",
    "content": "import { base256ToString } from '../../../common/typecast';\nimport JassWidget from './widget';\nimport JassPlayer from './player';\n\n/**\n * type unit\n */\nexport default class JassUnit extends JassWidget {\n  player: JassPlayer;\n  unitId: string;\n  x: number;\n  y: number;\n  face: number;\n  acquireRange = 500;\n\n  constructor(player: JassPlayer, unitId: number, x: number, y: number, face: number) {\n    super();\n\n    this.player = player;\n    this.unitId = base256ToString(unitId);\n    this.x = x;\n    this.y = y;\n    this.face = face;\n\n    // if (balanceRow) {\n    //   this.balanceRow = balanceRow;\n    //   this.health = balanceRow.realHP;\n    //   this.maxHealth = this.health;\n    //   this.mana = parseFloat(balanceRow.realM) || 0;\n    //   this.maxMana = this.mana;\n    // } else if (jass.debugMode) {\n    //   console.log('Unknown unitid', unitId);\n    // }\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/unitevent.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type unitevent\n */\nexport default class JassUnitEvent extends JassEventId {}\n"
  },
  {
    "path": "src/utils/jass2/types/unitstate.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type unitstate\n */\nexport default class JassUnitState extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/unittype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type unittype\n */\nexport default class JassUnitType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/version.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type version\n */\nexport default class JassVersion extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/volumegroup.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type volumegroup\n */\nexport default class JassVolumeGroup extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/weapontype.ts",
    "content": "import JassEnum from './enum';\n\n/**\n * type weapontype\n */\nexport default class JassWeaponType extends JassEnum {}\n"
  },
  {
    "path": "src/utils/jass2/types/weathereffect.ts",
    "content": "import JassHandle from './handle';\nimport JassRect from './rect';\n\n/**\n * type weathereffect\n */\nexport default class JassWeatherEffect extends JassHandle {\n  whichRect: JassRect;\n  effectId: string;\n  enabled = false;\n\n  constructor(whichRect: JassRect, effectId: string) {\n    super();\n\n    this.whichRect = whichRect;\n    this.effectId = effectId;\n  }\n}\n"
  },
  {
    "path": "src/utils/jass2/types/widget.ts",
    "content": "import JassAgent from './agent';\n\n/**\n * type widget\n */\nexport default class JassWidget extends JassAgent {\n  health = 0;\n  maxHealth = 0;\n}\n"
  },
  {
    "path": "src/utils/jass2/types/widgetevent.ts",
    "content": "import JassEventId from './eventid';\n\n/**\n * type widgetevent\n */\nexport default class JassWidgetEvent extends JassEventId {}\n"
  },
  {
    "path": "src/utils/mappeddata.ts",
    "content": "import SlkFile from '../parsers/slk/file';\nimport { IniFile } from '../parsers/ini/file';\n\n/**\n * A MappedData row.\n */\nexport class MappedDataRow {\n  map: {[key: string]: string } = {};\n\n  set(key: string, value: string | number): void {\n    if (typeof value !== 'string') {\n      value = value.toString();\n    }\n\n    this.map[key.toLowerCase()] = value;\n  }\n\n  string(key: string): string | undefined {\n    return this.map[key.toLowerCase()];\n  }\n\n  number(key: string): number {\n    const string = this.string(key);\n\n    if (!string) {\n      return 0;\n    }\n    \n    return parseFloat(string);\n  }\n}\n\n/**\n * A structure that holds mapped data from INI and SLK files.\n * \n * In the case of SLK files, the first row is expected to hold the names of the columns.\n */\nexport class MappedData {\n  map: {[key: string]: MappedDataRow } = {};\n\n  constructor(buffer?: string) {\n    if (buffer) {\n      this.load(buffer);\n    }\n  }\n\n  /**\n   * Load data from an SLK file or an INI file.\n   * \n   * Note that this may override previous properties!\n   */\n  load(buffer: string): void {\n    if (buffer.startsWith('ID;')) {\n      const file = new SlkFile();\n      file.load(buffer);\n\n      const rows = file.rows;\n      const header = rows[0];\n      const map = this.map;\n\n      for (let i = 1, l = rows.length; i < l; i++) {\n        const row = rows[i];\n\n        // DialogueDemonBase.slk has an empty row.\n        if (row) {\n          const name = row[0];\n\n          // DialogueDemonBase.slk also has rows containing only a single underline.\n          if (name && name !== '_') {\n            if (!map[name]) {\n              map[name] = new MappedDataRow();\n            }\n\n            const mapped = map[name];\n\n            for (let j = 0, k = header.length; j < k; j++) {\n              let key = header[j];\n\n              // UnitBalance.slk doesn't define the name of one column.\n              if (key === undefined) {\n                key = `column${j}`;\n              }\n\n              mapped.map[key.toLowerCase()] = row[j];\n            }\n          }\n        }\n      }\n    } else {\n      const file = new IniFile();\n      file.load(buffer);\n\n      const sections = file.sections;\n      const map = this.map;\n\n      for (const [row, properties] of sections.entries()) {\n        if (!map[row]) {\n          map[row] = new MappedDataRow();\n        }\n\n        const mapped = map[row];\n\n        for (const [name, property] of properties) {\n          mapped.map[name.toLowerCase()] = property;\n        }\n      }\n    }\n  }\n\n  getRow(key: string): MappedDataRow | undefined {\n    return this.map[key];\n  }\n\n  getProperty(key: string, name: string): string {\n    return this.map[key].map[name];\n  }\n\n  setRow(key: string, values: MappedDataRow): void {\n    this.map[key] = values;\n  }\n\n  findRow(key: string, expectedValue: string): MappedDataRow | undefined {\n    for (const row of Object.values(this.map)) {\n      if (row.string(key) === expectedValue) {\n        return row;\n      }\n    }\n\n    return;\n  }\n}\n"
  },
  {
    "path": "src/utils/mdlx/index.ts",
    "content": "import sanityTest from './sanitytest/sanitytest';\nimport createPrimitive from './primitives/createprimitive';\nimport * as primitives from './primitives/primitives';\nimport mdlStructure from './mdlstructure';\n\nexport default {\n  sanityTest,\n  createPrimitive,\n  primitives,\n  mdlStructure,\n};\n"
  },
  {
    "path": "src/utils/mdlx/mdlstructure.ts",
    "content": "import Attachment from '../../parsers/mdlx/attachment';\nimport Bone from '../../parsers/mdlx/bone';\nimport Camera from '../../parsers/mdlx/camera';\nimport CollisionShape from '../../parsers/mdlx/collisionshape';\nimport FaceEffect from '../../parsers/mdlx/faceeffect';\nimport Geoset from '../../parsers/mdlx/geoset';\nimport GeosetAnimation from '../../parsers/mdlx/geosetanimation';\nimport Helper from '../../parsers/mdlx/helper';\nimport Layer from '../../parsers/mdlx/layer';\nimport Light from '../../parsers/mdlx/light';\nimport Model from '../../parsers/mdlx/model';\nimport ParticleEmitter from '../../parsers/mdlx/particleemitter';\nimport ParticleEmitter2 from '../../parsers/mdlx/particleemitter2';\nimport ParticleEmitterPopcorn from '../../parsers/mdlx/particleemitterpopcorn';\nimport RibbonEmitter from '../../parsers/mdlx/ribbonemitter';\nimport Sequence from '../../parsers/mdlx/sequence';\nimport Texture from '../../parsers/mdlx/texture';\nimport TextureAnimation from '../../parsers/mdlx/textureanimation';\nimport TokenStream from '../../parsers/mdlx/tokenstream';\nimport { getObjectName, getObjectTypeName } from './sanitytest/utils';\n\ninterface MdlStructureNode {\n  name: string;\n  source: string;\n  nodes?: MdlStructureNode[];\n}\n\nfunction mdlObjects(stream: TokenStream, model: Model, objects: (Sequence | Layer | Texture | TextureAnimation | Geoset | GeosetAnimation | Bone | Light | Helper | Attachment | ParticleEmitter | ParticleEmitter2 | ParticleEmitterPopcorn | RibbonEmitter | Camera | CollisionShape | FaceEffect)[], out: MdlStructureNode[]): void {\n  if (objects.length) {\n    for (const [index, object] of objects.entries()) {\n      object.writeMdl(stream, model.version);\n      out.push({ name: getObjectName(object, index), source: stream.buffer });\n      stream.clear();\n    }\n  }\n}\n\nfunction mdlObjectsBlock(stream: TokenStream, model: Model, objects: (Sequence | Texture | TextureAnimation)[], out: MdlStructureNode[]): void {\n  if (objects.length) {\n    const name = getObjectTypeName(objects[0]) + 's';\n    const nodes = <MdlStructureNode[]>[];\n\n    mdlObjects(stream, model, objects, nodes);\n\n    model.saveStaticObjectsBlock(stream, name, objects);\n    out.push({ name, source: stream.buffer, nodes });\n    stream.clear();\n  }\n}\n\nexport default function mdlStructure(model: Model): MdlStructureNode[] {\n  const stream = new TokenStream();\n  const out = <MdlStructureNode[]>[];\n\n  model.saveVersionBlock(stream);\n  out.push({ name: 'Version', source: stream.buffer });\n  stream.clear();\n\n  model.saveModelBlock(stream);\n  out.push({ name: 'Model', source: stream.buffer });\n  stream.clear();\n\n  mdlObjectsBlock(stream, model, model.sequences, out);\n\n  if (model.globalSequences.length) {\n    model.saveGlobalSequenceBlock(stream);\n    out.push({ name: 'GlobalSequences', source: stream.buffer });\n    stream.clear();\n  }\n\n  mdlObjectsBlock(stream, model, model.textures, out);\n\n  if (model.materials.length) {\n    const nodes = [];\n\n    for (const [index, material] of model.materials.entries()) {\n      const layerNodes = <MdlStructureNode[]>[];\n\n      mdlObjects(stream, model, material.layers, layerNodes);\n\n      material.writeMdl(stream, model.version);\n      nodes.push({ name: `Material ${index}`, source: stream.buffer, nodes: layerNodes });\n      stream.clear();\n    }\n\n    model.saveStaticObjectsBlock(stream, 'Materials', model.materials);\n    out.push({ name: 'Materials', source: stream.buffer, nodes });\n    stream.clear();\n  }\n\n  mdlObjectsBlock(stream, model, model.textureAnimations, out);\n  mdlObjects(stream, model, model.geosets, out);\n  mdlObjects(stream, model, model.geosetAnimations, out);\n  mdlObjects(stream, model, model.bones, out);\n  mdlObjects(stream, model, model.lights, out);\n  mdlObjects(stream, model, model.helpers, out);\n  mdlObjects(stream, model, model.attachments, out);\n\n  if (model.pivotPoints.length) {\n    model.savePivotPointBlock(stream);\n    out.push({ name: 'PivotPoints', source: stream.buffer });\n    stream.clear();\n  }\n\n  mdlObjects(stream, model, model.particleEmitters, out);\n  mdlObjects(stream, model, model.particleEmitters2, out);\n  mdlObjects(stream, model, model.particleEmittersPopcorn, out);\n  mdlObjects(stream, model, model.ribbonEmitters, out);\n  mdlObjects(stream, model, model.cameras, out);\n  mdlObjects(stream, model, model.eventObjects, out);\n  mdlObjects(stream, model, model.collisionShapes, out);\n  mdlObjects(stream, model, model.faceEffects, out);\n\n  if (model.bindPose.length) {\n    model.saveBindPoseBlock(stream);\n    out.push({ name: 'BindPose', source: stream.buffer });\n    stream.clear();\n  }\n\n  return out;\n}\n"
  },
  {
    "path": "src/utils/mdlx/primitives/createprimitive.ts",
    "content": "import MdlxModel from '../../../parsers/mdlx/model';\nimport MdlxTexture from '../../../parsers/mdlx/texture';\nimport MdlxMaterial from '../../../parsers/mdlx/material';\nimport MdlxLayer, { Flags } from '../../../parsers/mdlx/layer';\nimport MdlxGeoset from '../../../parsers/mdlx/geoset';\nimport MdlxGeosetAnimation from '../../../parsers/mdlx/geosetanimation';\nimport MdlxBone from '../../../parsers/mdlx/bone';\nimport ModelViewer from '../../../viewer/viewer';\nimport Texture from '../../../viewer/texture';\nimport { PathSolver } from '../../../viewer/handlerresource';\nimport MdxModel from '../../../viewer/handlers/mdx/model';\n\ninterface Primitive {\n  vertices: Float32Array;\n  uvs: Float32Array;\n  faces: Uint16Array;\n  edges: Uint16Array;\n  boundingRadius: number;\n}\n\ninterface Material {\n  lines?: boolean;\n  color?: Float32Array;\n  texture?: Texture | Promise<Texture>;\n  twoSided?: boolean;\n}\n\nexport default function createPrimitive(viewer: ModelViewer, primitive: Primitive, material: Material): Promise<MdxModel | undefined> {\n  let lines: boolean | undefined;\n  let color: Float32Array | undefined;\n  let texture: Texture | Promise<Texture> | undefined;\n  let layerFlags = Flags.Unshaded;\n\n  if (material) {\n    lines = material.lines;\n    color = material.color;\n    texture = material.texture;\n\n    if (material.twoSided) {\n      layerFlags |= Flags.TwoSided;\n    }\n  }\n\n  const model = new MdlxModel();\n\n  // Extent\n  const extent = model.extent;\n  const r = primitive.boundingRadius;\n\n  extent.min.fill(-r);\n  extent.max.fill(r);\n  extent.boundsRadius = r;\n\n  // Texture\n  const tex = new MdlxTexture();\n\n  tex.path = 'PLACEHOLDER';\n\n  model.textures[0] = tex;\n\n  const pathSolver: PathSolver = (src: unknown): unknown => {\n    if (src === model) {\n      return model;\n    }\n\n    return texture;\n  };\n\n  // Material\n  const mat = new MdlxMaterial();\n\n  const layer = new MdlxLayer();\n\n  layer.textureId = 0;\n  layer.flags = layerFlags;\n\n  mat.layers[0] = layer;\n\n  model.materials[0] = mat;\n\n  // Geoset\n  const geoset = new MdlxGeoset();\n\n  geoset.vertices = primitive.vertices;\n  geoset.uvSets[0] = primitive.uvs;\n  geoset.matrixGroups = new Uint32Array([1]);\n  geoset.matrixIndices = new Uint32Array([0]);\n  geoset.vertexGroups = new Uint8Array(primitive.vertices.length / 3);\n\n  let faceTypeGroup = 4;\n  let indices = primitive.faces;\n\n  if (lines) {\n    faceTypeGroup = 1;\n    indices = primitive.edges;\n  }\n\n  geoset.faceTypeGroups = new Uint32Array([faceTypeGroup]);\n  geoset.faceGroups = new Uint32Array([indices.length]);\n  geoset.faces = indices;\n\n  model.geosets[0] = geoset;\n\n  // Color via a geoset animation.\n  if (color) {\n    const geosetAnimation = new MdlxGeosetAnimation();\n\n    geosetAnimation.geosetId = 0;\n    geosetAnimation.color = color;\n\n    model.geosetAnimations[0] = geosetAnimation;\n  }\n\n  // Bone - otherwise can't transform the instance.\n  const bone = new MdlxBone();\n\n  bone.objectId = 0;\n\n  model.bones[0] = bone;\n\n  // Load and return the promise.\n  return <Promise<MdxModel | undefined>>viewer.load(model, pathSolver);\n}\n"
  },
  {
    "path": "src/utils/mdlx/primitives/primitives.ts",
    "content": "interface PrimitiveShape {\n  vertices: Float32Array;\n  uvs: Float32Array;\n  faces: Uint16Array;\n  edges: Uint16Array;\n  boundingRadius: number;\n}\n\n/**\n * Creates a rectangle geometry object.\n */\nexport function createRectangle(w: number, d: number): PrimitiveShape {\n  return {\n    vertices: new Float32Array([-w, d, 0, -w, -d, 0, w, -d, 0, w, d, 0]),\n    uvs: new Float32Array([0, 0, 0, 1, 1, 1, 1, 0]),\n    faces: new Uint16Array([0, 1, 2, 0, 2, 3]),\n    edges: new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0]),\n    boundingRadius: Math.hypot(w, d),\n  };\n}\n\n/**\n * Creates a unit rectangle geometry object.\n */\nexport function createUnitRectangle(): PrimitiveShape {\n  return createRectangle(1, 1);\n}\n\n/**\n * Creates a cube geometry object.\n */\nexport function createCube(w: number, d: number, h: number): PrimitiveShape {\n  return {\n    vertices: new Float32Array([-w, -d, -h, -w, -d, h, -w, d, -h, -w, d, h, w, d, -h, w, d, h, w, -d, -h, w, -d, h]),\n    uvs: new Float32Array([0, 0, 0, 1, 0.25, 0, 0.25, 1, 0.5, 0, 0.5, 1, 0.75, 0, 0.75, 1]),\n    faces: new Uint16Array([0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 5, 4, 4, 5, 6, 5, 7, 6, 6, 7, 0, 7, 1, 0, 0, 2, 4, 0, 4, 6, 1, 5, 3, 1, 7, 5]),\n    edges: new Uint16Array([0, 1, 2, 3, 4, 5, 6, 7, 0, 2, 2, 4, 4, 6, 6, 0, 1, 3, 3, 5, 5, 7, 7, 1]),\n    boundingRadius: Math.hypot(w, d, h),\n  };\n}\n\n/**\n * Creates a unit cube geometry object.\n */\nexport function createUnitCube(): PrimitiveShape {\n  return createCube(1, 1, 1);\n}\n\n/**\n * Creates a sphere geometry object.\n */\nexport function createSphere(radius: number, stacks: number, slices: number): PrimitiveShape {\n  const points = (stacks + 1) * (slices + 1);\n  const vertices = new Float32Array(points * 3);\n  const uvs = new Float32Array(points * 2);\n  const faces = new Uint16Array(stacks * slices * 6);\n  const edges = new Uint16Array(stacks * slices * 6);\n\n  for (let stack = 0, vOffset = 0, uOffset = 0; stack <= stacks; stack++) {\n    const theta = stack * Math.PI / stacks;\n    const sinTheta = Math.sin(theta);\n    const cosTheta = Math.cos(theta);\n\n    for (let slice = 0; slice <= slices; slice += 1, vOffset += 3, uOffset += 2) {\n      const phi = slice * 2 * Math.PI / slices;\n      const sinPhi = Math.sin(phi);\n      const cosPhi = Math.cos(phi);\n\n      vertices[vOffset + 0] = cosPhi * sinTheta * radius;\n      vertices[vOffset + 1] = sinPhi * sinTheta * radius;\n      vertices[vOffset + 2] = cosTheta * radius;\n\n      uvs[uOffset + 0] = slice / slices;\n      uvs[uOffset + 1] = 1 - (stack / stacks);\n    }\n  }\n\n  for (let stack = 0, fOffset = 0; stack < stacks; stack++) {\n    for (let slice = 0; slice < slices; slice += 1, fOffset += 6) {\n      const first = (stack * (slices + 1)) + slice;\n      const second = first + slices + 1;\n\n      // Faces\n      faces[fOffset + 0] = first;\n      faces[fOffset + 1] = second;\n      faces[fOffset + 2] = first + 1;\n\n      faces[fOffset + 3] = second;\n      faces[fOffset + 4] = second + 1;\n      faces[fOffset + 5] = first + 1;\n\n      // Edges\n      edges[fOffset + 0] = first;\n      edges[fOffset + 1] = second;\n\n      edges[fOffset + 2] = first;\n      edges[fOffset + 3] = first + 1;\n\n      edges[fOffset + 4] = second;\n      edges[fOffset + 5] = second + 1;\n    }\n  }\n\n  return {\n    vertices: vertices,\n    uvs: uvs,\n    faces: faces,\n    edges: edges,\n    boundingRadius: radius,\n  };\n}\n\n/**\n * Creates a unit sphere geometry object.\n */\nexport function createUnitSphere(stacks: number, slices: number): PrimitiveShape {\n  return createSphere(1, stacks, slices);\n}\n\n/**\n * Creates a cylinder geometry object.\n */\nexport function createCylinder(radius: number, height: number, slices: number): PrimitiveShape {\n  slices = Math.max(slices, 3);\n\n  const points = (slices + 1) * 2 + 2;\n  const vertices = new Float32Array(points * 3);\n  const uvs = new Float32Array(points * 2);\n  const faces = new Uint16Array(slices * 12);\n  const edges = new Uint16Array(slices * 10);\n  const step = (Math.PI * 2) / slices;\n  let vOffset = 0;\n  let uOffset = 0;\n\n  for (let slice = 0; slice < slices + 1; slice += 1, vOffset += 6, uOffset += 4) {\n    const x = Math.cos(step * slice) * radius;\n    const y = Math.sin(step * slice) * radius;\n    const u = slice / slices;\n\n    vertices[vOffset + 0] = x;\n    vertices[vOffset + 1] = y;\n    vertices[vOffset + 2] = height;\n    vertices[vOffset + 3] = x;\n    vertices[vOffset + 4] = y;\n    vertices[vOffset + 5] = -height;\n\n    uvs[uOffset + 0] = u;\n    uvs[uOffset + 1] = 1;\n    uvs[uOffset + 2] = u;\n    uvs[uOffset + 3] = 0;\n  }\n\n  // Poles\n  vertices[vOffset + 0] = 0;\n  vertices[vOffset + 1] = 0;\n  vertices[vOffset + 2] = height;\n\n  vertices[vOffset + 3] = 0;\n  vertices[vOffset + 4] = 0;\n  vertices[vOffset + 5] = -height;\n\n  uvs[uOffset + 0] = 0;\n  uvs[uOffset + 1] = 1;\n\n  uvs[uOffset + 2] = 0;\n  uvs[uOffset + 3] = 0;\n\n  for (let slice = 0, fOffset = 0, eOffset = 0; slice < slices; slice += 1, fOffset += 12, eOffset += 10) {\n    const first = slice * 2;\n\n    // Faces\n    faces[fOffset + 0] = first + 0;\n    faces[fOffset + 1] = first + 1;\n    faces[fOffset + 2] = (first + 3) % (points - 2);\n\n    faces[fOffset + 3] = first + 0;\n    faces[fOffset + 4] = (first + 3) % (points - 2);\n    faces[fOffset + 5] = (first + 2) % (points - 2);\n\n    faces[fOffset + 6] = first + 0;\n    faces[fOffset + 7] = (first + 2) % (points - 2);\n    faces[fOffset + 8] = points - 2;\n\n    faces[fOffset + 9] = first + 1;\n    faces[fOffset + 10] = (first + 3) % (points - 2);\n    faces[fOffset + 11] = points - 1;\n\n    // Edges\n    edges[eOffset + 0] = first + 0;\n    edges[eOffset + 1] = first + 1;\n\n    edges[eOffset + 2] = first + 0;\n    edges[eOffset + 3] = (first + 2) % (points - 2);\n\n    edges[eOffset + 4] = first + 1;\n    edges[eOffset + 5] = (first + 3) % (points - 2);\n\n    edges[eOffset + 6] = first + 0;\n    edges[eOffset + 7] = points - 2;\n\n    edges[eOffset + 8] = first + 1;\n    edges[eOffset + 9] = points - 1;\n  }\n\n  return {\n    vertices: vertices,\n    uvs: uvs,\n    faces: faces,\n    edges: edges,\n    boundingRadius: Math.hypot(radius, height),\n  };\n}\n\n/**\n * Creates a unit cylinder geometry object.\n */\nexport function createUnitCylinder(slices: number): PrimitiveShape {\n  return createCylinder(1, 1, slices);\n}\n\n/**\n * Create a furstum geometry.\n */\nexport function createFrustum(fieldOfView: number, aspectRatio: number, nearClipPlane: number, farClipPlane: number): PrimitiveShape {\n  const tanFov = 2 * Math.tan(fieldOfView / 2);\n  const nearHeight = (tanFov * nearClipPlane) / 2;\n  const nearWidth = (nearClipPlane * aspectRatio) / 2;\n  const farHeight = (tanFov * farClipPlane) / 2;\n  const farWidth = (farClipPlane * aspectRatio) / 2;\n\n  return {\n    vertices: new Float32Array([\n      -nearWidth, -nearHeight, nearClipPlane,\n      -nearWidth, nearHeight, nearClipPlane,\n      -farWidth, -farHeight, farClipPlane,\n      -farWidth, farHeight, farClipPlane,\n      farWidth, -farHeight, farClipPlane,\n      farWidth, farHeight, farClipPlane,\n      nearWidth, -nearHeight, nearClipPlane,\n      nearWidth, nearHeight, nearClipPlane]),\n    uvs: new Float32Array([0, 0, 0, 1, 0.25, 0, 0.25, 1, 0.5, 0, 0.5, 1, 0.75, 0, 0.75, 1]),\n    faces: new Uint16Array([0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 5, 4, 4, 5, 6, 5, 7, 6, 6, 7, 0, 7, 1, 0, 0, 2, 4, 0, 4, 6, 1, 5, 3, 1, 7, 5]),\n    edges: new Uint16Array([0, 1, 2, 3, 4, 5, 6, 7, 0, 2, 2, 4, 4, 6, 6, 0, 1, 3, 3, 5, 5, 7, 7, 1]),\n    boundingRadius: Math.hypot(farWidth, farHeight),\n  };\n}\n"
  },
  {
    "path": "src/utils/mdlx/sanitytest/data.ts",
    "content": "import Model from '../../../parsers/mdlx/model';\nimport GenericObject from '../../../parsers/mdlx/genericobject';\nimport { getObjectName, MdlxType } from './utils';\n\nexport interface SanityTestMessage {\n  type: 'error' | 'severe' | 'warning' | 'unused';\n  message: string;\n}\n\nexport interface SanityTestNode {\n  type: 'node';\n  name: string;\n  errors: number;\n  severe: number;\n  warnings: number;\n  unused: number;\n  nodes: (SanityTestNode | SanityTestMessage)[];\n  uses?: number;\n}\n\nexport default class SanityTestData {\n  model: Model;\n  objects: GenericObject[] = [];\n  current: SanityTestNode;\n  stack: SanityTestNode[];\n  map: Map<MdlxType, SanityTestNode> = new Map();\n  foundStand = false;\n  foundDeath = false;\n  boneUsageMap = new Map();\n\n  constructor(model: Model) {\n    this.model = model;\n    this.current = { type: 'node', name: '', errors: 0, severe: 0, warnings: 0, unused: 0, nodes: []};\n    this.stack = [this.current];\n\n    this.addObjects(model.sequences);\n    this.addObjects(model.globalSequences);\n    this.addObjects(model.textures);\n    this.addObjects(model.materials);\n    this.addObjects(model.textureAnimations);\n    this.addObjects(model.geosets);\n    this.addObjects(model.geosetAnimations);\n    this.addObjects(model.bones);\n    this.addObjects(model.lights);\n    this.addObjects(model.helpers);\n    this.addObjects(model.attachments);\n    this.addObjects(model.particleEmitters);\n    this.addObjects(model.particleEmitters2);\n    this.addObjects(model.particleEmittersPopcorn);\n    this.addObjects(model.ribbonEmitters);\n    this.addObjects(model.cameras);\n    this.addObjects(model.eventObjects);\n    this.addObjects(model.collisionShapes);\n    this.addObjects(model.faceEffects);\n  }\n\n  /**\n   * Adds nodes for all of the given objects.\n   * Also handles the flat array of generic objects.\n   */\n  addObjects(objects: MdlxType[]): void {\n    if (objects.length) {\n      const areGeneric = objects[0] instanceof GenericObject;\n\n      for (let i = 0, l = objects.length; i < l; i++) {\n        const object = objects[i];\n        const name = getObjectName(object, i);\n        const node = <SanityTestNode>{ type: 'node', name, errors: 0, severe: 0, warnings: 0, unused: 0, nodes: []};\n\n        if (!areGeneric) {\n          node.uses = 0;\n        }\n\n        this.map.set(object, node);\n      }\n\n      if (areGeneric) {\n        this.objects.push(...<GenericObject[]>objects);\n      }\n    }\n  }\n\n  /**\n   * Pushes to the stack the node the given object maps to.\n   * If this node does not exist, a new one will be created, which is used by internal nodes like material layers.\n   */\n  push(object: MdlxType, index: number): void {\n    let node = this.map.get(object);\n\n    if (!node) {\n      const name = getObjectName(object, index);\n\n      node = <SanityTestNode>{ type: 'node', name, errors: 0, severe: 0, warnings: 0, unused: 0, nodes: []};\n    }\n\n    this.current.nodes.push(node);\n    this.current = node;\n    this.stack.unshift(node);\n  }\n\n  /**\n   * Pops the current node from the stack.\n   */\n  pop(): void {\n    this.stack.shift();\n    this.current = this.stack[0];\n  }\n\n  /**\n   * Adds a reference to the node the given object maps to.\n   */\n  addReference(object: MdlxType): void {\n    const node = <SanityTestNode>this.map.get(object);\n\n    if (node.uses !== undefined) {\n      node.uses += 1;\n    }\n  }\n\n  /**\n   * Add a reference to the current node.\n   */\n  addImplicitReference(): void {\n    const node = this.current;\n\n    if (node.uses !== undefined) {\n      node.uses += 1;\n    }\n  }\n\n  addError(message: string): void {\n    this.current.nodes.push({ type: 'error', message });\n\n    for (const node of this.stack) {\n      node.errors += 1;\n    }\n  }\n\n  addSevere(message: string): void {\n    this.current.nodes.push({ type: 'severe', message });\n\n    for (const node of this.stack) {\n      node.severe += 1;\n    }\n  }\n\n  addWarning(message: string): void {\n    this.current.nodes.push({ type: 'warning', message });\n\n    for (const node of this.stack) {\n      node.warnings += 1;\n    }\n  }\n\n  addUnused(message: string): void {\n    this.current.nodes.push({ type: 'unused', message });\n\n    for (const node of this.stack) {\n      node.unused += 1;\n    }\n  }\n\n  assertError(condition: boolean, message: string): void {\n    if (!condition) {\n      this.addError(message);\n    }\n  }\n\n  assertSevere(condition: boolean, message: string): void {\n    if (!condition) {\n      this.addSevere(message);\n    }\n  }\n\n  assertWarning(condition: boolean, message: string): void {\n    if (!condition) {\n      this.addWarning(message);\n    }\n  }\n\n  assertUnused(condition: boolean, message: string): void {\n    if (!condition) {\n      this.addUnused(message);\n    }\n  }\n}\n"
  },
  {
    "path": "src/utils/mdlx/sanitytest/sanitytest.ts",
    "content": "import Model from '../../../parsers/mdlx/model';\nimport SanityTestData, { SanityTestMessage, SanityTestNode } from './data';\nimport { testObjects, cleanNode } from './utils';\nimport { testHeader, testSequences, testGlobalSequence, testTextures, testMaterial, testGeoset, testGeosetAnimation, testBone, testLight, testAttachments, testPivotPoints, testParticleEmitter, testParticleEmitter2, testParticleEmitterPopcorn, testRibbonEmitter, testEventObject, testCamera, testFaceEffect, testBindPose } from './testers';\n\nexport interface SanityTestResult {\n  type: string;\n  nodes: (SanityTestNode | SanityTestMessage)[];\n  errors: number;\n  severe: number;\n  warnings: number;\n  unused: number;\n}\n\n/**\n * Run a sanity test on the model and return the results.\n */\nexport default function sanityTest(model: Model): SanityTestResult {\n  const data = new SanityTestData(model);\n\n  // Run the tests.\n  testHeader(data);\n  testSequences(data);\n  testObjects(data, model.globalSequences, testGlobalSequence);\n  testTextures(data);\n  testObjects(data, model.materials, testMaterial);\n  testObjects(data, model.textureAnimations);\n  testObjects(data, model.geosets, testGeoset);\n  testObjects(data, model.geosetAnimations, testGeosetAnimation);\n  testObjects(data, model.bones, testBone);\n  testObjects(data, model.lights, testLight);\n  testObjects(data, model.helpers);\n  testAttachments(data);\n  testPivotPoints(data);\n  testObjects(data, model.particleEmitters, testParticleEmitter);\n  testObjects(data, model.particleEmitters2, testParticleEmitter2);\n\n  if (model.version > 800) {\n    testObjects(data, model.particleEmittersPopcorn, testParticleEmitterPopcorn);\n  }\n\n  testObjects(data, model.ribbonEmitters, testRibbonEmitter);\n  testObjects(data, model.eventObjects, testEventObject);\n  testObjects(data, model.cameras, testCamera);\n  testObjects(data, model.collisionShapes);\n\n  if (model.version > 800) {\n    testObjects(data, model.faceEffects, testFaceEffect);\n    testBindPose(data);\n  }\n\n  const root = data.stack[0];\n\n  // Remove nodes that passed the test.\n  cleanNode(root);\n\n  const { nodes, errors, severe, warnings } = root;\n  let { unused } = root;\n\n  // Add top-level objects that are not used.\n  for (const node of nodes) {\n    if (node.type === 'node') {\n      if (node.uses === 0) {\n        unused += 1;\n      }\n    }\n  }\n\n  return { type: 'node', nodes, errors, severe, warnings, unused };\n}\n"
  },
  {
    "path": "src/utils/mdlx/sanitytest/testers.ts",
    "content": "import { extname } from '../../../common/path';\nimport Sequence from '../../../parsers/mdlx/sequence';\nimport Texture from '../../../parsers/mdlx/texture';\nimport Material from '../../../parsers/mdlx/material';\nimport Layer, { FilterMode as LayerFilterMode } from '../../../parsers/mdlx/layer';\nimport Geoset from '../../../parsers/mdlx/geoset';\nimport GeosetAnimation from '../../../parsers/mdlx/geosetanimation';\nimport Bone from '../../../parsers/mdlx/bone';\nimport Light from '../../../parsers/mdlx/light';\nimport ParticleEmitter from '../../../parsers/mdlx/particleemitter';\nimport ParticleEmitter2, { FilterMode as Particle2FilterMode, Flags as Particle2Flags } from '../../../parsers/mdlx/particleemitter2';\nimport ParticleEmitterPopcorn from '../../../parsers/mdlx/particleemitterpopcorn';\nimport RibbonEmitter from '../../../parsers/mdlx/ribbonemitter';\nimport EventObject from '../../../parsers/mdlx/eventobject';\nimport Camera from '../../../parsers/mdlx/camera';\nimport FaceEffect from '../../../parsers/mdlx/faceeffect';\nimport SanityTestData from './data';\nimport { sequenceNames, replaceableIds, testObjects, testReference, getTextureIds, testGeosetSkinning, hasAnimation, getAnimation, testExtent, testAndGetReference } from './utils';\nimport testTracks from './tracks';\n\nexport function testHeader(data: SanityTestData): void {\n  const version = data.model.version;\n\n  if (version !== 800 && version !== 900 && version !== 1000) {\n    data.addWarning(`Unknown version: ${version}`);\n  }\n\n  if (version === 900) {\n    data.addError('Version 900 is not supported by Warcrft 3');\n  }\n\n  if (data.model.animationFile !== '') {\n    data.addWarning(`The animation file should probably be empty, currently set to: \"${data.model.animationFile}\"`);\n  }\n\n  testExtent(data, data.model.extent);\n}\n\nexport function testSequences(data: SanityTestData): void {\n  const sequences = data.model.sequences;\n\n  if (sequences.length) {\n    testObjects(data, sequences, testSequence);\n\n    data.assertSevere(data.foundStand, 'Missing \"Stand\" sequence');\n    data.assertSevere(data.foundDeath, 'Missing \"Death\" sequence');\n  } else {\n    data.addWarning('No sequences');\n  }\n}\n\nfunction testSequence(data: SanityTestData, sequence: Sequence, index: number): void {\n  const name = sequence.name;\n  const tokens = name.toLowerCase().trim().split('-')[0].split(/\\s+/);\n  let token = tokens[0];\n  const interval = sequence.interval;\n  const length = interval[1] - interval[0];\n  const sequences = data.model.sequences;\n\n  for (let i = 0; i < index; i++) {\n    const otherSequence = sequences[i];\n    const otherInterval = otherSequence.interval;\n\n    // Reforged fixed these weird issues with sequence ordering.\n    if (data.model.version === 800) {\n      if (interval[0] === otherInterval[0]) {\n        data.addSevere(`This sequence starts at the same frame as sequence ${i} \"${otherSequence.name}\"`);\n      } else if (interval[0] < otherInterval[1]) {\n        data.addSevere(`This sequence starts before sequence ${i} \"${otherSequence.name}\" ends`);\n      }\n    }\n  }\n\n  if (token === 'alternate') {\n    token = tokens[1];\n  }\n\n  if (token === 'stand') {\n    data.foundStand = true;\n  }\n\n  if (token === 'death') {\n    data.foundDeath = true;\n  }\n\n  data.addImplicitReference();\n\n  data.assertWarning(sequenceNames.has(token), `\"${token}\" is not a standard name`);\n  data.assertWarning(length !== 0, 'Zero length');\n  data.assertWarning(length > -1, `Negative length: ${length}`);\n\n  testExtent(data, sequence.extent);\n}\n\nexport function testGlobalSequence(data: SanityTestData, sequence: number): void {\n  data.assertWarning(sequence !== 0, 'Zero length');\n  data.assertWarning(sequence >= 0, `Negative length: ${sequence}`);\n}\n\nexport function testTextures(data: SanityTestData): void {\n  const textures = data.model.textures;\n\n  if (textures.length) {\n    testObjects(data, textures, testTexture);\n  } else {\n    data.addWarning('No textures');\n  }\n}\n\nfunction testTexture(data: SanityTestData, texture: Texture): void {\n  const replaceableId = texture.replaceableId;\n  const path = texture.path.toLowerCase();\n  const ext = extname(path);\n\n  data.assertError(path === '' || ext === '.blp' || ext === '.tga' || ext === '.tif' || ext === '.dds', `Corrupted path: \"${path}\"`);\n  data.assertError(replaceableId === 0 || replaceableIds.has(replaceableId), `Unknown replaceable ID: ${replaceableId}`);\n  data.assertWarning(path === '' || replaceableId === 0, `Path \"${path}\" and replaceable ID ${replaceableId} used together`);\n}\n\nexport function testMaterial(data: SanityTestData, material: Material): void {\n  const layers = material.layers;\n  const shader = material.shader;\n\n  if (data.model.version > 800) {\n    data.assertWarning(shader === '' || shader === 'Shader_SD_FixedFunction' || shader === 'Shader_HD_DefaultUnit', `Unknown shader: \"${shader}\"`);\n  }\n\n  if (layers.length) {\n    testObjects(data, layers, testLayer);\n  } else {\n    data.addWarning('No layers');\n  }\n}\n\nfunction testLayer(data: SanityTestData, layer: Layer): void {\n  const textures = data.model.textures;\n  const textureAnimations = data.model.textureAnimations;\n\n  for (const textureId of getTextureIds(layer)) {\n    testReference(data, textures, textureId, 'texture');\n  }\n\n  const textureAnimationId = layer.textureAnimationId;\n\n  if (textureAnimationId !== -1) {\n    testReference(data, textureAnimations, textureAnimationId, 'texture animation');\n  }\n\n  const filterMode = layer.filterMode;\n\n  data.assertWarning(filterMode >= LayerFilterMode.None && filterMode <= LayerFilterMode.Modulate2x, `Invalid filter mode: ${layer.filterMode}`);\n}\n\nexport function testGeoset(data: SanityTestData, geoset: Geoset, index: number): void {\n  const geosetAnimations = data.model.geosetAnimations;\n  const material = testAndGetReference(data, data.model.materials, geoset.materialId, 'material');\n  let isHd = false;\n\n  if (material && material.shader === 'Shader_HD_DefaultUnit') {\n    isHd = true;\n  }\n\n  if (!isHd) {\n    // When a geoset has too many vertices (or faces? or both?) it will render completely bugged in WC3.\n    // I don't know the exact number, but here are numbers that I tested:\n    //\n    //     Verts   Faces   Result\n    //     ----------------------\n    //     7433    16386   Bugged\n    //     7394    16290   Good\n    //\n    const GUESSED_MAX_VERTICES = 7433 * 3;\n\n    data.assertSevere(geoset.vertices.length < GUESSED_MAX_VERTICES, `Too many vertices in one geoset: ${geoset.vertices.length / 3}`);\n  }\n\n  testGeosetSkinning(data, geoset);\n\n  if (geosetAnimations.length) {\n    const references = [];\n\n    for (let j = 0, k = geosetAnimations.length; j < k; j++) {\n      if (geosetAnimations[j].geosetId === index) {\n        references.push(j);\n      }\n    }\n\n    data.assertWarning(references.length <= 1, `Referenced by ${references.length} geoset animations: ${references.join(', ')}`);\n  }\n\n  if (geoset.faces.length) {\n    data.addImplicitReference();\n  } else {\n    // The game and my code have no issue with geosets containing no faces, but Magos crashes, so add a warning in addition to it being useless.\n    data.addWarning('Zero faces');\n  }\n\n  // The game and my code have no issue with geosets having any number of sequence extents, but Magos fails to parse, so add a warning.\n  // Either way this is only relevant to version 800, because there seem to always be 0 extents in >800 models.\n  if (geoset.sequenceExtents.length !== data.model.sequences.length && data.model.version === 800) {\n    data.addWarning(`Number of sequence extents (${geoset.sequenceExtents.length}) does not match the number of sequences (${data.model.sequences.length})`);\n  }\n\n  testExtent(data, geoset.extent);\n\n  for (const extent of geoset.sequenceExtents) {\n    testExtent(data, extent);\n  }\n}\n\nexport function testGeosetAnimation(data: SanityTestData, geosetAnimation: GeosetAnimation): void {\n  const geosets = data.model.geosets;\n  const geosetId = geosetAnimation.geosetId;\n\n  data.addImplicitReference();\n\n  testReference(data, geosets, geosetId, 'geoset');\n}\n\nconst SUPPOSED_ALPHA_THRESHOLD = 0.1;\n\nexport function testBone(data: SanityTestData, bone: Bone, index: number): void {\n  const geosets = data.model.geosets;\n  const geosetAnimations = data.model.geosetAnimations;\n  const geosetId = bone.geosetId;\n  const geosetAnimationId = bone.geosetAnimationId;\n\n  if (geosetId !== -1) {\n    testReference(data, geosets, geosetId, 'geoset');\n  }\n\n  if (geosetAnimationId !== -1 && testReference(data, geosetAnimations, geosetAnimationId, 'geoset animation')) {\n    const geosetAnimation = geosetAnimations[geosetAnimationId];\n\n    if (geosetId !== -1 && geosetAnimation.alpha < SUPPOSED_ALPHA_THRESHOLD && !hasAnimation(geosetAnimation, 'KGAO')) {\n      data.addSevere(`Referencing geoset ${geosetId} and geoset animation ${geosetAnimationId} with a 0 alpha, the geoset may be invisible`);\n    }\n  }\n\n  data.assertWarning(data.boneUsageMap.get(index) > 0, `There are no vertices attached to this bone`);\n}\n\nexport function testLight(data: SanityTestData, light: Light): void {\n  const attenuation = light.attenuation;\n\n  data.assertWarning(attenuation[0] >= 80, `Minimum attenuation should probably be bigger than or equal to 80, but is ${attenuation[0]}`);\n  data.assertWarning(attenuation[1] <= 200, `Maximum attenuation should probably be smaller than or equal to 200, but is ${attenuation[1]}`);\n  data.assertWarning(attenuation[1] - attenuation[0] > 0, `The maximum attenuation should be bigger than the minimum, but isn't`);\n}\n\nexport function testAttachments(data: SanityTestData): void {\n  const attachments = data.model.attachments;\n  let foundOrigin = false;\n\n  for (const attachment of attachments) {\n    const path = attachment.path;\n\n    if (path.length) {\n      const lowerCase = path.toLowerCase();\n\n      data.assertError(lowerCase.endsWith('.mdl') || lowerCase.endsWith('.mdx'), `Invalid path \"${path}\"`);\n    }\n  \n    if (attachment.name.startsWith('Origin Ref')) {\n      foundOrigin = true;\n    }\n  }\n\n  if (!foundOrigin) {\n    data.addWarning('Missing the Origin attachment point');\n  }\n}\n\nexport function testPivotPoints(data: SanityTestData): void {\n  const pivotPoints = data.model.pivotPoints;\n  const objects = data.objects;\n\n  data.assertWarning(pivotPoints.length === objects.length, `Expected ${objects.length} pivot points, got ${pivotPoints.length}`);\n}\n\nexport function testParticleEmitter(data: SanityTestData, emitter: ParticleEmitter): void {\n  const path = emitter.path.toLowerCase();\n\n  data.assertError(path.endsWith('.mdl') || path.endsWith('.mdx'), 'Invalid path');\n}\n\nexport function testParticleEmitter2(data: SanityTestData, emitter: ParticleEmitter2): void {\n  const replaceableId = emitter.replaceableId;\n\n  testReference(data, data.model.textures, emitter.textureId, 'texture');\n\n  const filterMode = emitter.filterMode;\n\n  data.assertWarning(filterMode >= Particle2FilterMode.Blend && filterMode <= Particle2FilterMode.AlphaKey, `Invalid filter mode: ${emitter.filterMode}`);\n  data.assertError(replaceableId === 0 || replaceableIds.has(replaceableId), `Invalid replaceable ID: ${replaceableId}`);\n\n  if (emitter.flags & Particle2Flags.XYQuad) {\n    data.assertSevere(emitter.speed !== 0 && emitter.latitude !== 0, 'XY Quad emitters must have a non-zero speed and latitude');\n  }\n\n  data.assertSevere(emitter.timeMiddle >= 0 && emitter.timeMiddle <= 1, `Expected time middle to be between 0 and 1, got ${emitter.timeMiddle}`);\n\n  if (emitter.squirt && !getAnimation(emitter, 'KP2E')) {\n    data.addSevere('Using squirt without animating the emission rate');\n  }\n}\n\nexport function testParticleEmitterPopcorn(data: SanityTestData, emitter: ParticleEmitterPopcorn): void {\n  data.assertSevere(emitter.animationVisiblityGuide.length > 0, 'No animation visibility guide');\n}\n\nexport function testRibbonEmitter(data: SanityTestData, emitter: RibbonEmitter): void {\n  testReference(data, data.model.materials, emitter.materialId, 'material');\n}\n\nexport function testEventObject(data: SanityTestData, eventObject: EventObject): void {\n  testTracks(data, eventObject);\n}\n\nexport function testCamera(data: SanityTestData, _camera: Camera): void {\n  // I don't know what the rules are as to when cameras are used for portraits.\n  // Therefore, for now never report them as not used.\n  data.addImplicitReference();\n}\n\nexport function testFaceEffect(data: SanityTestData, faceEffect: FaceEffect): void {\n  const path = faceEffect.path;\n\n  if (path.length) {\n    data.assertError(path.endsWith('.facefx') || path.endsWith('.facefx_ingame'), `Corrupted face effect path: \"${path}\"`);\n  }\n\n  data.addImplicitReference();\n}\n\nexport function testBindPose(data: SanityTestData): void {\n  const matrices = data.model.bindPose;\n  const objects = data.objects;\n\n  if (matrices.length && objects.length) { \n    // There's always an extra matrix for some reason.\n    // Face effects? but also models with no face effects have it.\n    data.assertWarning(matrices.length === objects.length + 1, `Expected ${objects.length + 1} matrices, got ${matrices.length}`);\n  }\n}\n"
  },
  {
    "path": "src/utils/mdlx/sanitytest/tracks.ts",
    "content": "import { Animation, InterpolationType } from '../../../parsers/mdlx/animations';\nimport EventObject from '../../../parsers/mdlx/eventobject';\nimport SanityTestData from './data';\nimport { testReference } from './utils';\n\nfunction getSequenceFromFrame(data: SanityTestData, frame: number, globalSequenceId: number): number {\n  if (globalSequenceId === -1) {\n    const sequences = data.model.sequences;\n\n    for (let i = 0, l = sequences.length; i < l; i++) {\n      const interval = sequences[i].interval;\n\n      if (frame >= interval[0] && frame <= interval[1]) {\n        return i;\n      }\n    }\n  } else {\n    const end = data.model.globalSequences[globalSequenceId];\n\n    if (frame >= 0 && frame <= end) {\n      return globalSequenceId;\n    }\n  }\n\n  return -1;\n}\n\nfunction seprateTracks(data: SanityTestData, frames: number[] | Uint32Array, globalSequenceId: number, separated: number[][]): void {\n  let lastFrame = -Infinity;\n\n  for (let i = 0, l = frames.length; i < l; i++) {\n    const frame = frames[i];\n\n    data.assertWarning(frame >= 0, `Track ${i} has a negative frame ${frame}`);\n\n    if (frame === lastFrame) {\n      data.addWarning(`Track ${i} has the same frame ${frame} as track ${i - 1}`);\n    } else if (frame < lastFrame) {\n      data.addSevere(`Track ${i} at frame ${frame} is lower than the track before it at ${lastFrame}`);\n    }\n\n    const sequence = getSequenceFromFrame(data, frame, globalSequenceId);\n\n    if (sequence !== -1) {\n      separated[sequence].push(i);\n    } else {\n      // Frame 0 seems to be special.\n      // Or maybe it's the first keyframe regardless of the frame.\n      // Who knows.\n      if (frame !== 0 && frames.length > 1) {\n        if (globalSequenceId === -1) {\n          data.addUnused(`Track ${i} at frame ${frame} is not in any sequence`);\n        } else {\n          data.addUnused(`Track ${i} at frame ${frame} is not in global sequence ${globalSequenceId}`);\n        }\n      }\n    }\n\n    lastFrame = frame;\n  }\n}\n\nfunction getSequenceName(data: SanityTestData, sequence: number, globalSequenceId: number): string {\n  if (globalSequenceId === -1) {\n    return `sequence \"${data.model.sequences[sequence].name}\"`;\n  } else {\n    return `global sequence ${globalSequenceId}`;\n  }\n}\n\nconst EPSILON = 0.001;\n\nexport function getValuesDiff(a: Uint32Array | Float32Array, b: Uint32Array | Float32Array, c: Uint32Array | Float32Array): number {\n  let d = 0;\n\n  for (let i = 0, l = a.length; i < l; i++) {\n    const ai = a[i];\n    const d1 = Math.abs(ai - b[i]);\n    const d2 = Math.abs(ai - c[i]);\n\n    if (d1 > d) {\n      d = d1;\n    }\n\n    if (d2 > d) {\n      d = d2;\n    }\n  }\n\n  return d;\n}\n\nexport function areValuesEqual(a: Uint32Array | Float32Array, b: Uint32Array | Float32Array): boolean {\n  for (let i = 0, l = a.length; i < l; i++) {\n    if (a[i] !== b[i]) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction testSequenceTracks(data: SanityTestData, indices: number[], sequence: number, object: Animation, frames: number[] | Uint32Array): void {\n  const { globalSequenceId, interpolationType, values } = object;\n  let start;\n\n  if (globalSequenceId === -1) {\n    start = data.model.sequences[sequence].interval[0];\n  } else {\n    start = 0;\n  }\n\n  const firstIndex = indices[0];\n  const lastIndex = indices[indices.length - 1];\n  const firstFrame = frames[firstIndex];\n\n  // Missing the opening track for a specific sequence can cause bugged warping with negative interpolations.\n  if (interpolationType !== InterpolationType.DontInterp && firstFrame !== start) {\n    const firstValue = values[firstIndex];\n    const lastValue = values[lastIndex];\n\n    // If the first and last values are equal, even though there's warping, it won't do anything.\n    if (!areValuesEqual(firstValue, lastValue)) {\n      data.addSevere(`Missing opening track for ${getSequenceName(data, sequence, globalSequenceId)} at frame ${start} where it is needed`);\n    }\n  }\n\n  // Check for consecutive tracks with the same values.\n  if (indices.length > 2) {\n    let a = values[indices[0]];\n    let b = values[indices[1]];\n\n    for (let i = 2, l = indices.length; i < l; i++) {\n      const c = values[indices[i]];\n      const index = indices[i - 1];\n      const d = getValuesDiff(a, b, c);\n\n      if (d === 0) {\n        data.addUnused(`Track ${index} at frame ${frames[index]} has exactly the same value as tracks ${index - 1} and ${index + 1}`);\n      } else if (d < EPSILON) {\n        data.addUnused(`Track ${index} at frame ${frames[index]} has roughly the same value as tracks ${index - 1} and ${index + 1}`);\n      }\n\n      a = b;\n      b = c;\n    }\n  }\n}\n\nexport default function testTracks(data: SanityTestData, object: Animation | EventObject): void {\n  let framesOrTracks;\n\n  if (object instanceof Animation) {\n    data.assertWarning(object.frames.length > 0, 'Zero tracks');\n\n    framesOrTracks = object.frames;\n  } else {\n    data.assertError(object.tracks.length > 0, 'Zero tracks');\n\n    framesOrTracks = object.tracks;\n  }\n\n  const globalSequenceId = object.globalSequenceId;\n  const separated: number[][] = [];\n\n  if (globalSequenceId === -1) {\n    data.assertWarning(data.model.sequences.length > 0, 'This animation exists, but the model has no sequences');\n\n    for (let i = 0, l = data.model.sequences.length; i < l; i++) {\n      separated.push([]);\n    }\n  } else if (testReference(data, data.model.globalSequences, globalSequenceId, 'global sequence')) {\n    separated[globalSequenceId] = [];\n  } else {\n    return;\n  }\n\n  seprateTracks(data, framesOrTracks, globalSequenceId, separated);\n\n  // Since event objects work on the concept of notes, where a keyframe denotes emission, check just animation keyframe values.\n  if (object instanceof Animation) {\n    for (let i = 0, l = separated.length; i < l; i++) {\n      const indices = separated[i];\n\n      if (indices && indices.length > 1) {\n        testSequenceTracks(data, indices, i, object, framesOrTracks);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/utils/mdlx/sanitytest/utils.ts",
    "content": "import unique from '../../../common/arrayunique';\nimport { basename } from '../../../common/path';\nimport { Animation, InterpolationType } from '../../../parsers/mdlx/animations';\nimport AnimatedObject from '../../../parsers/mdlx/animatedobject';\nimport GenericObject from '../../../parsers/mdlx/genericobject';\nimport Extent from '../../../parsers/mdlx/extent';\nimport Sequence from '../../../parsers/mdlx/sequence';\nimport Texture from '../../../parsers/mdlx/texture';\nimport Material from '../../../parsers/mdlx/material';\nimport Layer from '../../../parsers/mdlx/layer';\nimport TextureAnimation from '../../../parsers/mdlx/textureanimation';\nimport Geoset from '../../../parsers/mdlx/geoset';\nimport GeosetAnimation from '../../../parsers/mdlx/geosetanimation';\nimport Bone from '../../../parsers/mdlx/bone';\nimport Light from '../../../parsers/mdlx/light';\nimport Helper from '../../../parsers/mdlx/helper';\nimport Attachment from '../../../parsers/mdlx/attachment';\nimport ParticleEmitter from '../../../parsers/mdlx/particleemitter';\nimport ParticleEmitter2 from '../../../parsers/mdlx/particleemitter2';\nimport ParticleEmitterPopcorn from '../../../parsers/mdlx/particleemitterpopcorn';\nimport RibbonEmitter from '../../../parsers/mdlx/ribbonemitter';\nimport EventObject from '../../../parsers/mdlx/eventobject';\nimport Camera from '../../../parsers/mdlx/camera';\nimport CollisionShape from '../../../parsers/mdlx/collisionshape';\nimport FaceEffect from '../../../parsers/mdlx/faceeffect';\nimport SanityTestData from './data';\nimport testTracks from './tracks';\nimport { SanityTestNode } from './data';\n\nexport function isBetween(x: number, minVal: number, maxVal: number): boolean {\n  return x >= minVal && x <= maxVal;\n}\n\nexport const sequenceNames = new Set([\n  'attack',\n  'birth',\n  'cinematic',\n  'death',\n  'decay',\n  'dissipate',\n  'morph',\n  'portrait',\n  'sleep',\n  'spell',\n  'stand',\n  'walk',\n  'ready', // HeroMountainKing.mdx has \"Alternate Ready\" which I assume is the same as or a replacement to \"Alternate Stand Ready\"?\n]);\n\nexport const replaceableIds = new Set([\n  1,\n  2,\n  11,\n  21,\n  31,\n  32,\n  33,\n  34,\n  35,\n  36,\n  37,\n]);\n\nexport const animatedTypeNames = new Map([\n  // Layer\n  ['KMTF', 'Texture ID'],\n  ['KMTA', 'Alpha'],\n  ['KMTE', 'Emissive Gain'],\n  ['KFC3', 'Fresnel Color'],\n  ['KFCA', 'Fresnel Opacity'],\n  ['KFTC', 'Fresnel Team Color'],\n  // TextureAnimation\n  ['KTAT', 'Translation'],\n  ['KTAR', 'Rotation'],\n  ['KTAS', 'Scaling'],\n  // GeosetAnimation\n  ['KGAO', 'Alpha'],\n  ['KGAC', 'Color'],\n  // GenericObject\n  ['KGTR', 'Translation'],\n  ['KGRT', 'Rotation'],\n  ['KGSC', 'Scaling'],\n  // Light\n  ['KLAS', 'Attenuation Start'],\n  ['KLAE', 'Attenuation End'],\n  ['KLAC', 'Color'],\n  ['KLAI', 'Intensity'],\n  ['KLBI', 'Ambient Intensity'],\n  ['KLBC', 'Ambient Color'],\n  ['KLAV', 'Visibility'],\n  // Attachment\n  ['KATV', 'Visibility'],\n  // ParticleEmitter\n  ['KPEE', 'Emission Rate'],\n  ['KPEG', 'Gravity'],\n  ['KPLN', 'Longitude'],\n  ['KPLT', 'Latitude'],\n  ['KPEL', 'Lifespan'],\n  ['KPES', 'Speed'],\n  ['KPEV', 'Visibility'],\n  // ParticleEmitter2\n  ['KP2E', 'Emission Rate'],\n  ['KP2G', 'Gravity'],\n  ['KP2L', 'Latitude'],\n  ['KP2R', 'Variation'],\n  ['KP2N', 'Length'],\n  ['KP2W', 'Width'],\n  ['KP2S', 'Speed'],\n  ['KP2V', 'Visibility'],\n  // ParticleEmitterCorn\n  ['KPPA', 'Alpha'],\n  ['KPPC', 'Color'],\n  ['KPPE', 'EmissionRate'],\n  ['KPPL', 'LifeSpan'],\n  ['KPPS', 'Speed'],\n  ['KPPV', 'Visibility'],\n  // RibbonEmitter\n  ['KRHA', 'Height Above'],\n  ['KRHB', 'Height Below'],\n  ['KRAL', 'Alpha'],\n  ['KRCO', 'Color'],\n  ['KRTX', 'Texture Slot'],\n  ['KRVS', 'Visibility'],\n  // Camera\n  ['KCTR', 'Translation'],\n  ['KTTR', 'Rotation'],\n  ['KCRL', 'Target Translation'],\n]);\n\nexport function hasAnimation(object: AnimatedObject, name: string): boolean {\n  for (const animation of object.animations) {\n    if (animation.name === name) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nexport type MdlxType = Extent | Sequence | number | Texture | Material | Layer | TextureAnimation | Geoset | GeosetAnimation | Bone | Light | Helper | Attachment | ParticleEmitter | ParticleEmitter2 | ParticleEmitterPopcorn | RibbonEmitter | EventObject | Camera | CollisionShape | FaceEffect | Animation;\n\nexport function getObjectTypeName(object: MdlxType): string {\n  if (object instanceof Extent) {\n    return 'Extent';\n  } else if (object instanceof Sequence) {\n    return 'Sequence';\n  } else if (typeof object === 'number') {\n    return 'GlobalSequence';\n  } else if (object instanceof Texture) {\n    return 'Texture';\n  } else if (object instanceof Material) {\n    return 'Material';\n  } else if (object instanceof Layer) {\n    return 'Layer';\n  } else if (object instanceof TextureAnimation) {\n    return 'TextureAnimation';\n  } else if (object instanceof Geoset) {\n    return 'Geoset';\n  } else if (object instanceof GeosetAnimation) {\n    return 'GeosetAnimation';\n  } else if (object instanceof Bone) {\n    return 'Bone';\n  } else if (object instanceof Light) {\n    return 'Light';\n  } else if (object instanceof Helper) {\n    return 'Helper';\n  } else if (object instanceof Attachment) {\n    return 'Attachment';\n  } else if (object instanceof ParticleEmitter) {\n    return 'ParticleEmitter';\n  } else if (object instanceof ParticleEmitter2) {\n    return 'ParticleEmitter2';\n  } else if (object instanceof ParticleEmitterPopcorn) {\n    return 'ParticleEmitterPopcorn';\n  } else if (object instanceof RibbonEmitter) {\n    return 'RibbonEmitter';\n  } else if (object instanceof EventObject) {\n    return 'EventObject';\n  } else if (object instanceof Camera) {\n    return 'Camera';\n  } else if (object instanceof CollisionShape) {\n    return 'CollisionShape';\n  } else if (object instanceof FaceEffect) {\n    return 'FaceEffect';\n  } else if (object instanceof Animation) {\n    return <string>animatedTypeNames.get(object.name);\n  } else {\n    console.warn('Unknown object type', object);\n    return 'Unknown';\n  }\n}\n\nexport function getObjectName(object: MdlxType, index: number): string {\n  let name = getObjectTypeName(object);\n\n  if (!(object instanceof Animation) && !(object instanceof Extent)) {\n    name += ` ${index}`;\n  }\n\n  if (object instanceof Sequence || object instanceof GenericObject || object instanceof Camera) {\n    name += ` - \"${object.name}\"`;\n  }\n\n  if (object instanceof Texture || object instanceof FaceEffect) {\n    if (object.path.length) {\n      name += ` - \"${basename(object.path)}\"`;\n    }\n\n    if (object instanceof Texture) {\n      if (object.replaceableId === 1) {\n        name += ' - Team color';\n      } else if (object.replaceableId === 2) {\n        name += ' - Team glow';\n      } else if (object.replaceableId > 0) {\n        name += ` - Replaceable ID ${object.replaceableId}`;\n      }\n    }\n  }\n\n  return name;\n}\n\nexport function testObjects<T extends MdlxType>(data: SanityTestData, objects: T[], handler?: (data: SanityTestData, object: T, index: number) => void): void {\n  const l = objects.length;\n\n  if (l) {\n    const isAnimated = objects[0] instanceof AnimatedObject;\n    const isGeneric = objects[0] instanceof GenericObject;\n\n    for (let i = 0; i < l; i++) {\n      const object = objects[i];\n\n      data.push(object, i);\n\n      if (handler) {\n        handler(data, object, i);\n      }\n\n      if (isAnimated) {\n        const asAnimated = <AnimatedObject>object;\n\n        testObjects(data, asAnimated.animations, testAnimation);\n      }\n\n      if (isGeneric) {\n        const asGeneric = <GenericObject>object;\n\n        const objectId = asGeneric.objectId;\n        const parentId = asGeneric.parentId;\n\n        data.assertError(parentId === -1 || hasGenericObject(data, parentId), `Invalid parent ${parentId}`);\n        data.assertError(objectId !== parentId, 'Same object and parent');\n      }\n\n      data.pop();\n    }\n  }\n}\n\nexport function testAndGetReference<T extends MdlxType>(data: SanityTestData, objects: T[], index: number, typeNameIfError: string): T | undefined {\n  if (index >= 0 && index < objects.length) {\n    data.addReference(objects[index]);\n\n    return objects[index];\n  } else {\n    data.addError(`Invalid ${typeNameIfError} ${index}`);\n\n    return;\n  }\n}\n\nexport function testReference<T extends MdlxType>(data: SanityTestData, objects: T[], index: number, typeNameIfError: string): boolean {\n  // This explicit test against undefined is needed because global sequences are numbers and could be equal to 0.\n  return testAndGetReference(data, objects, index, typeNameIfError) !== undefined;\n}\n\n/**\n * Get all of the texture indices referenced by a layer.\n */\nexport function getTextureIds(layer: Layer): number[] {\n  for (const animation of layer.animations) {\n    if (animation.name === 'KMTF') {\n      return unique(animation.values.map((value) => value[0]));\n    }\n  }\n\n  return [layer.textureId];\n}\n\nfunction testVertexSkinning(data: SanityTestData, vertex: number, bone: number, isHd: boolean): void {\n  const object = data.objects[bone];\n\n  if (isHd) {\n    data.assertError(isBetween(bone, 0, 255), `Vertex ${vertex}: References bone ${bone} but there can only be 256 bones in an HD model`);\n  }\n\n  if (object) {\n    if (!(object instanceof Bone)) {\n      data.addSevere(`Vertex ${vertex}: Attached to \"${object.name}\" which is not a bone`);\n    } else {\n      // Add a use for this bone, to check later if bones have vertices attached to them.\n      const uses = data.boneUsageMap.get(bone) || 0;\n     \n      data.boneUsageMap.set(bone, uses + 1);\n    }\n  } else {\n    data.addError(`Vertex ${vertex}: Attached to object ${bone} which does not exist`);\n  }\n}\n\n/**\n * Test geoset skinning.\n */\nexport function testGeosetSkinning(data: SanityTestData, geoset: Geoset): void {\n  if (data.model.version > 800 && geoset.skin.length) {\n    data.assertWarning(geoset.vertexGroups.length === 0, 'This geoset has both skin/weights and vertex groups');\n\n    const skin = geoset.skin;\n\n    for (let i = 0, l = skin.length / 8; i < l; i++) {\n      const offset = i * 8;\n      const bone0 = skin[offset];\n      const bone1 = skin[offset + 1];\n      const bone2 = skin[offset + 2];\n      const bone3 = skin[offset + 3];\n      const weight0 = skin[offset + 4];\n      const weight1 = skin[offset + 5];\n      const weight2 = skin[offset + 6];\n      const weight3 = skin[offset + 7];\n\n      if (weight0 > 0) {\n        testVertexSkinning(data, i, bone0, true);\n      }\n\n      if (weight1 > 0) {\n        testVertexSkinning(data, i, bone1, true);\n      }\n\n      if (weight2 > 0) {\n        testVertexSkinning(data, i, bone2, true);\n      }\n\n      if (weight3 > 0) {\n        testVertexSkinning(data, i, bone3, true);\n      }\n\n      const weight = weight0 + weight1 + weight2 + weight3;\n\n      if (weight === 0) {\n        data.addSevere(`Vertex ${i}: Not attached to anything`);\n      } else if (weight !== 255) {\n        data.addSevere(`Vertex ${i}: The weights are not normalized to 1`);\n      }\n    }\n  } else {\n    // A model having no bones at all is also valid.\n    // I don't know if the skinning information in that case can be anything whatsoever, or if there are rules.\n    if (data.model.bones.length) {\n      const vertexGroups = geoset.vertexGroups;\n      const matrixGroups = geoset.matrixGroups;\n      const matrixIndices = geoset.matrixIndices;\n      const slices = [];\n\n      for (let i = 0, l = matrixGroups.length, k = 0; i < l; i++) {\n        slices.push(matrixIndices.subarray(k, k + matrixGroups[i]));\n        k += matrixGroups[i];\n      }\n\n      for (let i = 0, l = vertexGroups.length; i < l; i++) {\n        const slice = slices[vertexGroups[i]];\n\n        if (slice) {\n          for (const bone of slice) {\n            testVertexSkinning(data, i, bone, false);\n          }\n        } else {\n          const vertexGroup = vertexGroups[i];\n\n          if (vertexGroup === 255) {\n            data.addSevere(`Vertex ${i}: Not attached to anything`);\n          } else {\n            data.addSevere(`Vertex ${i}: Attached to vertex group ${vertexGroup} which does not exist`);\n          }\n        }\n      }\n    }\n  }\n}\n\n/**\n * Is the given ID a valid generic object?\n */\nfunction hasGenericObject(data: SanityTestData, id: number): boolean {\n  for (const object of data.objects) {\n    if (object.objectId === id) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nexport function testAnimation(data: SanityTestData, animation: Animation): void {\n  const name = animation.name;\n  const interpolationType = animation.interpolationType;\n\n  // Particle emitter 2 variation animations are not implemented in Magos for the MDX format.\n  data.assertWarning(name !== 'KP2R', 'Using a variation animation.');\n\n  // Particle emitter 2 gravity animations are not implemented in Magos for the MDX format.\n  data.assertWarning(name !== 'KP2G', 'Using a gravity animation.');\n\n  // The game seems to force visiblity (and others?) interpolation types to none.\n  data.assertWarning(animatedTypeNames.get(name) !== 'Visibility' || interpolationType === InterpolationType.DontInterp, 'Interpolation type not set to None');\n\n  testTracks(data, animation);\n}\n\nexport function cleanNode(node: SanityTestNode): void {\n  const nodes = node.nodes;\n\n  for (let i = nodes.length - 1; i >= 0; i--) {\n    const child = nodes[i];\n\n    if (child.type === 'node') {\n      if (child.errors || child.severe || child.warnings || child.unused || (child.uses !== undefined && !child.uses)) {\n        cleanNode(child);\n      } else {\n        nodes.splice(i, 1);\n      }\n    }\n  }\n}\n\nexport function getAnimation(object: AnimatedObject, name: string): Animation | undefined {\n  for (const animation of object.animations) {\n    if (animation.name === name) {\n      return animation;\n    }\n  }\n\n  return;\n}\n\nexport function testExtent(data: SanityTestData, extent: Extent): void {\n  data.push(extent, 0);\n\n  const { max, min } = extent;\n\n  if ((max[0] - min[0] < 0) || (max[1] - min[1] < 0) || (max[2] - min[2] < 0)) {\n    data.addWarning('Negative extents');\n  }\n\n  data.pop();\n}\n\n/*\nlet attachmentNames = new Set([\n    'chest',\n    'feet',\n    'foot',\n    'hand',\n    'head',\n    'origin',\n    'overhead',\n    'sprite',\n    'weapon',\n]);\n\nlet attachmentQualifiers = new Set([\n    'alternate',\n    'left',\n    'mount',\n    'right',\n    'rear',\n    'smart',\n    'first',\n    'second',\n    'third',\n    'fourth',\n    'fifth',\n    'sixth',\n    'small',\n    'medium',\n    'large',\n    'gold',\n    'rallypoint',\n    'eattree',\n]);\n\nfunction testAttachmentName(attachment) {\n    let tokens = attachment.node.name.toLowerCase().trim().split(/\\s+/),\n        valid = true;\n\n    if (tokens.length > 1) {\n        let names = attachmentNames,\n            firstToken = tokens[0],\n            lastToken = tokens[tokens.length - 1];\n\n        if (!names.has(tokens[0]) || lastToken !== 'ref') {\n            valid = false;\n        }\n\n        if (tokens.length > 2) {\n            let qualifiers = attachmentQualifiers;\n\n            for (let i = 1, l = tokens.length - 1; i < l; i++) {\n                if (!qualifiers.has(tokens[i])) {\n                    valid = false;\n                }\n            }\n        }\n    } else {\n        valid = false;\n    }\n\n    return valid;\n}\n*/\n"
  },
  {
    "path": "src/utils/w3x/generatelistfile.ts",
    "content": "import { basename } from '../../common/path';\nimport { IniFile } from '../../parsers/ini/file';\nimport MdlxModel from '../../parsers/mdlx/model';\nimport War3MapImp from '../../parsers/w3x/imp/file';\nimport War3Map from '../../parsers/w3x/map';\nimport War3MapW3d from '../../parsers/w3x/w3d/file';\nimport War3MapW3i from '../../parsers/w3x/w3i/file';\nimport War3MapW3s from '../../parsers/w3x/w3s/file';\nimport War3MapW3u from '../../parsers/w3x/w3u/file';\nimport TokenStream from '../jass2/tokenstream';\n\nfunction isModel(file: string): boolean {\n  return file.endsWith('.mdx') || file.endsWith('.mdl');\n}\n\nfunction isTexture(file: string): boolean {\n  return file.endsWith('.blp') || file.endsWith('.dds') || file.endsWith('.tga');\n}\n\nfunction isOther(file: string): boolean {\n  return file.endsWith('.wav') || file.endsWith('.mp3') || file.endsWith('.slk') || file.endsWith('.txt');\n}\n\nfunction filterFile(files: string[], file: string): void {\n  if (file.length > 6 && (isModel(file) || isTexture(file) || isOther(file))) {\n    if (file.endsWith('.mdl')) {\n      file = `${file.slice(0, -4)}.mdx`;\n    }\n\n    files.push(file.replace(/\\\\\\\\/g, '\\\\'));\n  }\n}\n\n/**\n * Given a map, attempt to find all file names referenced in it.\n * \n * Can be used with MpqArchive.applyListfile() to actually attempt to resolve the files in the archive.\n * \n * Based on code generously shared by Ralle.\n */\nexport default function generateListfile(map: War3Map): Set<string> {\n  const files = [\n    '(listfile)',\n    '(signature)',\n    '(attributes)',\n    'war3map.w3e',\n    'war3map.w3i',\n    'war3map.wtg',\n    'war3map.wct',\n    'war3map.wts',\n    'war3map.j',\n    'scripts\\\\war3map.j',\n    'war3map.lua',\n    'scripts\\\\war3map.lua',\n    'war3map.shd',\n    'war3mapMap.blp',\n    'war3mapMap.b00',\n    'war3mapMap.tga',\n    'war3mapPreview.tga',\n    'war3map.mmp',\n    'war3mapPath.tga',\n    'war3map.wpm',\n    'war3map.doo',\n    'war3mapUnits.doo',\n    'war3map.w3r',\n    'war3map.w3c',\n    'war3map.w3s',\n    'war3map.w3u',\n    'war3map.w3t',\n    'war3map.w3a',\n    'war3map.w3b',\n    'war3map.w3d',\n    'war3map.w3q',\n    'war3mapMisc.txt',\n    'war3mapSkin.txt',\n    'war3mapExtra.txt',\n    'war3map.imp',\n  ];\n\n  // Listfile.\n  let file = map.get('(listfile)');\n\n  if (file) {\n    try {\n      const text = file.text();\n      const lines = text.split(/\\r\\n/g);\n\n      for (const line of lines) {\n        files.push(line.trim());\n      }\n    } catch (e) {\n      console.warn('(listfile)', e);\n    }\n  }\n\n  // Object files.\n  for (const objectFile of ['.w3u', '.w3t', '.w3b', '.w3d', '.w3a', '.w3h', '.w3q']) {\n    file = map.get('war3map' + objectFile);\n\n    if (file) {\n      try {\n        const bytes = file.bytes();\n        let parser;\n\n        if (objectFile === '.w3d' || objectFile === '.w3q' || objectFile === '.w3a') {\n          parser = new War3MapW3d();\n        } else {\n          parser = new War3MapW3u();\n        }\n\n        parser.load(bytes);\n\n        const tables = [\n          parser.originalTable,\n          parser.customTable,\n        ];\n\n        for (const table of tables) {\n          for (const object of table.objects) {\n            for (const modification of object.modifications) {\n              // String\n              if (modification.variableType === 3) {\n                filterFile(files, <string>modification.value);\n              }\n            }\n          }\n        }\n      } catch (e) {\n        console.warn(file.name, e);\n      }\n    }\n  }\n\n  // Sounds.\n  file = map.get('war3map.w3s');\n\n  if (file) {\n    try {\n      const bytes = file.bytes();\n      const parser = new War3MapW3s();\n\n      parser.load(bytes);\n\n      for (const sound of parser.sounds) {\n        files.push(sound.file);\n      }\n    } catch (e) {\n      console.warn('war3map.w3s', e);\n    }\n  }\n\n\n  // Scripts.\n  file = map.get('war3map.j') || map.get('Scripts\\\\war3map.j') || map.get('war3map.lua') || map.get('Scripts\\\\war3map.lua');\n\n  if (file) {\n    try {\n      const text = file.text();\n      const stream = new TokenStream(text);\n      let token;\n\n      while ((token = stream.read()) !== undefined) {\n        if (token[0] === '\"') {\n          filterFile(files, token.slice(1, -1));\n        }\n      }\n    } catch (e) {\n      console.warn(file.name, e);\n    }\n  }\n\n  // User interface replacements.\n  file = map.get('war3mapSkin.txt');\n\n  if (file) {\n    try {\n      const text = file.text();\n      const config = new IniFile();\n\n      config.load(text);\n\n      for (const section of config.sections.values()) {\n        for (const value of section.values()) {\n          // We know the values are going to be strings.\n          for (const token of value.split(',')) {\n            filterFile(files, token);\n          }\n        }\n      }\n    } catch (e) {\n      console.warn('war3mapSkin.txt', e);\n    }\n  }\n\n  // Imports\n  file = map.get('war3map.imp');\n\n  if (file) {\n    try {\n      const bytes = file.bytes();\n      const parser = new War3MapImp();\n\n      parser.load(bytes);\n\n      for (const file of parser.entries.keys()) {\n        files.push(file);\n      }\n    } catch (e) {\n      console.warn('war3map.imp', e);\n    }\n  }\n\n  // Map information.\n  file = map.get('war3map.w3i');\n\n  if (file) {\n    try {\n      const bytes = file.bytes();\n      const parser = new War3MapW3i();\n\n      parser.load(bytes);\n\n      filterFile(files, parser.loadingScreenModel);\n      filterFile(files, parser.prologueScreenModel);\n    } catch (e) {\n      console.warn('war3map.w3i', e);\n    }\n  }\n\n  // Model portraits\n  for (let i = 0, l = files.length; i < l; i++) {\n    const file = files[i];\n\n    if (isModel(file)) {\n      files.push(`${file.slice(0, -4)}_portrait.mdx`); // MDL portraits?\n    }\n  }\n\n  // Model textures.\n  for (let i = 0, l = files.length; i < l; i++) {\n    const file = files[i];\n\n    if (isModel(file)) {\n      const actualFile = map.get(file);\n\n      if (actualFile) {\n        try {\n          const bytes = actualFile.bytes();\n          const parser = new MdlxModel();\n\n          parser.load(bytes);\n\n          for (const texture of parser.textures) {\n            if (texture.path.length) {\n              files.push(texture.path);\n            }\n          }\n\n          for (const attachment of parser.attachments) {\n            filterFile(files, attachment.path);\n          }\n\n          for (const emitter of parser.particleEmitters) {\n            filterFile(files, emitter.path);\n          }\n        } catch (e) {\n          console.warn(file, e);\n        }\n      }\n    }\n  }\n\n  // Disabled icon versions.\n  for (let i = 0, l = files.length; i < l; i++) {\n    const file = files[i];\n\n    if (isTexture(file)) {\n      files.push(`ReplaceableTextures\\\\CommandButtonsDisabled\\\\DIS${basename(file)}`);\n    }\n  }\n\n\n  return new Set(files);\n}\n"
  },
  {
    "path": "src/utils/w3x/index.ts",
    "content": "import convertWeu from './weu/weu';\nimport generateListfile from './generatelistfile';\n\nexport default {\n  convertWeu,\n  generateListfile,\n};\n"
  },
  {
    "path": "src/utils/w3x/weu/conversions.ts",
    "content": "import Trigger from '../../../parsers/w3x/wtg/trigger';\nimport ECA from '../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../parsers/w3x/wtg/subparameters';\nimport WeuData from './data';\nimport { createCustomScriptECA, ensureNameSafety } from './utils';\n\n/**\n * A list of vanilla operators that take 3 parameters.\n * The only one not here, which takes 2 parameters, is OperatorString.\n */\nconst OPERATOR_NAMES = new Set([\n  'OperatorCompareBoolean',\n  'OperatorCompareAbilityId',\n  'OperatorCompareBuffId',\n  'OperatorCompareDestructible',\n  'OperatorCompareDestructableCode',\n  'OperatorCompareButton',\n  'OperatorCompareGameDifficulty',\n  'OperatorCompareGameSpeed',\n  'OperatorCompareHeroSkill',\n  'OperatorCompareInteger',\n  'OperatorCompareItem',\n  'OperatorCompareItemType',\n  'OperatorCompareItemCode',\n  'OperatorCompareMouseButton',\n  'OperatorCompareMeleeDifficulty',\n  'OperatorCompareOrderCode',\n  'OperatorComparePlayer',\n  'OperatorComparePlayerColor',\n  'OperatorComparePlayerControl',\n  'OperatorComparePlayerSlotStatus',\n  'OperatorCompareRace',\n  'OperatorCompareReal',\n  'OperatorCompareString',\n  'OperatorCompareTechCode',\n  'OperatorCompareTerrainType',\n  'OperatorCompareTrigger',\n  'OperatorCompareUnit',\n  'OperatorCompareUnitCode',\n  'OperatorInt',\n  'OperatorReal',\n]);\n\n/**\n * A list of vanilla functions which have an implicit code parameter.\n * The control flow \"functions\" such as IfThenElseMultiple and ForLoopAMultiple are handled specifically.\n */\nconst HAS_IMPLICIT_CODE = new Set([\n  'EnumDestructablesInRectAllMultiple',\n  'EnumDestructablesInCircleBJMultiple',\n  'EnumItemsInRectBJMultiple',\n  'ForForceMultiple',\n  'ForGroupMultiple',\n]);\n\n/**\n * Converts a Trigger to a custom script string.\n * Callbacks that are generated due to the conversion are added to the input callbacks array.\n */\nexport function convertTrigger(data: WeuData, trigger: Trigger, callbacks: string[]): string {\n  const name = ensureNameSafety(trigger.name);\n  const events = [];\n  const conditions = [];\n  const actions = [];\n\n  // Separate the events/conditions/actions.\n  for (const eca of trigger.ecas) {\n    if (eca.type === 0) {\n      events.push(eca);\n    } else if (eca.type === 1) {\n      conditions.push(eca);\n    } else {\n      actions.push(eca);\n    }\n  }\n\n  const functions = [];\n\n  if (events.length || conditions.length || actions.length) {\n    const initBody = [];\n    const conditionsBody = [];\n    const actionsBody = [];\n\n    // Reference the global trigger that WE generates.\n    const triggerName = `gg_trg_${name}`;\n\n    // Events don't explicitly define the trigger parameter.\n    // Therefore it is created here, and prepended below to the parameters of each event.\n    const triggerParameter = new Parameter();\n    triggerParameter.type = 3;\n    triggerParameter.value = triggerName;\n\n    initBody.push(`set ${triggerName} = CreateTrigger()`);\n\n    // Convert the events.\n    for (const event of events) {\n      event.parameters.unshift(triggerParameter);\n\n      for (const eca of convertFunctionCall(data, event, callbacks)) {\n        initBody.push(eca.parameters[0].value);\n      }\n    }\n\n    // Convert the conditions.\n    if (conditions.length) {\n      initBody.push(`call TriggerAddCondition(${triggerName}, Condition(function Trig_${name}_Conditions)`);\n\n      for (const condition of conditions) {\n        for (const eca of convertFunctionCall(data, condition, callbacks)) {\n          conditionsBody.push(`if ${eca.parameters[0].value} then\\r\\n return true\\r\\nendif`);\n        }\n      }\n    }\n\n    // Convert the actions.\n    if (actions.length) {\n      initBody.push(`call TriggerAddAction(${triggerName}, function Trig_${name}_Actions)`);\n\n      for (const action of actions) {\n        for (const eca of convertFunctionCall(data, action, callbacks)) {\n          actionsBody.push(eca.parameters[0].value);\n        }\n      }\n    }\n\n    // Add the actions function.\n    if (actionsBody.length) {\n      functions.push(`function Trig_${name}_Actions takes nothing returns nothing\\r\\n${actionsBody.join('\\r\\n')}\\r\\nendfunction`);\n    }\n\n    // Add the conditions function.\n    if (conditionsBody.length) {\n      functions.push(`function Trig_${name}_Conditions takes nothing returns boolean\\r\\n${conditionsBody.join('\\r\\n')}\\r\\nreturn false\\r\\nendfunction`);\n    }\n\n    // Add the initalization function.\n    functions.push(`function InitTrig_${name} takes nothing returns nothing\\r\\n${initBody.join('\\r\\n')}\\r\\nendfunction`);\n  }\n\n  // Finally, return the whole trigger as Jass.\n  return functions.join('\\r\\n');\n}\n\n/**\n * Converts an ECA or SubParameters to an array of custom script ECAs.\n * Callbacks that are generated due to the conversion are added to the input callbacks array.\n */\nexport function convertFunctionCall(data: WeuData, object: ECA | SubParameters, callbacks: string[]): ECA[] {\n  const name = object.name;\n  const ecas: string[] = [];\n  const parameters = object.parameters;\n  const signature = data.triggerData.getFunction(object.type, object.name);\n\n  if (!signature) {\n    throw new Error(`Could not find a function signature: ${name}. Stack: ${data.stackToString()}`);\n  }\n\n  let { args, scriptName } = signature;\n  const argCount = args.length;\n  let isCode = false;\n  let isBoolexpr = false;\n  let isScriptCode = false;\n  const ecaObject = <ECA>object; // Get correct typing for the cases where the object is known to be an ECA.\n\n  scriptName = scriptName || object.name;\n\n  if (argCount) {\n    const lastArg = args[argCount - 1];\n\n    if (lastArg === 'code' || HAS_IMPLICIT_CODE.has(name)) {\n      isCode = true;\n    } else if (lastArg === 'boolexpr') {\n      isBoolexpr = true;\n    } else if (lastArg === 'scriptcode') {\n      isScriptCode = true;\n    }\n  }\n\n  // IfThenElse and other control flow \"functions\" must come before the generic code/boolexpr callback handling, since they don't follow the same rules.\n  if (name === 'IfThenElse') {\n    ecas.push(`if ${convertParameter(data, parameters[0], args[0], callbacks)} then`);\n    ecas.push(`call ${convertParameter(data, parameters[1], args[1], callbacks)}`);\n    ecas.push('else');\n    ecas.push(`call ${convertParameter(data, parameters[2], args[2], callbacks)}`);\n    ecas.push('endif');\n  } else if (name === 'OrMultiple') {\n    ecas.push(ecaObject.ecas.slice().map((eca) => convertFunctionCall(data, eca, callbacks).map((eca) => eca.parameters[0].value)).join(' or '));\n  } else if (name === 'AndMultiple') {\n    ecas.push(ecaObject.ecas.slice().map((eca) => convertFunctionCall(data, eca, callbacks).map((eca) => eca.parameters[0].value)).join(' and '));\n  } else if (name === 'ForLoopAMultiple' || name === 'ForLoopBMultiple' || name === 'ForLoopVarMultiple') {\n    let loopName = 'A';\n\n    if (name === 'ForLoopBMultiple') {\n      loopName = 'B';\n    } else if (name === 'ForLoopVarMultiple') {\n      loopName = 'Var';\n    }\n\n    let index;\n\n    if (loopName === 'A' || loopName === 'B') {\n      index = `bj_forLoop${loopName}Index`;\n\n      const indexEnd = `${index}End`;\n\n      ecas.push(`set ${index} = ${convertParameter(data, parameters[0], args[0], callbacks)}`);\n      ecas.push(`set ${indexEnd} = ${convertParameter(data, parameters[1], args[1], callbacks)}`);\n      ecas.push('loop');\n      ecas.push(`exitwhen ${index} > ${indexEnd}`);\n    } else {\n      index = convertParameter(data, parameters[0], args[0], callbacks);\n\n      ecas.push(`set ${index} = ${convertParameter(data, parameters[1], args[1], callbacks)}`);\n      ecas.push('loop');\n      ecas.push(`exitwhen ${index} > ${convertParameter(data, parameters[2], args[2], callbacks)}`);\n    }\n\n    for (const action of ecaObject.ecas) {\n      const replacements = convertFunctionCall(data, action, callbacks);\n\n      for (const replacement of replacements) {\n        ecas.push(`${replacement.parameters[0].value}`);\n      }\n    }\n\n    ecas.push(`set ${index} = ${index} + 1`);\n    ecas.push('endloop');\n  } else if (name === 'IfThenElseMultiple') {\n    let condition;\n    const thenActions = [];\n    const elseActions = [];\n\n    for (const eca of ecaObject.ecas) {\n      if (eca.group === 0) {\n        condition = eca;\n      } else if (eca.group === 1) {\n        thenActions.push(eca);\n      } else if (eca.group === 2) {\n        elseActions.push(eca);\n      }\n    }\n\n    if (condition) {\n      ecas.push(`if ${convertFunctionCall(data, condition, callbacks)[0].parameters[0].value} then`);\n    }\n\n    for (const action of thenActions) {\n      const replacements = convertFunctionCall(data, action, callbacks);\n\n      for (const replacement of replacements) {\n        ecas.push(`${replacement.parameters[0].value}`);\n      }\n    }\n\n    if (elseActions.length) {\n      ecas.push('else');\n\n      for (const action of elseActions) {\n        const replacements = convertFunctionCall(data, action, callbacks);\n\n        for (const replacement of replacements) {\n          ecas.push(`${replacement.parameters[0].value}`);\n        }\n      }\n    }\n\n    ecas.push('endif');\n  } else if (isCode || isBoolexpr) {\n    const triggerName = data.getTriggerName();\n    const callbackName = `Trig_${ensureNameSafety(triggerName)}_Func${callbacks.length}`;\n    let call = `function ${callbackName}`;\n    let returnType = 'nothing';\n    let callOrReturn = 'call';\n    let lastParam = parameters.length - 1;\n    const isMultiple = object.name.endsWith('Multiple');\n\n    if (isBoolexpr) {\n      call = `Filter(${call})`;\n      returnType = 'boolean';\n      callOrReturn = 'return';\n    }\n\n    if (isMultiple) {\n      lastParam = parameters.length;\n    }\n\n    // The callback names are based on where they are in the callback array.\n    // This breaks when one of the convert functions below need to create more callbacks before actually adding this one to the callbacks array.\n    // To solve this, add a placeholder and save the index, and then use the index after converting everything.\n    const callbackIndex = callbacks.length;\n    callbacks[callbackIndex] = 'NOTHING';\n\n    const callParams = [...parameters.slice(0, lastParam).map((value, index) => convertParameter(data, value, args[index], callbacks)), call];\n\n    if (object instanceof ECA) {\n      ecas.push(`call ${scriptName}(${callParams.join(', ')})`);\n    } else {\n      ecas.push(`${scriptName}(${callParams.join(', ')})`);\n    }\n\n    let body;\n\n    if (isMultiple) {\n      body = ecaObject.ecas.map((eca) => convertFunctionCall(data, eca, callbacks).map((customScript) => customScript.parameters[0].value).join('\\r\\n')).join('\\r\\n');\n    } else {\n      body = `${callOrReturn} ${convertParameter(data, parameters[lastParam], args[lastParam], callbacks)}`;\n    }\n\n    // Now use the callback index and replace the placeholder.\n    callbacks[callbackIndex] = `function ${callbackName} takes nothing returns ${returnType}\\r\\n${body}\\r\\nendfunction`;\n  } else if (isScriptCode) {\n    ecas.push(convertParameter(data, ecaObject.parameters[0], 'scriptcode', callbacks));\n  } else if (name === 'SetVariable') {\n    ecas.push(`set ${convertParameter(data, parameters[0], args[0], callbacks)} = ${convertParameter(data, parameters[1], args[1], callbacks)}`);\n  } else if (name === 'OperatorString') { // String concat\n    ecas.push(`${convertParameter(data, parameters[0], args[0], callbacks)} + ${convertParameter(data, parameters[1], args[1], callbacks)}`);\n  } else if (OPERATOR_NAMES.has(name)) { // All other operators\n    ecas.push(`${convertParameter(data, parameters[0], args[0], callbacks)} ${convertParameter(data, parameters[1], args[1], callbacks)} ${convertParameter(data, parameters[2], args[2], callbacks)}`);\n  } else if (name === 'CommentString') { // Comment\n    ecas.push(`// ${parameters[0].value}`);\n  } else if (name === 'GetBooleanAnd') {\n    ecas.push(`(${convertParameter(data, parameters[0], args[0], callbacks)} and ${convertParameter(data, parameters[1], args[1], callbacks)})`);\n  } else if (name === 'GetBooleanOr') {\n    ecas.push(`(${convertParameter(data, parameters[0], args[0], callbacks)} or ${convertParameter(data, parameters[1], args[1], callbacks)})`);\n  } else if (object instanceof ECA) {\n    // If this is a trigger event, there is the implicit trigger parameter at the beginning.\n    if (object.type === 0) {\n      args = ['trigger', ...args];\n    }\n\n    ecas.push(`call ${scriptName}(${parameters.map((value, index) => convertParameter(data, value, args[index], callbacks)).join(', ')})`);\n  } else if (object instanceof SubParameters) {\n    ecas.push(`${scriptName}(${parameters.map((value, index) => convertParameter(data, value, args[index], callbacks)).join(', ')})`);\n  }\n\n  return ecas.map((eca) => createCustomScriptECA(eca));\n}\n\n/**\n * Converts a parameter to custom script.\n * Callbacks that are generated due to the conversion are added to the input callbacks array.\n */\nexport function convertParameter(data: WeuData, parameter: Parameter, dataType: string, callbacks: string[]): string {\n  const { type, value } = parameter;\n\n  if (type === 0) {\n    const preset = data.triggerData.getPreset(value);\n\n    if (preset === undefined) {\n      throw new Error(`Failed to find a preset: \"${value}\"`);\n    }\n\n    return preset;\n  } else if (type === 1) {\n    if (value.startsWith('gg_')) {\n      // Used to track global generated variables and their status.\n      data.updateGUIReference(value, false);\n\n      return value;\n    } else {\n      let global = `udg_${value}`;\n\n      if (parameter.isArray && parameter.arrayIndex) {\n        global += `[${convertParameter(data, parameter.arrayIndex, 'integer', callbacks)}]`;\n      }\n\n      return global;\n    }\n  } else if (parameter.type === 2) {\n    return convertFunctionCall(data, <SubParameters>parameter.subParameters, callbacks)[0].parameters[0].value;\n  } else if (parameter.type === 3) {\n    const baseType = data.triggerData.getBaseType(dataType);\n\n    // \"value\"\n    // scriptcode needs to be converted as-is, and doesn't need quotes.\n    if (baseType === 'string' && dataType !== 'scriptcode') {\n      // Inline string table entries.\n      if (value.startsWith('TRIGSTR') && data.stringTable) {\n        const string = data.stringTable.getString(value);\n\n        if (string !== undefined) {\n          return `\"${string.replace(/\\r\\n/g, '\\\\r\\n')}\"`;\n        } else {\n          data.change('missingstring', 'Entry not found in the string table', value);\n        }\n      }\n\n      return `\"${value.replace(/\\\\/g, '\\\\\\\\')}\"`;\n    }\n\n    // 'value'\n    if (baseType === 'integer' && isNaN(parseInt(value))) {\n      return `'${value}'`;\n    }\n\n    // value\n    return value;\n  } else {\n    return '';\n  }\n}\n\n/**\n * Convert a parameter to a custom script string, discarding any generated callbacks.\n */\nexport function convertParameterInline(data: WeuData, parameter: Parameter, dataType: string): string {\n  return convertParameter(data, parameter, dataType, []);\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/data.ts",
    "content": "import Trigger from '../../../parsers/w3x/wtg/trigger';\nimport ECA from '../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../parsers/w3x/wtg/subparameters';\nimport CustomTextTrigger from '../../../parsers/w3x/wct/customtexttrigger';\nimport { TriggerData } from '../../../parsers/w3x/wtg/triggerdata';\nimport War3MapWts from '../../../parsers/w3x/wts/file';\n\nexport interface WEUChange {\n  type: string;\n  reason: string;\n  data: string;\n  stack: string;\n}\n\nexport default class WeuData {\n  triggerData: TriggerData;\n  stringTable: War3MapWts;\n  preplacedObjects: Map<string, boolean> = new Map();\n  changes: WEUChange[] = [];\n  stack: (Trigger | ECA | Parameter | SubParameters)[] = [];\n\n  constructor(triggerData: TriggerData, stringTable: War3MapWts) {\n    this.triggerData = triggerData;\n    this.stringTable = stringTable;\n  }\n\n  push(object: Trigger | ECA | Parameter | SubParameters): void {\n    this.stack.unshift(object);\n  }\n\n  pop(): void {\n    this.stack.shift();\n  }\n\n  change(type: string, reason: string, data: string): void {\n    this.changes.push({ type, reason, data, stack: this.stackToString() });\n  }\n\n  stackToString(): string {\n    return this.stack.map((object) => {\n      if (object instanceof Parameter) {\n        return object.value;\n      } else {\n        return object.name;\n      }\n    }).reverse().join(' > ');\n  }\n\n  getTriggerName(): string {\n    for (const node of this.stack) {\n      if (node instanceof Trigger) {\n        return node.name;\n      }\n    }\n\n    return '';\n  }\n\n  /**\n   * Every time a reference to a preplaced object is encountered while testing the GUI, this will be called with isGUI being true.\n   * Every time a reference to a preplaced object is converted to custom script, this will be called with isGUI being false.\n   * This is used to track references that existed in GUI before the conversion, but that will be only in custom scripts afterwards.\n   * References that are lost due to the conversion are then added in a new trigger called PreplacedObjectReferences.\n   */\n  updateGUIReference(name: string, isGUI: boolean): void {\n    // For now track only units and destructibles.\n    // Not sure what else needs tracking.\n    if (name.startsWith('gg_unit') || name.startsWith('gg_dest')) {\n      const preplacedObjects = this.preplacedObjects;\n\n      // If the reference is already known to be used by GUI, no need to do anything.\n      if (!preplacedObjects.get(name)) {\n        preplacedObjects.set(name, isGUI);\n      }\n    }\n  }\n\n  saveGUIReferences(triggers: Trigger[], customTextTriggers: CustomTextTrigger[]): void {\n    const references = [];\n\n    // Get all of the references that are no longer references.\n    for (const [name, isGUI] of this.preplacedObjects) {\n      if (!isGUI) {\n        references.push(name);\n      }\n    }\n\n    // If there are indeed missing references, add them to a new trigger.\n    if (references.length) {\n      const trigger = new Trigger();\n      trigger.name = 'PreplacedObjectReferences';\n      trigger.isEnabled = 1;\n      trigger.isInitiallyOff = 1;\n\n      for (const reference of references) {\n        const eca = new ECA();\n        eca.type = 2;\n        eca.isEnabled = 1;\n\n        if (reference.startsWith('gg_unit')) {\n          eca.name = 'RemoveUnit';\n        } else if (reference.startsWith('gg_dest')) {\n          eca.name = 'RemoveDestructable';\n        }\n\n        const parameter = new Parameter();\n        parameter.type = 1;\n        parameter.value = reference;\n\n        eca.parameters[0] = parameter;\n\n        trigger.ecas.push(eca);\n      }\n\n      triggers.push(trigger);\n      customTextTriggers.push(new CustomTextTrigger());\n\n      this.change('references', 'Saved references to preplaced objects lost due to conversions', references.join('\\n'));\n    }\n  }\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/parsewtg.ts",
    "content": "import War3Map from '../../../parsers/w3x/map';\nimport War3MapWtg from '../../../parsers/w3x/wtg/file';\nimport ECA from '../../../parsers/w3x/wtg/eca';\nimport SubParameters from '../../../parsers/w3x/wtg/subparameters';\nimport { FunctionSignature, TriggerData } from '../../../parsers/w3x/wtg/triggerdata';\nimport WeuData from './data';\n\nfunction typeFunctionCall(wtg: War3MapWtg, object: ECA | SubParameters, signatures: Map<string, FunctionSignature>, customTriggerData: TriggerData): void {\n  // If this object's signature was unknown, attempt to fill in the argument types.\n  // Note that this is done every time the signature is encountered.\n  // If a parameter's type isn't known in one call, maybe it will be known in another call.\n  if (signatures.has(object.name)) {\n    const signature = <FunctionSignature>signatures.get(object.name);\n    const args = signature.args;\n\n    for (const [index, parameter] of object.parameters.entries()) {\n      const { type, value } = parameter;\n\n      if (type === 1) {\n        for (const variable of wtg.variables) {\n          if (variable.name === value) {\n            args[index] = variable.type;\n            break;\n          }\n        }\n      } else if (type === 2) {\n        if (parameter.subParameters) {\n          const subParameters = parameter.subParameters;\n          const childSignature = customTriggerData.getFunction(subParameters.type, subParameters.name);\n\n          if (childSignature) {\n            const returnType = childSignature.returnType;\n\n            if (returnType && returnType !== 'AnyType') {\n              args[index] = returnType;\n            }\n          }\n        }\n      } else if (type === 3) {\n        if (value.startsWith('TRIGSTER_') || value.includes('\\\\')) {\n          args[index] = 'string';\n        } else if (value === 'true' || value === 'false') {\n          args[index] = 'boolean';\n        }  else if (!isNaN(parseFloat(value))) {\n          const valueAsFloat = parseFloat(value);\n\n          if (!isNaN(valueAsFloat)) {\n            if (Number.isInteger(valueAsFloat) && !value.includes('.')) {\n              args[index] = 'integer';\n            } else {\n              args[index] = 'real';\n            }\n          }\n        }\n      }\n    }\n  }\n\n  // Continue the hierarchy down any function call parameter.\n  for (const parameter of object.parameters) {\n    if (parameter.type === 2 && parameter.subParameters) {\n      typeFunctionCall(wtg, parameter.subParameters, signatures, customTriggerData);\n    }\n  }\n\n  // Continue the hierarchy down any ECA.\n  if (object instanceof ECA) {\n    for (const child of object.ecas) {\n      typeFunctionCall(wtg, child, signatures, customTriggerData);\n    }\n  }\n}\n\nconst BIGGEST_SIGNATURE = 20;\n\n/**\n * Parses a WTG file, but with a twist - it also tries to fill in unknown function signatures.\n * \n * This lets the WEU converter to handle maps with small TriggerData modifications that are unknown.\n * \n * Unfortunately it only handles simple cases - if there is an unknown signature in an unknown signature, there is no way to parse it as far as I can tell.\n * \n * With that being said, it already managed to parse and mostly fill the signatures of relevant test maps.\n */\nexport default function parseWtg(map: War3Map, customTriggerData: TriggerData, data: WeuData): War3MapWtg | undefined {\n  let wtg;\n  const signatures: Map<string, FunctionSignature> = new Map();\n  let currentName: string | undefined;\n  let currentSignature: FunctionSignature | undefined;\n  let searching = true;\n\n  // If there's an unknown signature exception while parsing the triggers, a new signature will be injected.\n  // Initially the signature starts with 0 arguments.\n  // The triggers are then read again.\n  // If there's an exception, another argument is added to the signature, and this goes on up to BIGGEST_SIGNATURE arguments. \n  // If there's another unknown signature exception, the current signature is considered complete.\n  // If the triggers are fully parsed, the current signature is considered complete.\n  // Note that this will not work if there is an unknown signature with a child unknown signature.\n  // For example, a function call given as an argument to a function call.\n  // This is also the case if it's not a direct child, but anywhere down the hierarchy.\n  // If both have unknown signatures, there is no deterministic way (that I can tell) to parse the data.\n  while (searching) {\n    try {\n      wtg = map.readTriggers(customTriggerData);\n\n      searching = false;\n    } catch (e) {\n      if (e instanceof Error) {\n        const message = e.message;\n\n        if (message.endsWith('Unknown signature')) {\n          const end = message.lastIndexOf('\"');\n          const start = message.lastIndexOf('\"', end - 1) + 1;\n          const nameAndType = message.slice(start, end);\n          const [name, type] = nameAndType.split(':');\n          const typeAsNumber = parseInt(type);\n          const signature: FunctionSignature = { args: [], scriptName: null, returnType: typeAsNumber === 3 ? 'AnyType' : null };\n\n          currentName = name.toLowerCase();\n          currentSignature = signature;\n\n          signatures.set(name, signature);\n\n          customTriggerData.externalFunctions[typeAsNumber][currentName] = currentSignature;\n        } else if (currentName && currentSignature) {\n          currentSignature.args.push('AnyType');\n\n          if (currentSignature.args.length > BIGGEST_SIGNATURE) {\n            searching = false;\n          }\n        }\n      }\n    }\n  }\n\n  if (signatures.size) {\n    if (wtg) {\n      for (const trigger of wtg.triggers) {\n        for (const eca of trigger.ecas) {\n          typeFunctionCall(wtg, eca, signatures, customTriggerData);\n        }\n      }\n    }\n\n    for (const [name, signature] of signatures) {\n      data.change('unknownsignature', `Unknown signature`, `${name}(${signature.args.join(', ')}) => ${signature.returnType ? signature.returnType : 'void'}`);\n    }\n  }\n\n  return wtg;\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/processing.ts",
    "content": "import Trigger from '../../../parsers/w3x/wtg/trigger';\nimport ECA from '../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../parsers/w3x/wtg/subparameters';\nimport WeuData from './data';\nimport { createCustomScriptECA, convertSingleToMultiple, isConditionECA, ensureCustomScriptCodeSafety } from './utils';\nimport { convertFunctionCall } from './conversions';\nimport transformFunction from './transformations/functions';\nimport transformPreset from './transformations/presets';\n\ninterface ConvertionResult {\n  convert: boolean;\n  reason: string;\n}\n\nexport function processTrigger(data: WeuData, trigger: Trigger, callbacks: string[]): ConvertionResult {\n  data.push(trigger);\n\n  const eventsAndConditions = [];\n  const actions = [];\n\n  for (const eca of trigger.ecas) {\n    const type = eca.type;\n\n    if (type === 0 || type === 1) {\n      eventsAndConditions.push(eca);\n    } else if (type === 2) {\n      actions.push(eca);\n    }\n  }\n\n  const outputEcas = [];\n\n  for (const eventOrCondition of eventsAndConditions) {\n    const result = processECA(data, eventOrCondition, callbacks);\n\n    if (result.convert) {\n      data.pop();\n      return result;\n    }\n\n    outputEcas.push(eventOrCondition);\n  }\n\n  for (const action of actions) {\n    const result = processECA(data, action, callbacks);\n\n    if (result.convert) {\n      const customScripts = convertFunctionCall(data, action, callbacks);\n\n      data.change('inlinecustomscript', result.reason, customScripts.map((eca) => eca.parameters[0].value).join('\\n'));\n      outputEcas.push(...customScripts);\n    } else {\n      outputEcas.push(action);\n    }\n  }\n\n  trigger.ecas = ensureCustomScriptCodeSafety(outputEcas);\n\n  data.pop();\n  return { convert: false, reason: '' };\n}\n\nexport function processECA(data: WeuData, eca: ECA, callbacks: string[]): ConvertionResult {\n  data.push(eca);\n\n  // Test if this function call, or anything down its hierarchy, needs to be converted to custom script.\n  const result = processFunctionCall(data, eca, callbacks);\n\n  if (result.convert) {\n    const reason = result.reason;\n\n    // If conversion is needed, try first to see if this is a RoC control flow ECA, and convert it to its TFT equivalent.\n    // This includes things like IfThenElse (RoC) and IfThenElseMultiple (TFT).\n    // This allows to potentially only convert to custom script one part of the control flow block, rather than all of it.\n    if (convertSingleToMultiple(eca)) {\n      // If the test passes here (that is, false is returned), the TFT conversion allowed to handle the conversion down the hierarchy.\n      // In this case, this ECA no longer needs to be converted to custom script.\n      const result = processFunctionCall(data, eca, callbacks);\n\n      if (result.convert) {\n        data.pop();\n        return result;\n      } else {\n        data.change('singletomultiple', reason, eca.name);\n      }\n    } else {\n      data.pop();\n      return result;\n    }\n  }\n\n  const outputEcas = [];\n\n  // Test the child ECAs if there are any.\n  for (const child of eca.ecas) {\n    const result = processECA(data, child, callbacks);\n\n    if (result.convert) {\n      let customScripts;\n\n      // If this is a condition ECA, make a custom script condition.\n      if (isConditionECA(eca.name, child.group)) {\n        let condition = convertFunctionCall(data, child, callbacks)[0].parameters[0].value;\n\n        // Normally type 2 (function) ECAs have the call keyword prepended to them.\n        // If one was added, remove it now, since this is a condition.\n        if (condition.startsWith('call ')) {\n          condition = condition.slice(5);\n        }\n\n        let finalCondition;\n        let returnValue;\n\n        // IfThenElseMultiple and AndMultiple return false if any condition is false.\n        // OrMultiple needs to return true if any condition is true.\n        if (eca.name === 'OrMultiple') {\n          finalCondition = condition;\n          returnValue = 'true';\n        } else {\n          finalCondition = `not (${condition})`;\n          returnValue = 'false';\n        }\n\n        customScripts = [\n          createCustomScriptECA(`if ${finalCondition} then`),\n          createCustomScriptECA(`return ${returnValue}`),\n          createCustomScriptECA('endif'),\n        ];\n      } else {\n        customScripts = convertFunctionCall(data, child, callbacks);\n      }\n\n      // All of the custom scripts should be in the same group as the original child.\n      for (const script of customScripts) {\n        script.group = child.group;\n      }\n\n      data.change('inlinecustomscript', result.reason, customScripts.map((eca) => eca.parameters[0].value).join('\\n'));\n      outputEcas.push(...customScripts);\n    } else {\n      outputEcas.push(child);\n    }\n  }\n\n  eca.ecas = ensureCustomScriptCodeSafety(outputEcas);\n\n  data.pop();\n  return { convert: false, reason: '' };\n}\n\nfunction processFunctionCall(data: WeuData, object: ECA | SubParameters, callbacks: string[]): ConvertionResult {\n  const name = object.name;\n\n  // Check if this object can be converted back to normal GUI.\n  // If it's already normal GUI, nothing will happen.\n  if (transformFunction(data, object)) {\n    data.change('inlinegui', name, object.name);\n  }\n\n  // If this function is not from normal GUI, it has to be converted.\n  if (!data.triggerData.isBaseFunction(object.type, object.name)) {\n    return { convert: true, reason: object.name };\n  }\n\n  // Check the parameters.\n  // Note that they will also be checked if GUI was inlined.\n  // This is needed, because the inline functions don't check the parameters, only move them around.\n  for (const parameter of object.parameters) {\n    // Check for custom presets.\n    if (parameter.type === 0 && data.triggerData.isCustomPreset(parameter.value)) {\n      const value = parameter.value;\n\n      if (transformPreset(data, parameter)) {\n        data.change('inlinepreset', value, parameter.value);\n      } else {\n        return { convert: true, reason: value };\n      }\n    }\n\n    const result = processParameter(data, parameter, callbacks);\n\n    if (result.convert) {\n      return result;\n    }\n  }\n\n  return { convert: false, reason: '' };\n}\n\nfunction processParameter(data: WeuData, parameter: Parameter, callbacks: string[]): { convert: boolean, reason: string } {\n  data.push(parameter);\n\n  const type = parameter.type;\n  const value = parameter.value;\n\n  if (type === 1) {\n    if (value.startsWith('gg_')) {\n      // Used to track global generated variables and their status.\n      data.updateGUIReference(value, true);\n    }\n  } else if (type === 2) {\n    const result = processSubParameters(data, <SubParameters>parameter.subParameters, callbacks);\n\n    if (result.convert) {\n      data.pop();\n      return result;\n    }\n  }\n\n  // If this is an array element, test the array index.\n  const index = parameter.arrayIndex;\n\n  if (index) {\n    const result = processParameter(data, index, callbacks);\n\n    if (result.convert) {\n      data.pop();\n      return result;\n    }\n  }\n\n  data.pop();\n  return { convert: false, reason: '' };\n}\n\nfunction processSubParameters(data: WeuData, subParameters: SubParameters, callbacks: string[]): ConvertionResult {\n  data.push(subParameters);\n\n  const result = processFunctionCall(data, subParameters, callbacks);\n\n  if (result.convert) {\n    data.pop();\n    return result;\n  }\n\n  data.pop();\n  return { convert: false, reason: '' };\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/transformations/blz.ts",
    "content": "import ECA from '../../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../../parsers/w3x/wtg/subparameters';\nimport WeuData from '../data';\n\n/**\n * The Warcraft 3 1.29 PTR introduced many new functions.\n * A lot were later prepended with Blz to avoid name clashes with user functions.\n * This returns whether the given name matches one of these functions.\n */\nfunction isBlzNeeded(name: string): boolean {\n  return name === 'GetTriggerPlayerMouseX' || name === 'GetTriggerPlayerMouseY' || name === 'GetTriggerPlayerMousePosition' || name === 'GetTriggerPlayerMouseButton' ||\n    name === 'SetAbilityTooltip' || name === 'SetAbilityExtendedTooltip' || name === 'SetAbilityResearchTooltip' || name === 'SetAbilityResearchExtendedTooltip' ||\n    name === 'GetAbilityTooltip' || name === 'GetAbilityExtendedTooltip' || name === 'GetAbilityResearchTooltip' || name === 'GetAbilityResearchExtendedTooltip' ||\n    name === 'SetAbilityIcon' || name === 'GetAbilityIcon' || name === 'GetAbilityPosX' || name === 'GetAbilityPosY' || name === 'SetAbilityPosX' || name === 'SetAbilityPosY' ||\n    name === 'GetUnitMaxHP' || name === 'SetUnitMaxHP' || name === 'GetUnitMaxMana' || name === 'SetUnitMaxMana' || name === 'SetItemName' || name === 'SetItemDescription' ||\n    name === 'GetItemDescription' || name === 'SetItemTooltip' || name === 'GetItemTooltip' || name === 'SetItemExtendedTooltip' || name === 'GetItemExtendedTooltip' ||\n    name === 'SetItemIconPath' || name === 'GetItemIconPath' || name === 'SetUnitName' || name === 'SetHeroProperName' || name === 'GetUnitBaseDamage' ||\n    name === 'SetUnitBaseDamage' || name === 'GetUnitDiceNumber' || name === 'SetUnitDiceNumber' || name === 'GetUnitDiceSides' || name === 'SetUnitDiceSides' ||\n    name === 'GetUnitAttackCooldown' || name === 'SetUnitAttackCooldown' || name === 'SetSpcialEffectColorByPlayer' || name === 'SetSpecialEffectColor' ||\n    name === 'SetSpecialEffectAlpha' || name === 'SetSpecialEffectScale' || name === 'SetSpecialEffectPosition' || name === 'SetSpecialEffectHeight' ||\n    name === 'SetSpecialEffectTimeScale' || name === 'SetSpecialEffectTime' || name === 'SetSpecialEffectOrientation' || name === 'SetSpecialEffectYaw' ||\n    name === 'SetSpecialEffectPitch' || name === 'SetSpecialEffectRoll' || name === 'SetSpecialEffectX' || name === 'SetSpecialEffectY' || name === 'SetSpecialEffectZ' ||\n    name === 'SetSpecialEffectPositionLoc' || name === 'GetLocalSpecialEffectX' || name === 'GetLocalSpecialEffectY' || name === 'GetLocalSpecialEffectZ' ||\n    name === 'GetUnitArmor' || name === 'SetUnitArmor' || name === 'UnitHideAbility' || name === 'UnitDisableAbility' || name === 'UnitCancelTimedLife' ||\n    name === 'IsUnitSelectable' || name === 'IsUnitInvulnerable' || name === 'UnitInterruptAttack' || name === 'GetUnitCollisionSize' || name === 'GetAbilityManaCost' ||\n    name === 'GetAbilityCooldown' || name === 'SetUnitAbilityCooldown' || name === 'GetUnitAbilityCooldown' || name === 'GetUnitAbilityCooldownRemaining' ||\n    name === 'EndUnitAbilityCooldown' || name === 'GetUnitAbilityManaCost' || name === 'SetEventDamage' ||\n    // Note, the following two functions are available in the 1.29 PTR, but not in the public version!\n    // They require version 1.30, which at the time of writing is in PTR.\n    name === 'PlaySpecialEffect' || name === 'PlaySpecialEffectWithTimeScale';\n}\n\nexport default function transformBlz(data: WeuData, object: ECA | SubParameters): boolean {\n  const name = object.name;\n\n  if (!isBlzNeeded(name)) {\n    return false;\n  }\n\n  object.name = `Blz${name}`;\n\n  // If this is a subparameters object, need to change the name also for the parent parameter.\n  if (object instanceof SubParameters) {\n    (<Parameter>data.stack[1]).value = `Blz${name}`;\n  }\n\n  const parameters = object.parameters;\n\n  // In the PTR these functions had 3 parameters, but later it became 2.\n  if ((name === 'GetAbilityIcon' || name === 'SetAbilityIcon') && parameters.length === 3) {\n    parameters.pop();\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/transformations/functions.ts",
    "content": "import ECA from '../../../../parsers/w3x/wtg/eca';\nimport SubParameters from '../../../../parsers/w3x/wtg/subparameters';\nimport WeuData from '../data';\nimport transformer, { Transformer } from './transformer';\nimport { transformerIsUnitOwnedByPlayer, transformerIsUnitRace, transformerIsUnitType } from './specific';\nimport transformBlz from './blz';\n\nlet initialized = false;\nlet transformers: {[keyof: string]: (data: WeuData, object: ECA | SubParameters) => boolean };\n\nfunction rename(name: string): Transformer {\n  return transformer({\n    [name]: {}\n  });\n}\n\nfunction swap(parameters: number[]): (name: string) => Transformer {\n  return function (name: string): Transformer {\n    return transformer({\n      [name]: {\n        parameters\n      }\n    });\n  };\n}\n\nfunction initialize(): void {\n  if (!initialized) {\n    initialized = true;\n\n    const swap10 = swap([1, 0]);\n    const swap102 = swap([1, 0, 2]);\n    const swap120 = swap([1, 2, 0]);\n    const swap201 = swap([2, 0, 1]);\n    const swap210 = swap([2, 1, 0]);\n    const swap0231 = swap([0, 2, 3, 1]);\n    const swap1023 = swap([1, 0, 2, 3]);\n    const swap3012 = swap([3, 0, 1, 2]);\n    const swap3201 = swap([3, 2, 0, 1]);\n    const swap3210 = swap([3, 2, 1, 0]);\n\n    transformers = {\n      UnitId: rename('String2UnitIdBJ'),\n      UnitId2String: rename('UnitId2StringBJ'),\n      GetObjectName: rename('GetAbilityName'),\n      // Math API\n      Sin: transformer({\n        SinBJ: {\n          parameters: [[0, '/', Math.PI / 180]]\n        }\n      }),\n      Cos: transformer({\n        CosBJ: {\n          parameters: [[0, '/', Math.PI / 180]]\n        }\n      }),\n      Tan: transformer({\n        TanBJ: {\n          parameters: [[0, '/', Math.PI / 180]]\n        }\n      }),\n      // String Utility API\n      GetHandleId: rename('GetHandleIdBJ'),\n      SubString: transformer({\n        SubStringBJ: {\n          parameters: [0, [1, '+', 1], 2]\n        }\n      }),\n      StringHash: rename('StringHashBJ'),\n      GetLocalizedString: rename('StringIdentity'),\n      // Map Setup API\n      SetMapFlag: transformer({\n        LockGameSpeedBJ: {\n          tests: [[0, 'MAP_LOCK_SPEED'], [1, 'true']],\n          parameters: []\n        },\n        UnlockGameSpeedBJ: {\n          tests: [[0, 'MAP_LOCK_SPEED'], [1, 'false']],\n          parameters: []\n        }\n      }),\n      SetPlayerColor: transformer({\n        SetPlayerColorBJ: {\n          parameters: [0, 1, 'PlayerChangeColorRetain']\n        }\n      }),\n      SetPlayerAlliance: swap0231('SetPlayerAllianceBJ'),\n      SetPlayerTaxRate: swap3201('SetPlayerTaxRateBJ'),\n      SetPlayerOnScoreScreen: swap10('SetPlayerOnScoreScreenBJ'),\n      GetPlayerTaxRate: swap201('GetPlayerTaxRateBJ'),\n      // Timer API\n      TimerStart: transformer({\n        StartTimerBJ: {\n          test: [3, 'null'],\n          parameters: [0, 2, 1]\n        }\n      }),\n      PauseTimer: transformer({\n        PauseTimerBJ: {\n          parameters: ['PauseResumePause', 0]\n        }\n      }),\n      ResumeTimer: transformer({\n        PauseTimerBJ: {\n          parameters: ['PauseResumeResume', 0]\n        }\n      }),\n      // Group API\n      GroupAddUnit: swap10('GroupAddUnitSimple'),\n      GroupRemoveUnit: swap10('GroupRemoveUnitSimple'),\n      GroupImmediateOrderById: rename('GroupTrainOrderByIdBJ'),\n      // Force API\n      ForceAddPlayer: swap10('ForceAddPlayerSimple'),\n      ForceRemovePlayer: swap10('ForceRemovePlayerSimple'),\n      // Region and Location API\n      GetWorldBounds: rename('GetEntireMapRect'),\n      // Trigger Game Event API\n      TriggerRegisterTimerEvent: transformer({\n        TriggerRegisterTimerEventPeriodic: {\n          test: [2, 'true'],\n          parameters: [0, 1]\n        },\n        TriggerRegisterTimerEventSingle: {\n          test: [2, 'false'],\n          parameters: [0, 1]\n        }\n      }),\n      TriggerRegisterTimerExpireEvent: rename('TriggerRegisterTimerExpireEventBJ'),\n      TriggerRegisterGameStateEvent: transformer({\n        TriggerRegisterGameStateEventTimeOfDay: {\n          test: [1, 'GAME_STATE_TIME_OF_DAY'],\n          parameters: [0, 2, 3]\n        }\n      }),\n      TriggerRegisterDialogEvent: rename('TriggerRegisterDialogEventBJ'),\n      TriggerRegisterGameEvent: transformer({\n        TriggerRegisterShowSkillEventBJ: {\n          test: [1, 'EVENT_GAME_SHOW_SKILL'],\n          parameters: [0]\n        },\n        TriggerRegisterBuildSubmenuEventBJ: {\n          test: [1, 'EVENT_GAME_BUILD_SUBMENU'],\n          parameters: [0]\n        },\n        TriggerRegisterGameLoadedEventBJ: {\n          test: [1, 'EVENT_GAME_LOADED'],\n          parameters: [0]\n        },\n        TriggerRegisterGameSavedEventBJ: {\n          test: [1, 'EVENT_GAME_SAVE'],\n          parameters: [0]\n        }\n      }),\n      GetClickedButton: rename('GetClickedButtonBJ'),\n      GetClickedDialog: rename('GetClickedDialogBJ'),\n      // Trigger Player Based Event API\n      TriggerRegisterPlayerEvent: transformer({\n        TriggerRegisterPlayerKeyEventBJ: [\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_LEFT_DOWN'],\n            parameters: [0, 1, 'KeyEventTypeDepress', 'KeyEventKeyLeft']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_RIGHT_DOWN'],\n            parameters: [0, 1, 'KeyEventTypeDepress', 'KeyEventKeyRight']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_DOWN_DOWN'],\n            parameters: [0, 1, 'KeyEventTypeDepress', 'KeyEventKeyDown']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_UP_DOWN'],\n            parameters: [0, 1, 'KeyEventTypeDepress', 'KeyEventKeyUp']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_LEFT_UP'],\n            parameters: [0, 1, 'KeyEventTypeRelease', 'KeyEventKeyLeft']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_RIGHT_UP'],\n            parameters: [0, 1, 'KeyEventTypeRelease', 'KeyEventKeyRight']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_DOWN_UP'],\n            parameters: [0, 1, 'KeyEventTypeRelease', 'KeyEventKeyDown']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_ARROW_UP_UP'],\n            parameters: [0, 1, 'KeyEventTypeRelease', 'KeyEventKeyUp']\n          }\n        ],\n        TriggerRegisterPlayerMouseEventBJ: [\n          {\n            test: [2, 'EVENT_PLAYER_MOUSE_DOWN'],\n            parameters: [0, 1, 'MouseEventTypeDown']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_MOUSE_UP'],\n            parameters: [0, 1, 'MouseEventTypeUp']\n          },\n          {\n            test: [2, 'EVENT_PLAYER_MOUSE_MOVE'],\n            parameters: [0, 1, 'MouseEventTypeMove']\n          },\n        ],\n        TriggerRegisterPlayerEventVictory: {\n          test: [2, 'EVENT_PLAYER_VICTORY'],\n          parameters: [0, 1]\n        },\n        TriggerRegisterPlayerEventDefeat: {\n          test: [2, 'EVENT_PLAYER_DEFEAT'],\n          parameters: [0, 1]\n        },\n        TriggerRegisterPlayerEventLeave: {\n          test: [2, 'EVENT_PLAYER_LEAVE'],\n          parameters: [0, 1]\n        },\n        TriggerRegisterPlayerEventAllianceChanged: {\n          test: [2, 'EVENT_PLAYER_ALLIANCE_CHANGED'],\n          parameters: [0, 1]\n        },\n        TriggerRegisterPlayerEventEndCinematic: {\n          test: [2, 'EVENT_PLAYER_END_CINEMATIC'],\n          parameters: [0, 1]\n        }\n      }),\n      TriggerRegisterPlayerUnitEvent: transformer({\n        TriggerRegisterPlayerUnitEventSimple: {\n          test: [3, 'null'],\n          parameters: [0, 1, 2]\n        }\n      }),\n      GetLearnedSkill: rename('GetLearnedSkillBJ'),\n      GetKillingUnit: rename('GetKillingUnitBJ'),\n      GetTransportUnit: rename('GetTransportUnitBJ'),\n      GetLoadedUnit: rename('GetLoadedUnitBJ'),\n      GetIssuedOrderId: rename('GetIssuedOrderIdBJ'),\n      // Trigger Unit Based Event API\n      TriggerRegisterUnitStateEvent: transformer({\n        TriggerRegisterUnitLifeEvent: {\n          test: [1, 'UNIT_STATE_LIFE'],\n          parameters: [0, 2, 3]\n        },\n        TriggerRegisterUnitManaEvent: {\n          test: [1, 'UNIT_STATE_MANA'],\n          parameters: [0, 2, 3]\n        }\n      }),\n      TriggerWaitForSound: rename('WaitForSoundBJ'),\n      // Widget API\n      GetWidgetLife: rename('GetItemLifeBJ'),\n      SetWidgetLife: rename('SetItemLifeBJ'),\n      // Destructable Object API\n      SetDestructableInvulnerable: rename('SetDestructableInvulnerableBJ'),\n      IsDestructableInvulnerable: rename('IsDestructableInvulnerableBJ'),\n      EnumDestructablesInRect: transformer({\n        EnumDestructablesInRectAll: {\n          test: [1, 'null'],\n          parameters: [0, 2]\n        }\n      }),\n      SetDestructableMaxLife: rename('SetDestructableMaxLifeBJ'),\n      QueueDestructableAnimation: rename('QueueDestructableAnimationBJ'),\n      SetDestructableAnimation: rename('SetDestructableAnimationBJ'),\n      SetDestructableAnimationSpeed: transformer({\n        SetDestAnimationSpeedPercent: {\n          parameters: [0, [1, '*', 100]]\n        }\n      }),\n      ShowDestructable: swap10('ShowDestructableBJ'),\n      GetTriggerDestructable: rename('GetDyingDestructable'),\n      // Item API\n      SetItemDropOnDeath: rename('SetItemDropOnDeathBJ'),\n      SetItemDroppable: rename('SetItemDroppableBJ'),\n      SetItemPlayer: rename('SetItemPlayerBJ'),\n      SetItemInvulnerable: rename('SetItemInvulnerableBJ'),\n      SetItemVisible: swap10('SetItemVisibleBJ'),\n      IsItemOwned: transformer({\n        CheckItemStatus: {\n          parameters: [0, 'ItemStatusOwned']\n        }\n      }),\n      IsItemPowerup: transformer({\n        CheckItemStatus: {\n          parameters: [0, 'ItemStatusPowerup']\n        }\n      }),\n      IsItemSellable: transformer({\n        CheckItemStatus: {\n          parameters: [0, 'ItemStatusSellable']\n        }\n      }),\n      IsItemPawnable: transformer({\n        CheckItemStatus: {\n          parameters: [0, 'ItemStatusPawnable']\n        }\n      }),\n      IsItemIdPowerup: transformer({\n        CheckItemcodeStatus: {\n          parameters: [0, 'ItemcodeStatusPowerup']\n        }\n      }),\n      IsItemIdSellable: transformer({\n        CheckItemcodeStatus: {\n          parameters: [0, 'ItemcodeStatusSellable']\n        }\n      }),\n      IsItemIdPawnable: transformer({\n        CheckItemcodeStatus: {\n          parameters: [0, 'ItemcodeStatusPawnable']\n        }\n      }),\n      EnumItemsInRect: transformer({\n        EnumItemsInRectBJ: {\n          test: [1, 'null'],\n          parameters: [0, 2]\n        }\n      }),\n      // Unit API\n      ShowUnit: transformer({\n        ShowUnitShow: {\n          test: [1, 'true'],\n          parameters: [0]\n        },\n        ShowUnitHide: {\n          test: [1, 'false'],\n          parameters: [0]\n        }\n      }),\n      SetUnitState: transformer({\n        SetUnitLifeBJ: {\n          test: [1, 'UNIT_STATE_LIFE'],\n          parameters: [0, 2]\n        },\n        SetUnitManaBJ: {\n          test: [1, 'UNIT_STATE_MANA'],\n          parameters: [0, 2]\n        }\n      }),\n      SetUnitFlyHeight: rename('SetUnitFlyHeightBJ'),\n      SetUnitTurnSpeed: rename('SetUnitTurnSpeedBJ'),\n      SetUnitAcquireRange: rename('SetUnitAcquireRangeBJ'),\n      SetUnitCreepGuard: transformer({\n        LockGuardPosition: {\n          test: [1, 'true'],\n          parameters: [0]\n        }\n      }),\n      GetUnitDefaultPropWindow: rename('GetUnitDefaultPropWindowBJ'),\n      SetUnitScale: transformer({\n        SetUnitScalePercent: {\n          parameters: [0, [1, '*', 100], [2, '*', 100], [3, '*', 100]]\n        }\n      }),\n      SetUnitTimeScale: transformer({\n        SetUnitTimeScalePercent: {\n          parameters: [0, [1, '*', 100]]\n        }\n      }),\n      SetUnitBlendTime: rename('SetUnitBlendTimeBJ'),\n      QueueUnitAnimation: rename('QueueUnitAnimationBJ'),\n      SetUnitAnimation: transformer({\n        ResetUnitAnimation: {\n          test: [1, '\"stand\"'],\n          parameters: [0]\n        }\n      }),\n      AddUnitAnimationProperties: swap210('AddUnitAnimationPropertiesBJ'),\n      SetHeroStr: transformer({\n        ModifyHeroStat: {\n          test: [2, 'true'],\n          parameters: ['HeroStatStr', 0, 'ModifyMethodSet', 1]\n        }\n      }),\n      SetHeroAgi: transformer({\n        ModifyHeroStat: {\n          test: [2, 'true'],\n          parameters: ['HeroStatAgi', 0, 'ModifyMethodSet', 1]\n        }\n      }),\n      SetHeroInt: transformer({\n        ModifyHeroStat: {\n          test: [2, 'true'],\n          parameters: ['HeroStatInt', 0, 'ModifyMethodSet', 1]\n        }\n      }),\n      GetHeroStr: transformer({\n        GetHeroStatBJ: {\n          parameters: ['HeroStatStr', 0, 1]\n        }\n      }),\n      GetHeroAgi: transformer({\n        GetHeroStatBJ: {\n          parameters: ['HeroStatAgi', 0, 1]\n        }\n      }),\n      GetHeroInt: transformer({\n        GetHeroStatBJ: {\n          parameters: ['HeroStatInt', 0, 1]\n        }\n      }),\n      UnitModifySkillPoints: transformer({\n        ModifyHeroSkillPoints: {\n          parameters: [0, '0', 1]\n        }\n      }),\n      AddHeroXP: swap102('AddHeroXPSwapped'),\n      GetUnitAbilityLevel: swap10('GetUnitAbilityLevelSwapped'),\n      DecUnitAbilityLevel: swap10('DecUnitAbilityLevelSwapped'),\n      IncUnitAbilityLevel: swap10('IncUnitAbilityLevelSwapped'),\n      SetUnitAbilityLevel: swap102('SetUnitAbilityLevelSwapped'),\n      SetUnitExploded: rename('SetUnitExplodedBJ'),\n      PauseUnit: swap10('PauseUnitBJ'),\n      IsUnitPaused: rename('IsUnitPausedBJ'),\n      SelectUnit: transformer({\n        SelectUnitAdd: {\n          test: [1, 'true'],\n          parameters: [0]\n        },\n        SelectUnitRemove: {\n          test: [1, 'false'],\n          parameters: [0]\n        }\n      }),\n      UnitAddItem: swap10('UnitAddItemSwapped'),\n      UnitRemoveItem: swap10('UnitRemoveItemSwapped'),\n      UnitRemoveItemFromSlot: transformer({\n        UnitRemoveItemFromSlotSwapped: {\n          parameters: [0, [1, '+', 1]]\n        }\n      }),\n      UnitItemInSlot: transformer({\n        UnitItemInSlotBJ: {\n          parameters: [0, [1, '+', 1]]\n        }\n      }),\n      UnitInventorySize: rename('UnitInventorySizeBJ'),\n      UnitDropItemSlot: transformer({\n        UnitDropItemSlotBJ: {\n          parameters: [0, 1, [2, '+', 1]]\n        }\n      }),\n      UnitDropItemTarget: rename('UnitDropItemTargetBJ'),\n      GetUnitState: swap10('GetUnitStateSwap'),\n      SetUnitUseFood: swap10('SetUnitUseFoodBJ'),\n      IsUnitOwnedByPlayer: transformerIsUnitOwnedByPlayer,\n      IsUnitRace: transformerIsUnitRace,\n      IsUnitType: transformerIsUnitType,\n      IsUnitHidden: rename('IsUnitHiddenBJ'),\n      IsUnitIllusion: rename('IsUnitIllusionBJ'),\n      IsUnitInTransport: rename('IsUnitInTransportBJ'),\n      IsUnitLoaded: rename('IsUnitLoadedBJ'),\n      UnitShareVision: swap201('UnitShareVisionBJ'),\n      UnitSuspendDecay: swap10('UnitSuspendDecayBJ'),\n      UnitAddType: swap10('UnitAddTypeBJ'),\n      UnitRemoveType: swap10('UnitRemoveTypeBJ'),\n      UnitAddAbility: swap10('UnitAddAbilityBJ'),\n      UnitRemoveAbility: swap10('UnitRemoveAbilityBJ'),\n      UnitRemoveBuffs: transformer({\n        UnitRemoveBuffsBJ: [\n          {\n            tests: [[1, 'true'], [2, 'false']],\n            parameters: ['BuffTypePositive', 0]\n          },\n          {\n            tests: [[1, 'false'], [2, 'true']],\n            parameters: ['BuffTypeNegative', 0]\n          },\n          {\n            tests: [[1, 'true'], [2, 'true']],\n            parameters: ['BuffTypeAll', 0]\n          }\n        ]\n      }),\n      UnitRemoveBuffsEx: transformer({\n        UnitRemoveBuffsBJ: {\n          tests: [[1, 'true'], [2, 'true'], [3, 'false'], [4, 'false'], [5, 'false'], [6, 'true'], [7, 'false']],\n          parameters: ['BuffTypeNonTLife', 0]\n        }\n      }),\n      UnitAddSleep: rename('UnitSetCanSleepBJ'),\n      UnitCanSleep: rename('UnitCanSleepBJ'),\n      UnitIsSleeping: rename('UnitIsSleepingBJ'),\n      UnitWakeUp: rename('UnitWakeUpBJ'),\n      UnitApplyTimedLife: swap210('UnitApplyTimedLifeBJ'),\n      UnitPauseTimedLife: swap10('UnitPauseTimedLifeBJ'),\n      UnitSetUsesAltIcon: swap10('UnitSetUsesAltIconBJ'),\n      UnitDamageTarget: transformer({\n        UnitDamageTargetBJ: {\n          tests: [[3, 'true'], [4, 'false'], [7, 'WEAPON_TYPE_WHOKNOWS']],\n          parameters: [0, 1, 2, 5, 6]\n        }\n      }),\n      IssueImmediateOrderById: rename('IssueTrainOrderByIdBJ'),\n      AddResourceAmount: swap10('AddResourceAmountBJ'),\n      WaygateActivate: swap10('WaygateActivateBJ'),\n      WaygateIsActive: rename('WaygateIsActiveBJ'),\n      AddItemToStock: swap1023('AddItemToStockBJ'),\n      AddUnitToStock: swap1023('AddUnitToStockBJ'),\n      RemoveItemFromStock: swap10('RemoveItemFromStockBJ'),\n      RemoveUnitFromStock: swap10('RemoveUnitFromStockBJ'),\n      // Player API\n      Player: transformer({\n        ConvertedPlayer: {\n          parameters: [[0, '+', 1]]\n        }\n      }),\n      SetPlayerHandicap: transformer({\n        SetPlayerHandicapBJ: {\n          parameters: [0, [1, '*', 100]]\n        }\n      }),\n      SetPlayerHandicapXP: transformer({\n        SetPlayerHandicapXPBJ: {\n          parameters: [0, [1, '*', 100]]\n        }\n      }),\n      SetPlayerTechMaxAllowed: swap120('SetPlayerTechMaxAllowedSwap'),\n      GetPlayerTechMaxAllowed: swap10('GetPlayerTechMaxAllowedSwap'),\n      SetPlayerTechResearched: swap120('SetPlayerTechResearchedSwap'),\n      GetPlayerTechCount: transformer({\n        GetPlayerTechCountSimple: {\n          test: [2, 'true'],\n          parameters: [1, 0]\n        }\n      }),\n      SetPlayerAbilityAvailable: swap210('SetPlayerAbilityAvailableBJ'),\n      // Fog of War API\n      FogMaskEnable: transformer({\n        FogMaskEnableOn: {\n          test: [0, 'true'],\n          parameters: []\n        },\n        FogMaskEnableOff: {\n          test: [0, 'false'],\n          parameters: []\n        }\n      }),\n      FogEnable: transformer({\n        FogEnableOn: {\n          test: [0, 'true'],\n          parameters: []\n        },\n        FogEnableOff: {\n          test: [0, 'false'],\n          parameters: []\n        }\n      }),\n      // Game API\n      SetCampaignMenuRace: transformer({\n        SetCampaignMenuRaceBJ: [\n          {\n            test: [0, 'RACE_OTHER'],\n            parameters: ['CampaignIndexT']\n          },\n          {\n            test: [0, 'RACE_HUMAN'],\n            parameters: ['CampaignIndexH']\n          },\n          {\n            test: [0, 'RACE_UNDEAD'],\n            parameters: ['CampaignIndexU']\n          },\n          {\n            test: [0, 'RACE_ORC'],\n            parameters: ['CampaignIndexO']\n          },\n          {\n            test: [0, 'RACE_NIGHTELF'],\n            parameters: ['CampaignIndexN']\n          }\n        ]\n      }),\n      SetCampaignMenuRaceEx: transformer({\n        SetCampaignMenuRaceBJ: [\n          {\n            test: [0, 'bj_CAMPAIGN_OFFSET_XN'],\n            parameters: ['CampaignIndexXN']\n          },\n          {\n            test: [0, 'bj_CAMPAIGN_OFFSET_XH'],\n            parameters: ['CampaignIndexXH']\n          },\n          {\n            test: [0, 'bj_CAMPAIGN_OFFSET_XU'],\n            parameters: ['CampaignIndexXU']\n          },\n          {\n            test: [0, 'bj_CAMPAIGN_OFFSET_XO'],\n            parameters: ['CampaignIndexXO']\n          }\n        ]\n      }),\n      LoadGame: rename('LoadGameBJ'),\n      RenameSaveDirectory: rename('RenameSaveDirectoryBJ'),\n      RemoveSaveDirectory: rename('RemoveSaveDirectoryBJ'),\n      CopySaveGame: rename('CopySaveGameBJ'),\n      GetFloatGameState: transformer({\n        GetTimeOfDay: {\n          test: [0, 'GAME_STATE_TIME_OF_DAY'],\n          parameters: []\n        }\n      }),\n      SetFloatGameState: transformer({\n        SetTimeOfDay: {\n          test: [0, 'GAME_STATE_TIME_OF_DAY'],\n          parameters: [1]\n        }\n      }),\n      // Campaign API\n      SetCustomCampaignButtonVisible: transformer({\n        ShowCustomCampaignButton: {\n          parameters: [[0, '+', 1], 1]\n        }\n      }),\n      GetCustomCampaignButtonVisible: transformer({\n        IsCustomCampaignButtonVisibile: {\n          parameters: [[0, '+', 1]]\n        }\n      }),\n      // Dialog API\n      DialogClear: rename('DialogClearBJ'),\n      DialogSetMessage: rename('DialogSetMessageBJ'),\n      DialogDisplay: swap210('DialogDisplayBJ'),\n      InitGameCache: rename('InitGameCacheBJ'),\n      SaveGameCache: rename('SaveGameCacheBJ'),\n      StoreInteger: swap3210('StoreIntegerBJ'),\n      StoreReal: swap3210('StoreRealBJ'),\n      StoreBoolean: swap3210('StoreBooleanBJ'),\n      StoreUnit: swap3210('StoreUnitBJ'),\n      StoreString: swap3210('StoreStringBJ'),\n      HaveStoredBoolean: transformer({\n        HaveStoredValue: {\n          parameters: [2, 'CacheValueTypeBoolean', 1, 0]\n        }\n      }),\n      HaveStoredInteger: transformer({\n        HaveStoredValue: {\n          parameters: [2, 'CacheValueTypeInteger', 1, 0]\n        }\n      }),\n      HaveStoredReal: transformer({\n        HaveStoredValue: {\n          parameters: [2, 'CacheValueTypeReal', 1, 0]\n        }\n      }),\n      HaveStoredUnit: transformer({\n        HaveStoredValue: {\n          parameters: [2, 'CacheValueTypeUnit', 1, 0]\n        }\n      }),\n      HaveStoredString: transformer({\n        HaveStoredValue: {\n          parameters: [2, 'CacheValueTypeString', 1, 0]\n        }\n      }),\n      FlushGameCache: rename('FlushGameCacheBJ'),\n      FlushStoredMission: swap10('FlushStoredMissionBJ'),\n      GetStoredInteger: swap210('GetStoredIntegerBJ'),\n      GetStoredReal: swap210('GetStoredRealBJ'),\n      GetStoredBoolean: swap210('GetStoredBooleanBJ'),\n      GetStoredString: swap210('GetStoredStringBJ'),\n      InitHashtable: rename('InitHashtableBJ'),\n      SaveInteger: swap3210('SaveIntegerBJ'),\n      SaveReal: swap3210('SaveRealBJ'),\n      SaveBoolean: swap3210('SaveBooleanBJ'),\n      SaveStr: swap3210('SaveStringBJ'),\n      SavePlayerHandle: swap3210('SavePlayerHandleBJ'),\n      SaveWidgetHandle: swap3210('SaveWidgetHandleBJ'),\n      SaveDestructableHandle: swap3210('SaveDestructableHandleBJ'),\n      SaveItemHandle: swap3210('SaveItemHandleBJ'),\n      SaveUnitHandle: swap3210('SaveUnitHandleBJ'),\n      SaveAbilityHandle: swap3210('SaveAbilityHandleBJ'),\n      SaveTimerHandle: swap3210('SaveTimerHandleBJ'),\n      SaveTriggerHandle: swap3210('SaveTriggerHandleBJ'),\n      SaveTriggerConditionHandle: swap3210('SaveTriggerConditionHandleBJ'),\n      SaveTriggerActionHandle: swap3210('SaveTriggerActionHandleBJ'),\n      SaveTriggerEventHandle: swap3210('SaveTriggerEventHandleBJ'),\n      SaveForceHandle: swap3210('SaveForceHandleBJ'),\n      SaveGroupHandle: swap3210('SaveGroupHandleBJ'),\n      SaveLocationHandle: swap3210('SaveLocationHandleBJ'),\n      SaveRectHandle: swap3210('SaveRectHandleBJ'),\n      SaveBooleanExprHandle: swap3210('SaveBooleanExprHandleBJ'),\n      SaveSoundHandle: swap3210('SaveSoundHandleBJ'),\n      SaveEffectHandle: swap3210('SaveEffectHandleBJ'),\n      SaveUnitPoolHandle: swap3210('SaveUnitPoolHandleBJ'),\n      SaveItemPoolHandle: swap3210('SaveItemPoolHandleBJ'),\n      SaveQuestHandle: swap3210('SaveQuestHandleBJ'),\n      SaveQuestItemHandle: swap3210('SaveQuestItemHandleBJ'),\n      SaveDefeatConditionHandle: swap3210('SaveDefeatConditionHandleBJ'),\n      SaveTimerDialogHandle: swap3210('SaveTimerDialogHandleBJ'),\n      SaveLeaderboardHandle: swap3210('SaveLeaderboardHandleBJ'),\n      SaveMultiboardHandle: swap3210('SaveMultiboardHandleBJ'),\n      SaveMultiboardItemHandle: swap3210('SaveMultiboardItemHandleBJ'),\n      SaveTrackableHandle: swap3210('SaveTrackableHandleBJ'),\n      SaveDialogHandle: swap3210('SaveDialogHandleBJ'),\n      SaveButtonHandle: swap3210('SaveButtonHandleBJ'),\n      SaveTextTagHandle: swap3210('SaveTextTagHandleBJ'),\n      SaveLightningHandle: swap3210('SaveLightningHandleBJ'),\n      SaveImageHandle: swap3210('SaveImageHandleBJ'),\n      SaveUbersplatHandle: swap3210('SaveUbersplatHandleBJ'),\n      SaveRegionHandle: swap3210('SaveRegionHandleBJ'),\n      SaveFogStateHandle: swap3210('SaveFogStateHandleBJ'),\n      SaveFogModifierHandle: swap3210('SaveFogModifierHandleBJ'),\n      LoadInteger: swap210('LoadIntegerBJ'),\n      LoadReal: swap210('LoadRealBJ'),\n      LoadBoolean: swap210('LoadBooleanBJ'),\n      LoadStr: swap210('LoadStringBJ'),\n      LoadPlayerHandle: swap210('LoadPlayerHandleBJ'),\n      LoadWidgetHandle: swap210('LoadWidgetHandleBJ'),\n      LoadDestructableHandle: swap210('LoadDestructableHandleBJ'),\n      LoadItemHandle: swap210('LoadItemHandleBJ'),\n      LoadUnitHandle: swap210('LoadUnitHandleBJ'),\n      LoadAbilityHandle: swap210('LoadAbilityHandleBJ'),\n      LoadTimerHandle: swap210('LoadTimerHandleBJ'),\n      LoadTriggerHandle: swap210('LoadTriggerHandleBJ'),\n      LoadTriggerConditionHandle: swap210('LoadTriggerConditionHandleBJ'),\n      LoadTriggerActionHandle: swap210('LoadTriggerActionHandleBJ'),\n      LoadTriggerEventHandle: swap210('LoadTriggerEventHandleBJ'),\n      LoadForceHandle: swap210('LoadForceHandleBJ'),\n      LoadGroupHandle: swap210('LoadGroupHandleBJ'),\n      LoadLocationHandle: swap210('LoadLocationHandleBJ'),\n      LoadRectHandle: swap210('LoadRectHandleBJ'),\n      LoadBooleanExprHandle: swap210('LoadBooleanExprHandleBJ'),\n      LoadSoundHandle: swap210('LoadSoundHandleBJ'),\n      LoadEffectHandle: swap210('LoadEffectHandleBJ'),\n      LoadUnitPoolHandle: swap210('LoadUnitPoolHandleBJ'),\n      LoadItemPoolHandle: swap210('LoadItemPoolHandleBJ'),\n      LoadQuestHandle: swap210('LoadQuestHandleBJ'),\n      LoadQuestItemHandle: swap210('LoadQuestItemHandleBJ'),\n      LoadDefeatConditionHandle: swap210('LoadDefeatConditionHandleBJ'),\n      LoadTimerDialogHandle: swap210('LoadTimerDialogHandleBJ'),\n      LoadLeaderboardHandle: swap210('LoadLeaderboardHandleBJ'),\n      LoadMultiboardHandle: swap210('LoadMultiboardHandleBJ'),\n      LoadMultiboardItemHandle: swap210('LoadMultiboardItemHandleBJ'),\n      LoadTrackableHandle: swap210('LoadTrackableHandleBJ'),\n      LoadDialogHandle: swap210('LoadDialogHandleBJ'),\n      LoadButtonHandle: swap210('LoadButtonHandleBJ'),\n      LoadTextTagHandle: swap210('LoadTextTagHandleBJ'),\n      LoadLightningHandle: swap210('LoadLightningHandleBJ'),\n      LoadImageHandle: swap210('LoadImageHandleBJ'),\n      LoadUbersplatHandle: swap210('LoadUbersplatHandleBJ'),\n      LoadRegionHandle: swap210('LoadRegionHandleBJ'),\n      LoadFogStateHandle: swap210('LoadFogStateHandleBJ'),\n      LoadFogModifierHandle: swap210('LoadFogModifierHandleBJ'),\n      HaveSavedBoolean: transformer({\n        HaveSavedValue: {\n          parameters: [2, 'HashtableValueTypeBoolean', 1, 0]\n        }\n      }),\n      HaveSavedInteger: transformer({\n        HaveSavedValue: {\n          parameters: [2, 'HashtableValueTypeInteger', 1, 0]\n        }\n      }),\n      HaveSavedReal: transformer({\n        HaveSavedValue: {\n          parameters: [2, 'HashtableValueTypeReal', 1, 0]\n        }\n      }),\n      HaveSavedString: transformer({\n        HaveSavedValue: {\n          parameters: [2, 'HashtableValueTypeString', 1, 0]\n        }\n      }),\n      HaveSavedHandle: transformer({\n        HaveSavedValue: {\n          parameters: [2, 'HashtableValueTypeHandle', 1, 0]\n        }\n      }),\n      FlushParentHashtable: rename('FlushParentHashtableBJ'),\n      FlushChildHashtable: swap10('FlushChildHashtableBJ'),\n      // Randomization API\n      ChooseRandomCreep: rename('ChooseRandomCreepBJ'),\n      ChooseRandomNPBuilding: rename('ChooseRandomNPBuildingBJ'),\n      ChooseRandomItem: rename('ChooseRandomItemBJ'),\n      ChooseRandomItemEx: swap10('ChooseRandomItemExBJ'),\n      // Visual API\n      ResetTerrainFog: rename('ResetTerrainFogBJ'),\n      SetTerrainFogEx: transformer({\n        SetTerrainFogExBJ: {\n          parameters: [0, 1, 2, 3, [4, '*', 100], [5, '*', 100], [6, '*', 100]]\n        }\n      }),\n      SetTimeOfDayScale: transformer({\n        SetTimeOfDayScalePercentBJ: {\n          parameters: [[0, '*', 100]]\n        }\n      }),\n      PauseGame: transformer({\n        PauseGameOn: {\n          test: [0, 'true'],\n          parameters: []\n        },\n        PauseGameOff: {\n          test: [0, 'false'],\n          parameters: []\n        }\n      }),\n      DestroyTextTag: rename('DestroyTextTagBJ'),\n      SetTextTagPosUnit: rename('SetTextTagPosUnitBJ'),\n      SetTextTagSuspended: rename('SetTextTagSuspendedBJ'),\n      SetTextTagPermanent: rename('SetTextTagPermanentBJ'),\n      SetTextTagAge: rename('SetTextTagAgeBJ'),\n      SetTextTagLifespan: rename('SetTextTagLifespanBJ'),\n      SetTextTagFadepoint: rename('SetTextTagFadepointBJ'),\n      // Quest API\n      DestroyQuest: rename('DestroyQuestBJ'),\n      QuestSetTitle: rename('QuestSetTitleBJ'),\n      QuestSetDescription: rename('QuestSetDescriptionBJ'),\n      QuestSetCompleted: rename('QuestSetCompletedBJ'),\n      QuestSetDiscovered: rename('QuestSetDiscoveredBJ'),\n      QuestSetFailed: rename('QuestSetFailedBJ'),\n      QuestSetEnabled: swap10('QuestSetEnabledBJ'),\n      QuestItemSetDescription: rename('QuestItemSetDescriptionBJ'),\n      QuestItemSetCompleted: rename('QuestItemSetCompletedBJ'),\n      DestroyDefeatCondition: rename('DestroyDefeatConditionBJ'),\n      DefeatConditionSetDescription: rename('DefeatConditionSetDescriptionBJ'),\n      FlashQuestDialogButton: rename('FlashQuestDialogButtonBJ'),\n      // Timer Dialog API\n      DestroyTimerDialog: rename('DestroyTimerDialogBJ'),\n      TimerDialogSetTitle: rename('TimerDialogSetTitleBJ'),\n      TimerDialogDisplay: swap10('TimerDialogDisplayBJ'),\n      // Leaderboard API\n      DestroyLeaderboard: rename('DestroyLeaderboardBJ'),\n      LeaderboardDisplay: swap10('LeaderboardDisplayBJ'),\n      LeaderboardRemovePlayerItem: swap10('LeaderboardRemovePlayerItemBJ'),\n      LeaderboardSortItemsByValue: transformer({\n        LeaderboardSortItemsBJ: {\n          parameters: [0, 'LeaderboardSortByValue', 1]\n        }\n      }),\n      LeaderboardSortItemsByPlayer: transformer({\n        LeaderboardSortItemsBJ: {\n          parameters: [0, 'LeaderboardSortByPlayer', 1]\n        }\n      }),\n      LeaderboardSortItemsByLabel: transformer({\n        LeaderboardSortItemsBJ: {\n          parameters: [0, 'LeaderboardSortByLabel', 1]\n        }\n      }),\n      LeaderboardHasPlayerItem: rename('LeaderboardHasPlayerItemBJ'),\n      LeaderboardSetLabel: rename('LeaderboardSetLabelBJ'),\n      PlayerGetLeaderboard: rename('PlayerGetLeaderboardBJ'),\n      LeaderboardSetStyle: rename('LeaderboardSetStyleBJ'),\n      // Multiboard API\n      DestroyMultiboard: rename('DestroyMultiboardBJ'),\n      MultiboardDisplay: swap10('MultiboardDisplayBJ'),\n      MultiboardMinimize: swap10('MultiboardMinimizeBJ'),\n      // Camera API\n      CameraSetupGetField: swap10('CameraSetupGetFieldSwap'),\n      CameraSetSmoothingFactor: rename('CameraSetSmoothingFactorBJ'),\n      DisplayCineFilter: rename('DisplayCineFilterBJ'),\n      ForceCinematicSubtitles: rename('ForceCinematicSubtitlesBJ'),\n      // Sound API\n      SetSoundDistanceCutoff: rename('SetSoundDistanceCutoffBJ'),\n      SetSoundPitch: rename('SetSoundPitchBJ'),\n      AttachSoundToUnit: rename('AttachSoundToUnitBJ'),\n      StopSound: transformer({\n        StopSoundBJ: {\n          test: [1, 'false'],\n          parameters: [0, 2]\n        }\n      }),\n      KillSoundWhenDone: rename('KillSoundWhenDoneBJ'),\n      SetMapMusic: transformer({\n        SetMapMusicIndexedBJ: {\n          test: [1, 'false'],\n          parameters: [0, 2]\n        },\n        SetMapMusicRandomBJ: {\n          tests: [[1, 'true'], [2, '0']],\n          parameters: [0]\n        }\n      }),\n      ClearMapMusic: rename('ClearMapMusicBJ'),\n      PlayMusic: rename('PlayMusicBJ'),\n      StopMusic: rename('StopMusicBJ'),\n      ResumeMusic: rename('ResumeMusicBJ'),\n      PlayThematicMusic: rename('PlayThematicMusicBJ'),\n      EndThematicMusic: rename('EndThematicMusicBJ'),\n      VolumeGroupSetVolume: transformer({\n        VolumeGroupSetVolumeBJ: {\n          parameters: [0, [1, '*', 100]]\n        }\n      }),\n      // Effects API\n      AddWeatherEffect: rename('AddWeatherEffectSaveLast'),\n      RemoveWeatherEffect: rename('RemoveWeatherEffectBJ'),\n      AddSpecialEffectLoc: swap10('AddSpecialEffectLocBJ'),\n      AddSpecialEffectTarget: swap210('AddSpecialEffectTargetUnitBJ'),\n      DestroyEffect: rename('DestroyEffectBJ'),\n      DestroyLightning: rename('DestroyLightningBJ'),\n      GetLightningColorA: rename('GetLightningColorABJ'),\n      GetLightningColorR: rename('GetLightningColorRBJ'),\n      GetLightningColorG: rename('GetLightningColorGBJ'),\n      GetLightningColorB: rename('GetLightningColorBBJ'),\n      SetLightningColor: rename('SetLightningColorBJ'),\n      GetAbilityEffectById: rename('GetAbilityEffectBJ'),\n      GetAbilitySoundById: rename('GetAbilitySoundBJ'),\n      // Image API\n      ShowImage: swap10('ShowImageBJ'),\n      // Ubersplat API\n      ShowUbersplat: swap10('ShowUbersplatBJ'),\n      // Blight API\n      SetBlightRect: swap201('SetBlightRectBJ'),\n      SetBlightLoc: swap3012('SetBlightRadiusLocBJ'),\n      // Doodad API\n      SetDoodadAnimationRect: transformer({\n        SetDoodadAnimationRectBJ: {\n          test: [3, 'false'],\n          parameters: [2, 1, 0]\n        },\n      }),\n    };\n  }\n}\n\nexport default function transformFunction(data: WeuData, object: ECA | SubParameters): boolean {\n  if (!initialized) {\n    initialize();\n  }\n\n  const transform = transformers[object.name];\n\n  if (transform) {\n    return transform(data, object);\n  }\n\n  return transformBlz(data, object);\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/transformations/presets.ts",
    "content": "import Parameter from '../../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../../parsers/w3x/wtg/subparameters';\nimport WeuData from '../data';\n\nlet initialized = false;\nlet transformers: {[keyof: string]: (data: WeuData, object: Parameter) => boolean };\n\nfunction preset(name: string) {\n  return function (data: WeuData, object: Parameter): boolean {\n    const subParameters = new SubParameters();\n\n    subParameters.name = name;\n    subParameters.type = data.triggerData.getFunctionType(name);\n\n    object.value = name;\n    object.type = 2;\n    object.subParameters = subParameters;\n\n    return true;\n  };\n}\n\nfunction initialize(): void {\n  if (!initialized) {\n    initialized = true;\n    transformers = {\n      bj_forLoopAIndex: preset('GetForLoopIndexA'),\n      bj_forLoopBIndex: preset('GetForLoopIndexB'),\n      bj_queuedExecTotal: preset('QueuedTriggerCountBJ'),\n      bj_mapInitialCameraBounds: preset('GetCameraBoundsMapRect'),\n      bj_mapInitialPlayableArea: preset('GetPlayableMapRect'),\n      bj_lastCreatedWeatherEffect: preset('GetLastCreatedWeatherEffect'),\n      bj_lastCreatedTerrainDeformation: preset('GetLastCreatedTerrainDeformation'),\n      bj_lastCreatedLightning: preset('GetLastCreatedLightningBJ'),\n      bj_lastCreatedFogModifier: preset('GetLastCreatedFogModifier'),\n      bj_lastCreatedImage: preset('GetLastCreatedImage'),\n      bj_lastCreatedUbersplat: preset('GetLastCreatedUbersplat'),\n      bj_lastPlayedSound: preset('GetLastPlayedSound'),\n      bj_lastPlayedMusic: preset('GetLastPlayedMusic'),\n      bj_useDawnDuskSounds: preset('IsDawnDuskEnabled'),\n      bj_lastCreatedEffect: preset('GetLastCreatedEffectBJ'),\n      bj_lastCreatedItem: preset('GetLastCreatedItem'),\n      bj_lastRemovedItem: preset('GetLastRemovedItem'),\n      bj_lastCreatedUnit: preset('GetLastCreatedUnit'),\n      bj_lastReplacedUnit: preset('GetLastReplacedUnitBJ'),\n      bj_lastCreatedDestructable: preset('GetLastCreatedDestructable'),\n      bj_FORCE_ALL_PLAYERS: preset('GetPlayersAll'),\n      bj_lastCreatedButton: preset('GetLastCreatedButtonBJ'),\n      bj_lastCreatedQuest: preset('GetLastCreatedQuestBJ'),\n      bj_lastCreatedQuestItem: preset('GetLastCreatedQuestItemBJ'),\n      bj_lastCreatedDefeatCondition: preset('GetLastCreatedDefeatConditionBJ'),\n      bj_lastStartedTimer: preset('GetLastCreatedTimerBJ'),\n      bj_lastCreatedTimerDialog: preset('GetLastCreatedTimerDialogBJ'),\n      bj_lastCreatedLeaderboard: preset('GetLastCreatedLeaderboard'),\n      bj_lastCreatedMultiboard: preset('GetLastCreatedMultiboard'),\n      bj_lastCreatedTextTag: preset('GetLastCreatedTextTag'),\n      bj_lastTransmissionDuration: preset('GetLastTransmissionDurationBJ'),\n      bj_lastCreatedGameCache: preset('GetLastCreatedGameCacheBJ'),\n      bj_lastCreatedHashtable: preset('GetLastCreatedHashtableBJ'),\n      bj_lastLoadedUnit: preset('GetLastRestoredUnitBJ'),\n      bj_lastHauntedGoldMine: preset('GetLastHauntedGoldMine'),\n    };\n  }\n}\n\nexport default function transformPreset(data: WeuData, parameter: Parameter): boolean {\n  if (!initialized) {\n    initialize();\n  }\n\n  const transform = transformers[parameter.value];\n\n  if (transform) {\n    return transform(data, parameter);\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/transformations/specific.ts",
    "content": "import ECA from '../../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../../parsers/w3x/wtg/subparameters';\nimport WeuData from '../data';\nimport { convertParameterInline } from '../conversions';\n\n/**\n * IsUnitOwnedByPlayer(whichUnit, whichPlayer) == boolean\n * =>\n * GetOwningPlayer(whichUnit) == whichPlayer\n */\nexport function transformerIsUnitOwnedByPlayer(data: WeuData, object: ECA | SubParameters): boolean {\n  const parameter = <Parameter>data.stack[1];\n  const comparator = <ECA>data.stack[2];\n  const comparatorParameters = comparator.parameters;\n\n  if (comparator.name !== 'OperatorCompareBoolean') {\n    return false;\n  }\n\n  let otherParameter;\n\n  if (comparator.parameters[0] === parameter) {\n    otherParameter = comparatorParameters[2];\n  } else {\n    otherParameter = comparatorParameters[0];\n  }\n\n  const trueOrFalse = convertParameterInline(data, otherParameter, 'boolean');\n\n  if (trueOrFalse !== 'true' && trueOrFalse !== 'false') {\n    return false;\n  }\n\n  // Change to a player comparison.\n  comparator.name = 'OperatorComparePlayer';\n\n  const parameters = object.parameters;\n  const whichPlayer = parameters[1];\n\n  // Change IsUnitOwnedByPlayer(whichUnit, whichPlayer) to GetOwningPlayer(whichUnit)\n  parameter.value = 'GetOwningPlayer';\n\n  object.name = 'GetOwningPlayer';\n  object.parameters.length = 1;\n\n  comparatorParameters[0] = parameter;\n\n  // Equal or not equal.\n  if (trueOrFalse === 'true') {\n    comparatorParameters[1].value = 'OperatorEqualENE';\n  } else {\n    comparatorParameters[1].value = 'OperatorNotEqualENE';\n  }\n\n  // Change the boolean to whichPlayer.\n  comparatorParameters[2] = whichPlayer;\n\n  return true;\n}\n\n/**\n * IsUnitRace(whichUnit, whichRace) == boolean\n * =>\n * GetUnitRace(whichUnit) == whichRace\n */\nexport function transformerIsUnitRace(data: WeuData, object: ECA | SubParameters): boolean {\n  const parameter = <Parameter>data.stack[1];\n  const comparator = <ECA>data.stack[2];\n  const comparatorParameters = comparator.parameters;\n\n  if (comparator.name !== 'OperatorCompareBoolean') {\n    return false;\n  }\n\n  let otherParameter;\n\n  if (comparator.parameters[0] === parameter) {\n    otherParameter = comparatorParameters[2];\n  } else {\n    otherParameter = comparatorParameters[0];\n  }\n\n  const trueOrFalse = convertParameterInline(data, otherParameter, 'boolean');\n\n  if (trueOrFalse !== 'true' && trueOrFalse !== 'false') {\n    return false;\n  }\n\n  // Change to a race comparison.\n  comparator.name = 'OperatorCompareRace';\n\n  const parameters = object.parameters;\n  const whichRace = parameters[1];\n\n  // Change IsUnitRace(whichUnit, whichRace) to GetUnitRace(whichUnit)\n  parameter.value = 'GetUnitRace';\n\n  object.name = 'GetUnitRace';\n  object.parameters.length = 1;\n\n  comparatorParameters[0] = parameter;\n\n  const isEqual = comparatorParameters[1].value === 'OperatorEqualENE';\n  const isTrue = trueOrFalse === 'true';\n\n  // Essentially a XOR between the booleans.\n  if (isEqual === isTrue) {\n    comparatorParameters[1].value = 'OperatorEqualENE';\n  } else {\n    comparatorParameters[1].value = 'OperatorNotEqualENE';\n  }\n\n  comparatorParameters[1] = whichRace;\n\n  return true;\n}\n\n/**\n * IsUnitType(whichUnit, UNIT_TYPE_DEAD) == boolean\n * =>\n * IsUnitDeadBJ(whichUnit) == boolean\n */\nexport function transformerIsUnitType(data: WeuData, object: ECA | SubParameters): boolean {\n  const comparator = <ECA>data.stack[2];\n\n  if (comparator.name !== 'OperatorCompareBoolean') {\n    return false;\n  }\n\n  const whichUnitType = convertParameterInline(data, object.parameters[1], 'unittype');\n\n  if (whichUnitType !== 'UNIT_TYPE_DEAD') {\n    return false;\n  }\n\n  const parameter = <Parameter>data.stack[1];\n\n  // Change IsUnitType(whichUnit, UNIT_TYPE_DEAD) to IsUnitDeadBJ(whichUnit)\n  parameter.value = 'IsUnitDeadBJ';\n\n  object.name = 'IsUnitDeadBJ';\n  object.parameters.length = 1;\n\n  return true;\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/transformations/transformer.ts",
    "content": "import ECA from '../../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../../parsers/w3x/wtg/subparameters';\nimport WeuData from '../data';\nimport { convertParameterInline } from '../conversions';\n\ntype WEUTransformerTest = [number, string];\n\ntype WEUTransformerOp = [number, '+' | '-' | '*' | '/', number];\n\ntype WEUTransformerParameter = number | string | WEUTransformerOp;\n\ninterface WEUTransformerTransformation {\n  test?: WEUTransformerTest;\n  tests?: WEUTransformerTest[];\n  parameters?: WEUTransformerParameter[];\n}\n\ninterface WEUTransformerTransformations {\n  [keyof: string]: WEUTransformerTransformation | WEUTransformerTransformation[];\n}\n\nfunction runTests(data: WeuData, object: ECA | SubParameters, args: string[], mapping: WEUTransformerTransformation, convertedParameters: string[]): boolean {\n  const parameters = object.parameters;\n  const tests = [];\n\n  if (mapping.test) {\n    tests.push(mapping.test);\n  }\n\n  if (mapping.tests) {\n    tests.push(...mapping.tests);\n  }\n\n  for (const [index, value] of tests) {\n    // Convert and cache the parameter.\n    if (convertedParameters[index] === undefined) {\n      convertedParameters[index] = convertParameterInline(data, parameters[index], args[index]);\n    }\n\n    if (value !== convertedParameters[index]) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction setNameAndType(data: WeuData, object: ECA | SubParameters, name: string): void {\n  object.name = name;\n  object.type = data.triggerData.getFunctionType(name);\n\n  if (object instanceof SubParameters) {\n    const parameter = <Parameter>data.stack[1];\n\n    parameter.value = name;\n  }\n}\n\nfunction setParameters(data: WeuData, object: ECA | SubParameters, args: string[], mapping: WEUTransformerTransformation): void {\n  if (mapping.parameters) {\n    const parameters = object.parameters;\n\n    object.parameters = mapping.parameters.map((value) => {\n      if (typeof value === 'number') {\n        return parameters[value];\n      } else if (typeof value === 'string') {\n        const parameter = new Parameter();\n\n        if (data.triggerData.getPreset(value)) {\n          parameter.type = 0;\n        } else {\n          parameter.type = 3;\n        }\n\n        parameter.value = value;\n\n        return parameter;\n      } else {\n        const whichParameter = value[0];\n        const whichOperator = value[1];\n        const operandValue = value[2];\n        const argType = args[whichParameter];\n        let typedFunction;\n        let mathOp;\n\n        if (argType === 'integer') {\n          typedFunction = 'OperatorInt';\n        } else if (argType === 'real') {\n          typedFunction = 'OperatorReal';\n        } else {\n          throw new Error(`Attempted to use an operator on a non-number parameter of type \"${argType}`);\n        }\n\n        if (whichOperator === '+') {\n          mathOp = 'OperatorAdd';\n        } else if (whichOperator === '-') {\n          mathOp = 'OperatorSubtract';\n        } else if (whichOperator === '*') {\n          mathOp = 'OperatorMultiply';\n        } else {\n          mathOp = 'OperatorDivide';\n        }\n\n        const parameter = new Parameter();\n\n        parameter.value = typedFunction;\n        parameter.type = 2;\n\n        const subParameters = new SubParameters();\n\n        subParameters.name = typedFunction;\n        subParameters.type = 3;\n\n        const operandA = parameters[whichParameter];\n\n        const operator = new Parameter();\n\n        operator.type = 0;\n        operator.value = mathOp;\n\n        const operandB = new Parameter();\n\n        operandB.type = 3;\n        operandB.value = `${operandValue}`;\n\n        subParameters.beginParameters = 1;\n        subParameters.parameters = [operandA, operator, operandB];\n\n        parameter.subParameters = subParameters;\n\n        return parameter;\n      }\n    });\n  }\n}\n\nexport default function transformer(transformations: WEUTransformerTransformations) {\n  return function (data: WeuData, object: ECA | SubParameters): boolean {\n    // The signature for the input (to be replaced) function.\n    const signature = data.triggerData.getFunction(object.type, object.name);\n\n    // This can happen if there is a transformer that is implemented, however it's not found in the custom TriggerData.txt\n    // Perhaps it will be worthwhile in the future to also query the signature from common.j, however that's an extra download etc.\n    // For now I am going to assume the used YDWE TriggerData.txt exposes more or less everything.\n    if (!signature) {\n      console.warn(`transformer failed to get the signature for the input function: ${object.name}`);\n\n      return false;\n    }\n\n    const args = signature.args;\n\n    // A cache for converted parameters.\n    // If there are multiple transformations, or transformations with multiple mappings, usually they branch on the same parameter(s).\n    // The first time a parameter is tested, it will be converted, and stored here.\n    // The next time it is tested, it will be fetched directly.\n    const convertedParameters: string[] = [];\n\n    for (const [name, mappings] of Object.entries(transformations)) {\n      let mappingAsArray;\n\n      if (Array.isArray(mappings)) {\n        mappingAsArray = mappings;\n      } else {\n        mappingAsArray = [mappings];\n      }\n\n      for (const mapping of mappingAsArray) {\n        if (runTests(data, object, args, mapping, convertedParameters)) {\n          setNameAndType(data, object, name);\n          setParameters(data, object, args, mapping);\n\n          return true;\n        }\n      }\n    }\n\n    return false;\n  };\n}\n\nexport type Transformer = ReturnType<typeof transformer>;\n"
  },
  {
    "path": "src/utils/w3x/weu/utils.ts",
    "content": "import { byteLengthUtf8, splitUtf8ByteLength } from '../../../common/utf8';\nimport ECA from '../../../parsers/w3x/wtg/eca';\nimport Parameter from '../../../parsers/w3x/wtg/parameter';\nimport SubParameters from '../../../parsers/w3x/wtg/subparameters';\n\n/**\n * Creates a new Custom Script or comment ECA with the given data.\n */\nexport function createCustomScriptOrCommentECA(data: string, isComment: boolean): ECA {\n  const eca = new ECA();\n\n  eca.type = 2; // Action\n\n  if (isComment) {\n    eca.name = 'CommentString';\n  } else {\n    eca.name = 'CustomScriptCode';\n  }\n\n  eca.isEnabled = 1;\n\n  const parameter = new Parameter();\n\n  parameter.type = 3; // String\n  parameter.value = data;\n\n  eca.parameters[0] = parameter;\n\n  return eca;\n}\n\n/**\n * Creates a new Custom Script ECA with the given script.\n */\nexport function createCustomScriptECA(script: string): ECA {\n  return createCustomScriptOrCommentECA(script, false);\n}\n\n// /**\n//  * Creates a new comment ECA with the given comment.\n//  */\n// function createCommentECA(comment: string) {\n//   return createCustomScriptOrCommentECA(comment, true);\n// }\n\nfunction subParametersToEca(subParameters: SubParameters, group: number): ECA {\n  const eca = new ECA();\n\n  eca.name = subParameters.name;\n  eca.type = subParameters.type;\n  eca.group = group;\n  eca.isEnabled = 1;\n  eca.parameters.push(...subParameters.parameters);\n\n  return eca;\n}\n\nexport function convertSingleToMultiple(eca: ECA): boolean {\n  if (eca.name === 'IfThenElse') {\n    const parameters = eca.parameters;\n    const ifParam = subParametersToEca(<SubParameters>parameters[0].subParameters, 0);\n    const thenParam = subParametersToEca(<SubParameters>parameters[1].subParameters, 1);\n    const elseParam = subParametersToEca(<SubParameters>parameters[2].subParameters, 2);\n\n    eca.name = 'IfThenElseMultiple';\n    eca.parameters.length = 0;\n    eca.ecas.push(ifParam, thenParam, elseParam);\n\n    return true;\n  } else if (eca.name === 'ForGroup' || eca.name === 'ForForce') {\n    const action = subParametersToEca(<SubParameters>eca.parameters[1].subParameters, 0);\n\n    eca.name = `${eca.name}Multiple`;\n    eca.parameters.length = 1;\n    eca.ecas.push(action);\n\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Given the name of the parent of some child ECA, and the child's group, determine if it's a condition.\n */\nexport function isConditionECA(name: string, group: number): boolean {\n  if (group !== 0) {\n    return false;\n  }\n\n  return name === 'AndMultiple' || name === 'OrMultiple' || name === 'IfThenElseMultiple';\n}\n\n// The number of bytes that each custom script action can contain.\nconst SCRIPT_LINE_LENGTH = 239;\n\n/**\n * CustomScriptCode ECAs have a maximum length for their (typically) string parameter.\n * If the script length exceeds the maximum length, WE will fail to load the map properly.\n * Either it crashes, or it loads the map and GUI up until the invalid ECA, after which everything is an error.\n * This function is used to split such ECAs.\n * Splitting is possible, because the Jass parser seems to not consider multiline comments as token delimiters.\n * For example, the following lines:\n * \n *   call BJDebug/*\n *   /*Msg(\"hi\")\n * \n * When compiled result in the correct call:\n * \n *   call BJDebugMsg(\"hi\")\n */\nexport function ensureCustomScriptCodeSafety(ecas: ECA[]): ECA[] {\n  const outputEcas = [];\n\n  for (const eca of ecas) {\n    if (eca.name === 'CustomScriptCode') {\n      const script = eca.parameters[0].value;\n      const scriptByteLength = byteLengthUtf8(script);\n\n      if (scriptByteLength > SCRIPT_LINE_LENGTH) {\n        const chunks = splitUtf8ByteLength(script, SCRIPT_LINE_LENGTH);\n        const lines = chunks.length;\n        const lastLine = lines - 1;\n\n        for (let i = 0; i < lines; i++) {\n          let text = '';\n\n          // If this is not the first line, end the previous line's comment.\n          if (i > 0) {\n            text += '*/';\n          }\n\n          text += chunks[i];\n\n          // If this is not the last line, start a new comment.\n          if (i < lastLine) {\n            text += '/*';\n          }\n\n          const customScript = createCustomScriptECA(text);\n\n          customScript.group = eca.group;\n\n          outputEcas.push(customScript);\n        }\n      } else {\n        outputEcas.push(eca);\n      }\n    } else {\n      outputEcas.push(eca);\n    }\n  }\n\n  return outputEcas;\n}\n\n/**\n * Given a name, converts all of the non-ASCII characters and space characters to underlines.\n */\nexport function ensureNameSafety(name: string): string {\n  // Convert non-ASCII characters to underlines, for locales other than en.\n  return name.split('').map((c) => c.charCodeAt(0) > 127 ? '_' : c).join('').replace(/\\s/g, '_');\n}\n"
  },
  {
    "path": "src/utils/w3x/weu/weu.ts",
    "content": "import War3Map from '../../../parsers/w3x/map';\nimport { TriggerData } from '../../../parsers/w3x/wtg/triggerdata';\nimport CustomTextTrigger from '../../../parsers/w3x/wct/customtexttrigger';\nimport parseWtg from './parsewtg';\nimport WeuData, { WEUChange } from './data';\nimport { processTrigger } from './processing';\nimport { convertTrigger } from './conversions';\n\nexport interface WeuConversionResult {\n  ok: boolean;\n  error?: string;\n  changes?: WEUChange[];\n}\n\nexport default function convertWeu(map: War3Map, customTriggerData: TriggerData, weTriggerData: TriggerData): WeuConversionResult {\n  let wts;\n  let wtg;\n  let wct;\n\n  // Try to read the string table.\n  try {\n    wts = map.readStringTable();\n  } catch (e) {\n    return { ok: false, error: `Failed to read the string table file: ${e}` };\n  }\n\n  if (!wts) {\n    return { ok: false, error: `The string table file doesn't exist` };\n  }\n\n  // Try to add function signatures from the map script.\n  // This handles the case of injected libraries, mostly seen in YDWE maps.\n  const scriptFile = map.getScriptFile();\n  if (scriptFile && scriptFile.name.endsWith('.j')) {\n    try {\n      customTriggerData.addJassFunctions(scriptFile.text());\n    } catch (e) {\n\n    }\n  }\n\n  const data = new WeuData(customTriggerData, wts);\n\n  // Try to read the triggers file using the custom trigger data.\n  // This will also try to analyze unknown signatures if such exist.\n  try {\n    wtg = parseWtg(map, customTriggerData, data);\n  } catch (e) {\n    return { ok: false, error: `Failed to read the triggers file: ${e}` };\n  }\n\n  if (!wtg) {\n    return { ok: false, error: `The triggers file doesn't exist` };\n  }\n\n  // Try to read the custom text triggers file.\n  try {\n    wct = map.readCustomTextTriggers();\n  } catch (e) {\n    return { ok: false, error: `Failed to read the custom text triggers file: ${e}` };\n  }\n\n  if (!wct) {\n    return { ok: false, error: `The custom text triggers file doesn't exist` };\n  }\n\n  const triggers = wtg.triggers;\n  const customTextTriggers = wct.triggers;\n  const mapHeader = wct.trigger;\n\n  // If there are less custom text triggers than triggers, WE does not crash, however it doesn't load the map.\n  if (customTextTriggers.length < triggers.length) {\n    for (let i = 0, l = triggers.length - customTextTriggers.length; i < l; i++) {\n      customTextTriggers.push(new CustomTextTrigger());\n    }\n  }\n\n  // Process and convert the triggers as needed.\n  for (let i = 0, l = triggers.length; i < l; i++) {\n    const trigger = triggers[i];\n\n    // Any callbacks that are generated due to conversions for this trigger will end up here.\n    const callbacks: string[] = [];\n\n    try {\n      // Process the trigger.\n      // If things inside it need to be converted, this will convert them.\n      const result = processTrigger(data, trigger, callbacks);\n\n      // If the trigger itself needs to be converted, convert it.\n      if (result.convert) {\n        data.push(trigger);\n\n        // The trigger body.\n        let body = convertTrigger(data, trigger, callbacks);\n\n        // If any callbacks were generated when converting the trigger, add them to the trigger.\n        if (callbacks.length) {\n          body = `${callbacks.join('\\r\\n')}\\r\\n${body}`;\n        }\n\n        customTextTriggers[i].text = body;\n\n        trigger.ecas.length = 0;\n        trigger.isCustom = 1;\n\n        data.change('convertedtrigger', result.reason, customTextTriggers[i].text);\n        data.pop();\n      } else if (callbacks.length) {\n        const callbacksText = callbacks.join('\\r\\n');\n\n        // If the trigger didn't need to be converted, but callbacks were generated due to things inside it being converted, add them to the map header.\n        mapHeader.text += `// Callbacks generated for trigger \"${trigger.name}\" due to conversions\\r\\n${callbacksText}\\r\\n`;\n\n        data.change('generatedcallbacks', trigger.name, callbacksText);\n      }\n    } catch (e) {\n      return { ok: false, error: `Error at ${data.stackToString()}: ${e}` };\n    }\n  }\n\n  // WE will only generate global variables for preplaced objects that are referenced directly by GUI.\n  // Referencing them in custom text ECAs or custom text triggers doesn't cut it.\n  // This function saves such references if they are deemed to be lost due to the conversion.\n  // It does this by adding a new trigger called PreplacedObjectReferences, which is not initially on.\n  // In it an ECA is added for each reference.\n  // Note that this is not the case for all preplaced objects.\n  // For example, triggers and regions seem to always be available.\n  // For now only units and destructibles are checked.\n  data.saveGUIReferences(triggers, customTextTriggers);\n\n  // Save the triggers file back.\n  map.set('war3map.wtg', wtg.save());\n\n  // Save the custom text triggers file back.\n  map.set('war3map.wct', wct.save());\n\n  // Now try to re-read the triggers file, but using the normal WE trigger data.\n  // If this fails, WE will fail too.\n  try {\n    wtg = map.readTriggers(weTriggerData);\n  } catch (e) {\n    return { ok: false, error: `Failed to validate the triggers file: ${e}` };\n  }\n\n  if (!wtg) {\n    return { ok: false, error: `Failed to re-read the triggers file` };\n  }\n\n  return { ok: true, changes: data.changes };\n}\n"
  },
  {
    "path": "src/version.ts",
    "content": "export const version = '5.13.0';\n"
  },
  {
    "path": "src/viewer/bounds.ts",
    "content": "/**\n * An object representing both a sphere and an AABB, which is used for culling of all instances.\n * \n * By default, the size of the bounds is 0, and thus point-culling is done.\n */\nexport default class Bounds {\n  x = 0;\n  y = 0;\n  z = 0;\n  r = 0;\n\n  fromExtents(min: Float32Array, max: Float32Array): void {\n    const x = min[0];\n    const y = min[1];\n    const z = min[2];\n    const w = max[0] - x;\n    const d = max[1] - y;\n    const h = max[2] - z;\n\n    this.x = x + w / 2;\n    this.y = y + d / 2;\n    this.z = z + h / 2;\n\n    // Ensure the radius is actually 0 or bigger.\n    // Some models apparently have reversed extents, go figure.\n    this.r = Math.max(0, Math.max(w, d, h) / 2);\n  }\n}\n"
  },
  {
    "path": "src/viewer/camera.ts",
    "content": "import { vec3, vec4, quat, mat4 } from 'gl-matrix';\nimport { VEC3_UNIT_Y, VEC3_UNIT_X, VEC3_UNIT_Z, unproject, unpackPlanes, quatLookAt } from '../common/gl-matrix-addon';\n\nconst vectorHeap = vec3.create();\nconst vectorHeap2 = vec3.create();\nconst vectorHeap3 = vec3.create();\nconst quatHeap = quat.create();\nconst facingCorrection = quat.setAxisAngle(quat.create(), VEC3_UNIT_X, Math.PI / 2);\n\n/**\n * A camera.\n */\nexport default class Camera {\n  isPerspective = true;\n  fov = 0;\n  aspect = 0;\n  isOrtho = false;\n  leftClipPlane = 0;\n  rightClipPlane = 0;\n  bottomClipPlane = 0;\n  topClipPlane = 0;\n  nearClipPlane = 0;\n  farClipPlane = 0;\n  location = vec3.create();\n  rotation = quat.create();\n  inverseRotation = quat.create();\n  /**\n   * World -> View.\n   */\n  viewMatrix = mat4.create();\n  /**\n   * View -> Clip.\n   */\n  projectionMatrix = mat4.create();\n  /**\n   * World -> Clip.\n   */\n  viewProjectionMatrix = mat4.create();\n  /**\n   * View -> World.\n   */\n  inverseViewMatrix = mat4.create();\n  /**\n   * Clip -> World.\n   */\n  inverseViewProjectionMatrix = mat4.create();\n  /**\n   * The X axis in camera space.\n   */\n  directionX = vec3.create();\n  /**\n   * The Y axis in camera space.\n   */\n  directionY = vec3.create();\n  /**\n   * The Z axis in camera space.\n   */\n  directionZ = vec3.create();\n  /**\n   * The four corners of a 2x2 rectangle.\n   */\n  vectors = [vec3.fromValues(-1, -1, 0), vec3.fromValues(-1, 1, 0), vec3.fromValues(1, 1, 0), vec3.fromValues(1, -1, 0), vec3.fromValues(1, 0, 0), vec3.fromValues(0, 1, 0), vec3.fromValues(0, 0, 1)];\n  /**\n   * Same as vectors, however these are all billboarded to the camera.\n   */\n  billboardedVectors = [vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create()];\n  /**\n   * The camera frustum planes in this order: left, right, top, bottom, near, far.\n   */\n  planes = [vec4.create(), vec4.create(), vec4.create(), vec4.create(), vec4.create(), vec4.create()];\n\n  /**\n   * Set the camera to perspective projection mode.\n   */\n  perspective(fov: number, aspect: number, near: number, far: number): void {\n    this.isPerspective = true;\n    this.isOrtho = false;\n    this.fov = fov;\n    this.aspect = aspect;\n    this.nearClipPlane = near;\n    this.farClipPlane = far;\n\n    this.update();\n  }\n\n  /**\n   * Set the camera to orthogonal projection mode.\n   */\n  ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): void {\n    this.isPerspective = false;\n    this.isOrtho = true;\n    this.leftClipPlane = left;\n    this.rightClipPlane = right;\n    this.bottomClipPlane = bottom;\n    this.topClipPlane = top;\n    this.nearClipPlane = near;\n    this.farClipPlane = far;\n\n    this.update();\n  }\n\n  /**\n   * Set the camera location in world coordinates.\n   */\n  setLocation(location: vec3): void {\n    vec3.copy(this.location, location);\n\n    this.update();\n  }\n\n  /**\n   * Move the camera by the given offset in world coordinates.\n   */\n  move(offset: vec3): void {\n    vec3.add(this.location, this.location, offset);\n\n    this.update();\n  }\n\n  /**\n   * Set the camera rotation.\n   */\n  setRotation(rotation: quat): void {\n    quat.copy(this.rotation, rotation);\n\n    this.update();\n  }\n\n  /**\n   * Rotate the camera by the given rotation.\n   */\n  rotate(rotation: quat): void {\n    quat.mul(this.rotation, this.rotation, rotation);\n\n    this.update();\n  }\n\n  /**\n   * Look at `to`.\n   */\n  face(to: vec3, worldUp: vec3): void {\n    quat.mul(this.rotation, facingCorrection, quatLookAt(quatHeap, to, this.location, worldUp));\n\n    this.update();\n  }\n\n  /**\n   * Move to `from` and look at `to`.\n   */\n  moveToAndFace(from: vec3, to: vec3, worldUp: vec3): void {\n    vec3.copy(this.location, from);\n    this.face(to, worldUp);\n  }\n\n  /**\n   * Reset the location and angles.\n   */\n  reset(): void {\n    vec3.set(this.location, 0, 0, 0);\n    quat.identity(this.rotation);\n\n    this.update();\n  }\n\n  /**\n   * Recalculate the camera's transformation.\n   */\n  update(): void {\n    const location = this.location;\n    const rotation = this.rotation;\n    const inverseRotation = this.inverseRotation;\n    const viewMatrix = this.viewMatrix;\n    const projectionMatrix = this.projectionMatrix;\n    const viewProjectionMatrix = this.viewProjectionMatrix;\n    const vectors = this.vectors;\n    const billboardedVectors = this.billboardedVectors;\n\n    // View -> Clip.\n    if (this.isPerspective) {\n      mat4.perspective(projectionMatrix, this.fov, this.aspect, this.nearClipPlane, this.farClipPlane);\n    } else {\n      mat4.ortho(projectionMatrix, this.leftClipPlane, this.rightClipPlane, this.bottomClipPlane, this.topClipPlane, this.nearClipPlane, this.farClipPlane);\n    }\n\n    // World -> View.\n    mat4.fromQuat(viewMatrix, rotation);\n    mat4.translate(viewMatrix, viewMatrix, vec3.negate(vectorHeap, location));\n\n    // World -> Clip.\n    mat4.mul(viewProjectionMatrix, projectionMatrix, viewMatrix);\n\n    // View -> World.\n    mat4.invert(this.inverseViewMatrix, viewMatrix);\n\n    // Clip -> World.\n    mat4.invert(this.inverseViewProjectionMatrix, viewProjectionMatrix);\n\n    // Recaculate the camera's frusum planes\n    unpackPlanes(this.planes, viewProjectionMatrix);\n\n    quat.conjugate(inverseRotation, rotation);\n\n    // View-space axes.\n    vec3.transformQuat(this.directionX, VEC3_UNIT_X, inverseRotation);\n    vec3.transformQuat(this.directionY, VEC3_UNIT_Y, inverseRotation);\n    vec3.transformQuat(this.directionZ, VEC3_UNIT_Z, inverseRotation);\n\n    // View-space rectangle, aka billboarded.\n    for (let i = 0; i < 7; i++) {\n      vec3.transformQuat(billboardedVectors[i], vectors[i], inverseRotation);\n    }\n  }\n\n  /**\n   * Given a vector in camera space, return the vector transformed to world space.\n   */\n  cameraToWorld(out: vec3, v: vec3): vec3 {\n    return vec3.transformMat4(out, v, this.inverseViewMatrix);\n  }\n\n  /**\n   * Given a vector in world space, return the vector transformed to camera space.\n   */\n  worldToCamera(out: vec3, v: vec3): vec3 {\n    return vec3.transformMat4(out, v, this.viewMatrix);\n  }\n\n  /**\n   * Given a vector in world space, return the vector transformed to screen space.\n   */\n  worldToScreen(out: Float32Array, v: Float32Array, viewport: vec4): Float32Array {\n    vec3.transformMat4(vectorHeap, <vec3>v, this.viewProjectionMatrix);\n\n    out[0] = Math.round(((vectorHeap[0] + 1) / 2) * viewport[2]);\n    out[1] = Math.round(((vectorHeap[1] + 1) / 2) * viewport[3]);\n\n    return out;\n  }\n\n  /**\n   * Given a vector in screen space, return a ray from the near plane to the far plane.\n   */\n  screenToWorldRay(out: Float32Array, v: Float32Array, viewport: vec4): Float32Array {\n    const a = vectorHeap;\n    const b = vectorHeap2;\n    const c = vectorHeap3;\n    const x = v[0];\n    const y = v[1];\n    const inverseViewProjectionMatrix = this.inverseViewProjectionMatrix;\n\n    // Intersection on the near-plane\n    unproject(a, vec3.set(c, x, y, 0), inverseViewProjectionMatrix, viewport);\n\n    // Intersection on the far-plane\n    unproject(b, vec3.set(c, x, y, 1), inverseViewProjectionMatrix, viewport);\n\n    out.set(a, 0);\n    out.set(b, 3);\n\n    return out;\n  }\n}\n"
  },
  {
    "path": "src/viewer/cell.ts",
    "content": "import { testCell } from '../common/gl-matrix-addon';\nimport Camera from './camera';\nimport ModelInstance from './modelinstance';\n\n/**\n * A grid cell.\n */\nexport default class Cell {\n  left: number;\n  right: number;\n  bottom: number;\n  top: number;\n  plane = -1;\n  instances: ModelInstance[] = [];\n  visible = false;\n\n  constructor(left: number, right: number, bottom: number, top: number) {\n    this.left = left;\n    this.right = right;\n    this.bottom = bottom;\n    this.top = top;\n  }\n\n  add(instance: ModelInstance): void {\n    this.instances.push(instance);\n  }\n\n  remove(instance: ModelInstance): void {\n    const index = this.instances.indexOf(instance);\n\n    this.instances.splice(index, 1);\n  }\n\n  /**\n   * Remove all of the instances from this cell.\n   */\n  clear(): void {\n    this.instances.length = 0;\n  }\n\n  isVisible(camera: Camera): boolean {\n    this.plane = testCell(camera.planes, this.left, this.right, this.bottom, this.top, this.plane);\n\n    return this.plane === -1;\n  }\n}\n"
  },
  {
    "path": "src/viewer/emittedobject.ts",
    "content": "import Emitter from './emitter';\n\n/**\n * An emitted object.\n */\nexport default abstract class EmittedObject {\n  emitter: Emitter;\n  index = -1;\n  health = 0;\n\n  abstract bind(emitData?: unknown): void;\n  abstract update(dt: number): void;\n\n  constructor(emitter: Emitter) {\n    this.emitter = emitter;\n  }\n}\n"
  },
  {
    "path": "src/viewer/emittedobjectupdater.ts",
    "content": "import EmittedObject from './emittedobject';\n\n/**\n * An emitted object updater.\n */\nexport default class EmittedObjectUpdater {\n  objects: EmittedObject[] = [];\n  alive = 0;\n\n  add(object: EmittedObject): void {\n    this.objects[this.alive++] = object;\n  }\n\n  update(dt: number): void {\n    const objects = this.objects;\n\n    for (let i = 0; i < this.alive; i++) {\n      const object = objects[i];\n\n      object.update(dt * object.emitter.instance.timeScale);\n\n      if (object.health <= 0) {\n        this.alive -= 1;\n\n        object.emitter.kill(object);\n\n        // Swap between this object and the last living object.\n        // Decrement the iterator so the swapped object is updated this frame.\n        if (i !== this.alive) {\n          objects[i] = objects[this.alive];\n          i -= 1;\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/emitter.ts",
    "content": "import Scene from './scene';\nimport ModelInstance from './modelinstance';\nimport EmittedObject from './emittedobject';\n\n/**\n * An emitter.\n */\nexport default abstract class Emitter {\n  instance: ModelInstance;\n  objects: EmittedObject[] = [];\n  alive = 0;\n  currentEmission = 0;\n\n  abstract createObject(): EmittedObject;\n  abstract updateEmission(dt: number): void;\n  abstract emit(): void;\n\n  constructor(instance: ModelInstance) {\n    this.instance = instance;\n  }\n\n  /**\n   * Update this emitter.\n   */\n  update(dt: number): void {\n    // Emit new objects if needed.\n    this.updateEmission(dt);\n\n    const currentEmission = this.currentEmission;\n\n    if (currentEmission >= 1) {\n      for (let i = 0; i < currentEmission; i += 1) {\n        this.emit();\n      }\n    }\n  }\n\n  /**\n   * Clear any emitted objects.\n   */\n  clear(): void {\n    const objects = this.objects;\n\n    for (let i = 0, l = this.alive; i < l; i++) {\n      const object = objects[i];\n\n      object.health = 0;\n    }\n\n    this.currentEmission = 0;\n  }\n\n  emitObject(emitData?: unknown): EmittedObject {\n    const objects = this.objects;\n\n    // If there are no unused objects, create a new one.\n    if (this.alive === objects.length) {\n      objects.push(this.createObject());\n    }\n\n    // Get the first unused object.\n    const object = objects[this.alive];\n\n    object.index = this.alive;\n\n    object.bind(emitData);\n\n    this.alive += 1;\n    this.currentEmission -= 1;\n\n    const scene = <Scene>this.instance.scene;\n\n    scene.emittedObjectUpdater.add(object);\n\n    return object;\n  }\n\n  kill(object: EmittedObject): void {\n    const objects = this.objects;\n\n    this.alive -= 1;\n\n    const otherObject = objects[this.alive];\n\n    objects[object.index] = otherObject;\n    objects[this.alive] = object;\n\n    otherObject.index = object.index;\n    object.index = -1;\n  }\n}\n"
  },
  {
    "path": "src/viewer/genericresource.ts",
    "content": "import { Resource, ResourceData } from './resource';\n\n/**\n * A generic resource.\n */\nexport default class GenericResource extends Resource {\n  data: unknown = null;\n\n  constructor(data: unknown, resourceData: ResourceData) {\n    super(resourceData);\n\n    this.data = data;\n  }\n}\n"
  },
  {
    "path": "src/viewer/gl/clientbuffer.ts",
    "content": "/**\n * A buffer.\n */\nexport default class ClientBuffer {\n  gl: WebGLRenderingContext;\n  buffer: WebGLBuffer;\n  size = 0;\n  arrayBuffer: ArrayBuffer | null = null;\n  byteView: Uint8Array | null = null;\n  floatView: Float32Array | null = null;\n\n  constructor(gl: WebGLRenderingContext, size = 4) {\n    this.gl = gl;\n    this.buffer = <WebGLBuffer>gl.createBuffer();\n\n    this.reserve(size);\n  }\n\n  reserve(size: number): void {\n    if (this.size < size) {\n      const gl = this.gl;\n\n      // Ensure the size is on a 4 byte boundary.\n      this.size = Math.ceil(size / 4) * 4;\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n      gl.bufferData(gl.ARRAY_BUFFER, this.size, gl.DYNAMIC_DRAW);\n\n      this.arrayBuffer = new ArrayBuffer(this.size);\n      this.byteView = new Uint8Array(this.arrayBuffer);\n      this.floatView = new Float32Array(this.arrayBuffer);\n    }\n  }\n\n  bindAndUpdate(size = this.size): void {\n    const gl = this.gl;\n    const byteView = <Uint8Array>this.byteView;\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n    gl.bufferSubData(gl.ARRAY_BUFFER, 0, byteView.subarray(0, size));\n  }\n}\n"
  },
  {
    "path": "src/viewer/gl/clientdatatexture.ts",
    "content": "/**\n * A data texture.\n */\nexport default class ClientDataTexture {\n  gl: WebGLRenderingContext;\n  texture: WebGLTexture;\n  width = 0;\n  height = 0;\n  arrayBuffer = new ArrayBuffer(0);\n  byteView: Uint8Array | null = null;\n  floatView: Float32Array | null = null;\n\n  constructor(gl: WebGLRenderingContext, width = 1, height = 1) {\n    this.gl = gl;\n    this.texture = <WebGLTexture>gl.createTexture();\n\n    gl.bindTexture(gl.TEXTURE_2D, this.texture);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n\n    this.reserve(width, height);\n  }\n\n  reserve(width: number, height: number): void {\n    if (this.width < width || this.height < height) {\n      const gl = this.gl;\n\n      this.width = Math.max(this.width, width);\n      this.height = Math.max(this.height, height);\n\n      gl.bindTexture(gl.TEXTURE_2D, this.texture);\n      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.FLOAT, null);\n\n      this.arrayBuffer = new ArrayBuffer(this.width * this.height * 16);\n      this.byteView = new Uint8Array(this.arrayBuffer);\n      this.floatView = new Float32Array(this.arrayBuffer);\n    }\n  }\n\n  bindAndUpdate(width = this.width, height = this.height): void {\n    const gl = this.gl;\n\n    gl.bindTexture(gl.TEXTURE_2D, this.texture);\n    gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.FLOAT, this.byteView);\n  }\n}\n"
  },
  {
    "path": "src/viewer/gl/datatexture.ts",
    "content": "/**\n * A data texture.\n */\nexport default class DataTexture {\n  gl: WebGLRenderingContext;\n  texture: WebGLTexture;\n  format: number;\n  width = 0;\n  height = 0;\n\n  constructor(gl: WebGLRenderingContext, channels = 4, width = 1, height = 1) {\n    this.gl = gl;\n    this.texture = <WebGLTexture>gl.createTexture();\n    this.format = (channels === 3 ? gl.RGB : gl.RGBA);\n\n    gl.bindTexture(gl.TEXTURE_2D, this.texture);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n\n    this.reserve(width, height);\n  }\n\n  reserve(width: number, height: number): void {\n    if (this.width < width || this.height < height) {\n      const gl = this.gl;\n\n      this.width = Math.max(this.width, width);\n      this.height = Math.max(this.height, height);\n\n      gl.bindTexture(gl.TEXTURE_2D, this.texture);\n      gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.width, this.height, 0, this.format, gl.FLOAT, null);\n    }\n  }\n\n  bindAndUpdate(buffer: Float32Array, width = this.width, height = this.height): void {\n    const gl = this.gl;\n\n    gl.bindTexture(gl.TEXTURE_2D, this.texture);\n    gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, this.format, gl.FLOAT, buffer);\n  }\n\n  bind(unit: number): void {\n    const gl = this.gl;\n\n    gl.activeTexture(gl.TEXTURE0 + unit);\n    gl.bindTexture(gl.TEXTURE_2D, this.texture);\n  }\n}\n"
  },
  {
    "path": "src/viewer/gl/gl.ts",
    "content": "import Texture from '../texture';\nimport ClientBuffer from './clientbuffer';\nimport ClientDataTexture from './clientdatatexture';\nimport DataTexture from './datatexture';\nimport Shader from './shader';\n\n/**\n * A small WebGL utility class.\n * Makes it easier to generate shaders, textures, etc.\n */\nexport default class WebGL {\n  gl: WebGLRenderingContext;\n  currentShader: Shader | null = null;\n  emptyTexture: WebGLTexture;\n  extensions: {[key: string]: unknown } = {};\n\n  constructor(canvas: HTMLCanvasElement, options: WebGLContextAttributes = { alpha: false }) {\n    let gl = canvas.getContext('webgl', options);\n\n    if (!gl) {\n      gl = <WebGLRenderingContext | null>canvas.getContext('experimental-webgl', options);\n    }\n\n    if (!gl) {\n      throw new Error('WebGL: Failed to create a WebGL context!');\n    }\n\n    const twoByTwo = new Uint8ClampedArray(16).fill(255);\n\n    const emptyTexture = <WebGLTexture>gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, emptyTexture);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, twoByTwo);\n\n    this.gl = gl;\n    this.emptyTexture = emptyTexture;\n  }\n\n  /**\n   * Ensures that an extension is available.\n   * \n   * If it is, it will be added to `extensions`.\n   */\n  ensureExtension(name: string): boolean {\n    const ext = this.gl.getExtension(name);\n\n    if (ext) {\n      this.extensions[name] = ext;\n\n      return true;\n    }\n\n    return false;\n  }\n\n  createShader(vertexSource: string, fragmentSource: string): Shader {\n    const gl = this.gl;\n\n    const vertex = <WebGLShader>gl.createShader(gl.VERTEX_SHADER);\n    gl.shaderSource(vertex, vertexSource);\n    gl.compileShader(vertex);\n\n    const fragment = <WebGLShader>gl.createShader(gl.FRAGMENT_SHADER);\n    gl.shaderSource(fragment, fragmentSource);\n    gl.compileShader(fragment);\n\n    const program = <WebGLProgram>gl.createProgram();\n    gl.attachShader(program, vertex);\n    gl.attachShader(program, fragment);\n    gl.linkProgram(program);\n\n    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n      let log = 'Shader failed to link:';\n\n      const vertexLog = gl.getShaderInfoLog(vertex);\n      if (vertexLog && vertexLog.length) {\n        log += ` Vertex shader: ${vertexLog}`;\n      }\n\n      const fragmentLog = gl.getShaderInfoLog(fragment);\n      if (fragmentLog && fragmentLog.length) {\n        log += ` Fragment shader: ${fragmentLog}`;\n      }\n\n      throw new Error(log);\n    }\n\n    return new Shader(this, program);\n  }\n\n  /**\n   * Enables all vertex attribs between [start, end], including start and discluding end.\n   */\n  enableVertexAttribs(start: number, end: number): void {\n    const gl = this.gl;\n\n    for (let i = start; i < end; i++) {\n      gl.enableVertexAttribArray(i);\n    }\n  }\n\n  /**\n   * Disables all vertex attribs between [start, end], including start and discluding end.\n   */\n  disableVertexAttribs(start: number, end: number): void {\n    const gl = this.gl;\n\n    for (let i = start; i < end; i++) {\n      gl.disableVertexAttribArray(i);\n    }\n  }\n\n  /**\n   * Use a shader program.\n   */\n  useShader(shader: Shader): void {\n    if (shader && shader !== this.currentShader) {\n      let oldAttribs = 0;\n      const newAttribs = shader.attribsCount;\n\n      if (this.currentShader) {\n        oldAttribs = this.currentShader.attribsCount;\n      }\n\n      this.gl.useProgram(shader.program);\n\n      if (newAttribs > oldAttribs) {\n        this.enableVertexAttribs(oldAttribs, newAttribs);\n      } else if (newAttribs < oldAttribs) {\n        this.disableVertexAttribs(newAttribs, oldAttribs);\n      }\n\n      this.currentShader = shader;\n    }\n  }\n\n  /**\n   * Bind a texture.\n   * \n   * If the given texture is invalid, a 2x2 black texture will be bound instead.\n   */\n  bindTexture(texture: Texture | undefined | null, unit: number): void {\n    const gl = this.gl;\n\n    gl.activeTexture(gl.TEXTURE0 + unit);\n\n    if (texture) {\n      gl.bindTexture(gl.TEXTURE_2D, texture.webglResource);\n    } else {\n      // Bind an empty texture in case an invalid one was given, to avoid WebGL errors.\n      gl.bindTexture(gl.TEXTURE_2D, this.emptyTexture);\n    }\n  }\n\n  bindTextureAndWrap(texture: Texture | undefined | null, unit: number, wrapS: number, wrapT: number): void {\n    const gl = this.gl;\n\n    gl.activeTexture(gl.TEXTURE0 + unit);\n\n    if (texture) {\n      gl.bindTexture(gl.TEXTURE_2D, texture.webglResource);\n    } else {\n      // Bind an empty texture in case an invalid one was given, to avoid WebGL errors.\n      gl.bindTexture(gl.TEXTURE_2D, this.emptyTexture);\n    }\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);\n  }\n\n  /**\n   * Set the texture wrap and filter values.\n   */\n  setTextureMode(wrapS: number, wrapT: number, magFilter: number, minFilter: number): void {\n    const gl = this.gl;\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);\n  }\n\n  /**\n   * A shortcut for `new ClientBuffer(gl, size)`.\n   */\n  createClientBuffer(size = 4): ClientBuffer {\n    return new ClientBuffer(this.gl, size);\n  }\n\n  /**\n   * A shortcut for `new DataTexture(gl, channels, width, height)`.\n   */\n  createDataTexture(channels = 4, width = 1, height = 1): DataTexture {\n    return new DataTexture(this.gl, channels, width, height);\n  }\n\n  /**\n   * A shortcut for `new ClientDataTexture(gl, width, height)`.\n   */\n  createClientDataTexture(width = 1, height = 1): ClientDataTexture {\n    return new ClientDataTexture(this.gl, width, height);\n  }\n}\n"
  },
  {
    "path": "src/viewer/gl/index.ts",
    "content": "import WebGL from './gl';\nimport Shader from './shader';\nimport ClientBuffer from './clientbuffer';\nimport DataTexture from './datatexture';\nimport ClientDataTexture from './clientdatatexture';\n\nexport default {\n  WebGL,\n  Shader,\n  ClientBuffer,\n  DataTexture,\n  ClientDataTexture,\n};\n"
  },
  {
    "path": "src/viewer/gl/shader.ts",
    "content": "import WebGL from './gl';\n\n/**\n * A wrapper around a WebGL shader program.\n */\nexport default class Shader {\n  webgl: WebGL;\n  program: WebGLProgram;\n  uniforms: {[key: string]: WebGLUniformLocation } = {};\n  attribs: {[key: string]: number } = {};\n  attribsCount = 0;\n\n  constructor(webgl: WebGL, program: WebGLProgram) {\n    this.webgl = webgl;\n    this.program = program;\n\n    const gl = webgl.gl;\n\n    for (let i = 0, l = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); i < l; i++) {\n      const object = gl.getActiveUniform(program, i);\n\n      if (object) {\n        if (object.size === 1) {\n          this.uniforms[object.name] = <WebGLUniformLocation>gl.getUniformLocation(program, object.name);\n        } else {\n          const base = object.name.substr(0, object.name.length - 3);\n\n          for (let index = 0; index < object.size; index++) {\n            const name = base + '[' + index + ']';\n\n            this.uniforms[name] = <WebGLUniformLocation>gl.getUniformLocation(program, name);\n          }\n        }\n      }\n    }\n\n    for (let i = 0, l = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); i < l; i++) {\n      const object = gl.getActiveAttrib(program, i);\n\n      if (object) {\n        this.attribsCount += object.size;\n\n        if (object.size === 1) {\n          this.attribs[object.name] = gl.getAttribLocation(program, object.name);\n        } else {\n          const base = object.name.substr(0, object.name.length - 3);\n\n          for (let index = 0; index < object.size; index++) {\n            const name = base + '[' + index + ']';\n\n            this.attribs[name] = gl.getAttribLocation(program, name);\n          }\n        }\n      }\n    }\n  }\n\n  use(): void {\n    this.webgl.useShader(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/grid.ts",
    "content": "import Cell from './cell';\nimport ModelInstance from './modelinstance';\n\n/**\n * A grid.\n */\nexport default class Grid {\n  x: number;\n  y: number;\n  width: number;\n  depth: number;\n  cellWidth: number;\n  cellDepth: number;\n  columns: number;\n  rows: number;\n  cells: Cell[] = [];\n\n  constructor(x: number, y: number, width: number, depth: number, cellWidth: number, cellDepth: number) {\n    const columns = width / cellWidth;\n    const rows = depth / cellDepth;\n\n    this.x = x;\n    this.y = y;\n    this.width = width;\n    this.depth = depth;\n    this.cellWidth = cellWidth;\n    this.cellDepth = cellDepth;\n    this.columns = columns;\n    this.rows = rows;\n\n    for (let row = 0; row < rows; row++) {\n      for (let column = 0; column < columns; column++) {\n        const left = x + column * cellWidth;\n        const right = left + cellWidth;\n        const bottom = y + row * cellDepth;\n        const top = bottom + cellDepth;\n\n        this.cells[row * columns + column] = new Cell(left, right, bottom, top);\n      }\n    }\n  }\n\n  add(instance: ModelInstance): void {\n    const cells = this.cells;\n    const columns = this.columns;\n    const left = instance.left;\n    const right = instance.right + 1;\n    const bottom = instance.bottom;\n    const top = instance.top + 1;\n\n    if (left !== -1) {\n      for (let y = bottom; y < top; y++) {\n        for (let x = left; x < right; x++) {\n          cells[y * columns + x].add(instance);\n        }\n      }\n    }\n  }\n\n  remove(instance: ModelInstance): void {\n    const cells = this.cells;\n    const columns = this.columns;\n    const left = instance.left;\n    const right = instance.right + 1;\n    const bottom = instance.bottom;\n    const top = instance.top + 1;\n\n    if (left !== -1) {\n      instance.left = -1;\n\n      for (let y = bottom; y < top; y++) {\n        for (let x = left; x < right; x++) {\n          cells[y * columns + x].remove(instance);\n        }\n      }\n    }\n  }\n\n  moved(instance: ModelInstance): void {\n    const cellWidth = this.cellWidth;\n    const cellDepth = this.cellDepth;\n    const bounds = instance.model.bounds;\n    const x = instance.worldLocation[0] + bounds.x - this.x;\n    const y = instance.worldLocation[1] + bounds.y - this.y;\n    const r = bounds.r;\n    const s = instance.worldScale;\n    let left = Math.floor((x - r * s[0]) / cellWidth);\n    let right = Math.floor((x + r * s[0]) / cellWidth);\n    let bottom = Math.floor((y - r * s[1]) / cellDepth);\n    let top = Math.floor((y + r * s[1]) / cellDepth);\n\n    if (right < 0 || left > this.columns - 1 || top < 0 || bottom > this.rows - 1) {\n      // The instance is outside of the grid, so remove it.\n      this.remove(instance);\n    } else {\n      // Clamp the values so they are in the grid.\n      left = Math.max(left, 0);\n      right = Math.min(right, this.columns - 1);\n      bottom = Math.max(bottom, 0);\n      top = Math.min(top, this.rows - 1);\n\n      // If the values actually changed, update the cells.\n      if (left !== instance.left || right !== instance.right || bottom !== instance.bottom || top !== instance.top) {\n        /// TODO: This can be optimized by checking if there are shared cells.\n        ///       That can be done in precisely the same way as done a few lines above, i.e. simple rectangle intersection.\n        this.remove(instance);\n\n        instance.left = left;\n        instance.right = right;\n        instance.bottom = bottom;\n        instance.top = top;\n\n        this.add(instance);\n      }\n    }\n  }\n\n  /**\n   * Removes all of the instances from this grid.\n   */\n  clear(): void {\n    for (const cell of this.cells) {\n      cell.clear();\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlerresource.ts",
    "content": "import { ResourceData, Resource } from './resource';\n\n\nexport type SolverParams ={[key: string]: unknown };\n\n/**\n * A path solver used for resolving fetch paths.\n */\nexport type PathSolver = (src: unknown, params?: SolverParams) => unknown;\n\n/**\n * The data sent to every handler resource as part of the loading process.\n */\nexport type HandlerResourceData = ResourceData & { pathSolver?: PathSolver };\n\n/**\n * A viewer handler resource.\n * \n * Generally speaking handler resources are created via viewer.load().\n */\nexport abstract class HandlerResource extends Resource {\n  pathSolver?: PathSolver;\n\n  constructor(resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    this.pathSolver = resourceData.pathSolver;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/blp/handler.ts",
    "content": "import { BlpImage } from '../../../parsers/blp/image';\nimport isBlp from '../../../parsers/blp/isformat';\nimport Texture from './texture';\n\nexport default {\n  isValidSource(object: unknown): boolean {\n    if (object instanceof BlpImage) {\n      return true;\n    }\n\n    return isBlp(object);\n  },\n  resource: Texture,\n};\n"
  },
  {
    "path": "src/viewer/handlers/blp/texture.ts",
    "content": "import { isPowerOfTwo } from '../../../common/math';\nimport { BlpImage } from '../../../parsers/blp/image';\nimport { HandlerResourceData } from '../../handlerresource';\nimport Texture from '../../texture';\n\n/**\n * A BLP texure handler.\n */\nexport default class BlpTexture extends Texture {\n  constructor(bufferOrImage: ArrayBuffer | BlpImage, resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    let image;\n\n    if (bufferOrImage instanceof BlpImage) {\n      image = bufferOrImage;\n    } else {\n      image = new BlpImage();\n\n      image.load(bufferOrImage);\n    }\n\n    const viewer = this.viewer;\n    const gl = viewer.gl;\n\n    const id = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, id);\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n    const isPOT = isPowerOfTwo(image.width) && isPowerOfTwo(image.height);\n\n    if (!isPOT) {\n      // Required for NPOT textures.\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    }\n\n    const mipmaps = image.mipmaps();\n\n    // If there is one mipmap, or fake mipmaps, or it's an NPOT image, use just the first mipmap. Otherwise load all of them.\n    if (mipmaps === 1 || image.fakeMipmaps() || !isPOT) {\n      const imageData = image.getMipmap(0);\n\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\n      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageData);\n    } else {\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);\n\n      let width = image.width;\n      let height = image.height;\n\n      for (let i = 0; i < mipmaps; i++) {\n        const imageData = image.getMipmap(i);\n\n        // Don't use the image data dimensions directly.\n        // Some JPG mipmaps out there have wrong sizes.\n        // For example the last two mipmaps being 2x1, which messes with GL.\n        gl.texImage2D(gl.TEXTURE_2D, i, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData.data);\n\n        width = Math.ceil(width / 2);\n        height = Math.ceil(height / 2);\n      }\n    }\n\n    this.width = image.width;\n    this.height = image.height;\n    this.webglResource = id;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/dds/handler.ts",
    "content": "import { DdsImage } from '../../../parsers/dds/image';\nimport isDds from '../../../parsers/dds/isformat';\nimport ModelViewer from '../../viewer';\nimport Texture from './texture';\n\nexport default {\n  load(viewer: ModelViewer): void {\n    const webgl = viewer.webgl;\n\n    // Optionally used when decoding mipmaps.\n    if (!webgl.ensureExtension('WEBGL_compressed_texture_s3tc')) {\n      console.warn('DDS: No compressed textures support! This might reduce performance.');\n    }\n  },\n  isValidSource(object: unknown): boolean {\n    if (object instanceof DdsImage) {\n      return true;\n    }\n\n    return isDds(object);\n  },\n  resource: Texture,\n};\n"
  },
  {
    "path": "src/viewer/handlers/dds/texture.ts",
    "content": "import { DdsImage, FOURCC_DXT1, FOURCC_DXT3, FOURCC_DXT5, FOURCC_ATI2 } from '../../../parsers/dds/image';\nimport { HandlerResourceData } from '../../handlerresource';\nimport Texture from '../../texture';\n\n/**\n * A DDS texture handler.\n */\nexport default class DdsTexture extends Texture {\n  constructor(bufferOrImage: ArrayBuffer | DdsImage, resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    let image;\n\n    if (bufferOrImage instanceof DdsImage) {\n      image = bufferOrImage;\n    } else {\n      image = new DdsImage();\n\n      image.load(bufferOrImage);\n    }\n\n    const viewer = this.viewer;\n    const gl = viewer.gl;\n    const webgl = viewer.webgl;\n    const compressedTextures = <WEBGL_compressed_texture_s3tc>webgl.extensions['WEBGL_compressed_texture_s3tc'];\n    const format = image.format;\n    let internalFormat = 0;\n\n    if (compressedTextures) {\n      if (format === FOURCC_DXT1) {\n        internalFormat = compressedTextures.COMPRESSED_RGB_S3TC_DXT1_EXT;\n      } else if (format === FOURCC_DXT3) {\n        internalFormat = compressedTextures.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n      } else if (format === FOURCC_DXT5) {\n        internalFormat = compressedTextures.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n      }\n    }\n\n    const id = gl.createTexture();\n\n    this.width = image.width;\n    this.height = image.height;\n    this.webglResource = id;\n\n    gl.bindTexture(gl.TEXTURE_2D, id);\n\n    const mipmaps = image.mipmaps();\n\n    // DXT1 and ATI2 pixels are two bytes.\n    // This generally doesn't matter, however, when having 1x2 or 2x1 mipmaps, it does.\n    // Therefore set the proper alignment if needed.\n    if (format === FOURCC_DXT1 || format === FOURCC_ATI2) {\n      gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2);\n    }\n\n    for (let i = 0; i < mipmaps; i++) {\n      // Let the GPU handle the compressed data if it supports it.\n      // Otherwise, decode the data on the client.\n      const { width, height, data } = image.getMipmap(i, internalFormat !== 0);\n\n      if (internalFormat) {\n        gl.compressedTexImage2D(gl.TEXTURE_2D, i, internalFormat, width, height, 0, data);\n      } else if (format === FOURCC_DXT1) {\n        gl.texImage2D(gl.TEXTURE_2D, i, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);\n      } else if (format === FOURCC_DXT3) {\n        gl.texImage2D(gl.TEXTURE_2D, i, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);\n      } else if (format === FOURCC_DXT5) {\n        gl.texImage2D(gl.TEXTURE_2D, i, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);\n      } else {\n        gl.texImage2D(gl.TEXTURE_2D, i, gl.LUMINANCE_ALPHA, width, height, 0, gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, data);\n      }\n    }\n\n    // Restore the alignment to the default, in case it changed.\n    gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n    if (mipmaps > 1) {\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);\n    } else {\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/index.ts",
    "content": "import blp from './blp/handler';\nimport dds from './dds/handler';\nimport m3 from './m3/handler';\nimport mdx from './mdx/handler';\nimport tga from './tga/handler';\nimport War3MapViewer from './w3x/viewer';\n\nexport default {\n  blp,\n  dds,\n  m3,\n  mdx,\n  tga,\n  War3MapViewer,\n};\n"
  },
  {
    "path": "src/viewer/handlers/m3/attachment.ts",
    "content": "import AttachmentPoint from '../../../parsers/m3/attachmentpoint';\n\n/**\n * An M3 attachment.\n */\nexport default class M3Attachment {\n  name: string;\n  bone: number;\n\n  constructor(attachment: AttachmentPoint) {\n    this.name = <string>attachment.name.get();\n    this.bone = attachment.bone;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/batch.ts",
    "content": "import M3Region from './region';\nimport { M3StandardMaterial } from './standardmaterial';\n\n/**\n * An M3 batch.\n */\nexport default class M3Batch {\n  region: M3Region;\n  material: M3StandardMaterial;\n\n  constructor(region: M3Region, material: M3StandardMaterial) {\n    this.region = region;\n    this.material = material;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/bone.ts",
    "content": "import Bone from '../../../parsers/m3/bone';\nimport { Uint32AnimationReference, Vector3AnimationReference, Vector4AnimationReference } from '../../../parsers/m3/animationreference';\n\n/**\n * An M3 bone.\n */\nexport default class M3Bone {\n  name: string;\n  parent: number;\n  location: Vector3AnimationReference;\n  rotation: Vector4AnimationReference;\n  scale: Vector3AnimationReference;\n  visibility: Uint32AnimationReference;\n  inhertTranslation: number;\n  inheritScale: number;\n  inheritRotation: number;\n  billboard1: number;\n  billboard2: number;\n  twoDProjection: number;\n  animated: number;\n  inverseKinematics: number;\n  skinned: number;\n  real: number;\n\n  constructor(bone: Bone) {\n    const flags = bone.flags;\n\n    this.name = <string>bone.name.get();\n    this.parent = bone.parent;\n    this.location = bone.location;\n    this.rotation = bone.rotation;\n    this.scale = bone.scale;\n    this.visibility = bone.visibility;\n    this.inhertTranslation = flags & 0x1;\n    this.inheritScale = flags & 0x2;\n    this.inheritRotation = flags & 0x4;\n    this.billboard1 = flags & 0x10;\n    this.billboard2 = flags & 0x40;\n    this.twoDProjection = flags & 0x100;\n    this.animated = flags & 0x200;\n    this.inverseKinematics = flags & 0x400;\n    this.skinned = flags & 0x800;\n    this.real = flags & 0x2000;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/boundingshape.ts",
    "content": "import M3BoundingShape from '../../../parsers/m3/boundingshape';\n\n/**\n * An M3 bounding shape.\n */\nexport default class BoundingShape {\n  bone: number;\n  matrix: Float32Array;\n\n  constructor(boundingshape: M3BoundingShape) {\n    this.bone = boundingshape.bone;\n    this.matrix = boundingshape.matrix;\n    //this.name = bones[boundingshape.bone].name;\n    /*\n    var size = boundingshape.size;\n    var shape;\n\n    if (boundingshape.shape === 0) {\n        shape = gl.createCube(-size[0], -size[1], -size[2], size[0], size[1], size[2]);\n    } else if (boundingshape.shape === 1) {\n        shape = gl.createSphere(0, 0, 0, 9, 9, size[0]);\n    } else {\n        shape = gl.createCylinder(0, 0, 0, size[0], size[1], 9);\n    }\n\n    this.shape = shape;\n    */\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/camera.ts",
    "content": "import Camera from '../../../parsers/m3/camera';\n\n/**\n * An M3 camera.\n */\nexport default class M3Camera {\n  bone: number;\n  name: string;\n\n  constructor(camera: Camera) {\n    this.bone = camera.bone;\n    this.name = <string>camera.name.get();\n\n    // / TODO: Add animated getters, much like the Mdx structures.\n    /*\n    this.fieldOfView = new AnimationReference(reader, readFloat32);\n    this.farClip = new AnimationReference(reader, readFloat32);\n    this.nearClip = new AnimationReference(reader, readFloat32);\n    this.clip2 = new AnimationReference(reader, readFloat32);\n    this.focalDepth = new AnimationReference(reader, readFloat32);\n    this.falloffStart = new AnimationReference(reader, readFloat32);\n    this.falloffEnd = new AnimationReference(reader, readFloat32);\n    this.depthOfField = new AnimationReference(reader, readFloat32);\n    */\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/handler.ts",
    "content": "import Parser from '../../../parsers/m3/model';\nimport isM3 from '../../../parsers/m3/isformat';\nimport ModelViewer from '../../viewer';\nimport Shader from '../../gl/shader';\nimport Model from './model';\nimport standardVert from './shaders/standard.vert';\nimport standardFrag from './shaders/standard.frag';\n\nexport interface M3HandlerObject {\n  standardShaders: Shader[];\n}\n\nexport default {\n  load(viewer: ModelViewer): void {\n    const gl = viewer.gl;\n    const webgl = viewer.webgl;\n    const teamColors = [[255, 3, 3], [0, 66, 255], [28, 230, 185], [84, 0, 129], [255, 252, 1], [254, 138, 14], [32, 192, 0], [229, 91, 176], [149, 150, 151], [126, 191, 241], [16, 98, 70], [78, 42, 4], [40, 40, 40], [0, 0, 0]];\n\n    // Bone textures.\n    if (!webgl.ensureExtension('OES_texture_float')) {\n      throw new Error('M3: No float texture support!');\n    }\n\n    const standardShaders = <Shader[]>[];\n\n    // Load shaders for 1-4 texture coordinate models.\n    for (let i = 0; i < 4; i++) {\n      const shader = webgl.createShader(`#define EXPLICITUV${i}\\n${standardVert}`, standardFrag);\n\n      // Bind the shader and set the team color uniforms.\n      shader.use();\n\n      for (let i = 0; i < 14; i++) {\n        const color = teamColors[i];\n\n        gl.uniform3f(shader.uniforms['u_teamColors[' + i + ']'], color[0] / 255, color[1] / 255, color[2] / 255);\n      }\n\n      standardShaders[i] = shader;\n    }\n\n    const handlerData: M3HandlerObject = { standardShaders };\n\n    viewer.sharedCache.set('m3', handlerData);\n  },\n  isValidSource(object: unknown): boolean {\n    if (object instanceof Parser) {\n      return true;\n    }\n\n    return isM3(object);\n  },\n  resource: Model,\n};\n"
  },
  {
    "path": "src/viewer/handlers/m3/layer.ts",
    "content": "import Reference from '../../../parsers/m3/reference';\nimport Layer from '../../../parsers/m3/layer';\nimport Texture from '../../texture';\nimport Shader from '../../gl/shader';\nimport { M3StandardMaterial, STANDARD_MATERIAL_OFFSET } from './standardmaterial';\nimport M3Model from './model';\nimport M3Texture from './texture';\n\nconst layerTypeToTextureUnit = {\n  diffuse: 1,\n  decal: 2,\n  specular: 3,\n  gloss: 4,\n  emissive: 5,\n  emissive2: 6,\n  evio: 7,\n  evioMask: 8,\n  alphaMask: 9,\n  alphaMask2: 10,\n  normal: 11,\n  heightMap: 12,\n  lightMap: 13,\n  ao: 14,\n};\n\n/**\n * An M3 layer.\n */\nexport default class M3Layer {\n  model: M3Model;\n  material: M3StandardMaterial;\n  index: number;\n  active = 0;\n  layer: Layer | null = null;\n  gl: WebGLRenderingContext;\n  uniformMap: { map: string; enabled: string; op: string; channels: string; teamColorMode: string; invert: string; clampResult: string; uvCoordinate: string; };\n  source = '';\n  texture: M3Texture | null = null;\n  flags = 0;\n  colorChannels = 0;\n  type = '';\n  op = 0;\n  uvCoordinate = 0;\n  textureUnit = 0;\n  invert = 0;\n  clampResult = 0;\n  teamColorMode = 0;\n\n  constructor(material: M3StandardMaterial, index: number, layerReference: Reference, type: string, op: number) {\n    const model = material.model;\n\n    this.model = model;\n    this.material = material;\n    this.gl = material.gl;\n    this.index = index;\n\n    const uniform = 'u_' + type;\n    const settings = uniform + 'LayerSettings.';\n\n    this.uniformMap = {\n      map: uniform + 'Map',\n      enabled: settings + 'enabled',\n      op: settings + 'op',\n      channels: settings + 'channels',\n      teamColorMode: settings + 'teamColorMode',\n      invert: settings + 'invert',\n      clampResult: settings + 'clampResult',\n      uvCoordinate: settings + 'uvCoordinate',\n    };\n\n    // Since Gloss doesn't exist in all versions\n    if (layerReference.entries) {\n      const layer = <Layer>layerReference.first();\n\n      this.layer = layer;\n\n      const pathSolver = model.pathSolver;\n\n      const path = layer.imagePath.get();\n\n      if (path) {\n        const source = (<string>path).toLowerCase();\n\n        if (source.length) {\n          this.source = source;\n          this.active = 1;\n\n          const uvSource = layer.uvSource;\n          const flags = layer.flags;\n\n          this.flags = flags;\n          this.colorChannels = layer.colorChannelSetting;\n\n          this.model = model;\n          this.type = type;\n          this.op = op;\n\n          let uvCoordinate = 0;\n\n          if (uvSource === 1) {\n            uvCoordinate = 1;\n          } else if (uvSource === 9) {\n            uvCoordinate = 2;\n          } else if (uvSource === 10) {\n            uvCoordinate = 3;\n          }\n\n          this.uvCoordinate = uvCoordinate;\n\n          this.textureUnit = layerTypeToTextureUnit[type];\n\n          this.invert = flags & 0x10;\n          this.clampResult = flags & 0x20;\n\n          // I am not sure if the emissive team color mode is even used, since so far combineColors takes care of it.\n          if (type === 'diffuse') {\n            this.teamColorMode = 1;\n          }\n\n          const m3Texture = new M3Texture(!!(flags & 0x4), !!(flags & 0x8));\n\n          model.viewer.load(source, pathSolver)\n            .then((texture) => {\n              if (texture) {\n                m3Texture.texture = <Texture>texture;\n              }\n            });\n\n          this.texture = m3Texture;\n        }\n      }\n    }\n  }\n\n  bind(shader: Shader, textureOverrides: Map<number, Texture>): void {\n    const gl = this.gl;\n    const uniformMap = this.uniformMap;\n    const uniforms = shader.uniforms;\n    const active = this.active;\n\n    gl.uniform1f(uniforms[uniformMap.enabled], active);\n\n    if (active) {\n      const m3Texture = <M3Texture>this.texture;\n      const texture = textureOverrides.get(this.material.index * STANDARD_MATERIAL_OFFSET + this.index) || m3Texture.texture;\n      const textureUnit = this.textureUnit;\n\n      gl.uniform1i(uniforms[uniformMap.map], textureUnit);\n\n      this.model.viewer.webgl.bindTextureAndWrap(texture, textureUnit, m3Texture.wrapS, m3Texture.wrapT);\n\n      gl.uniform1f(uniforms[uniformMap.op], this.op);\n      gl.uniform1f(uniforms[uniformMap.channels], this.colorChannels);\n      gl.uniform1f(uniforms[uniformMap.teamColorMode], this.teamColorMode);\n\n      // Alpha is probably unknown12. Can this be confirmed?\n      // Many of these flags seem to be incorrect\n      // gl.setParameter(uniform + 'multAddAlpha', [this.model.getValue(this.rgbMultiply, sequence, frame), this.model.getValue(this.rgbAdd, sequence, frame), 0]);\n      // gl.setParameter(uniform + 'useAlphaFactor', 0);\n\n      gl.uniform1f(uniforms[uniformMap.invert], this.invert);\n\n      // gl.setParameter(uniform + 'multColor', 0);\n      // gl.setParameter(uniform + 'addColor', 0);\n\n      gl.uniform1f(uniforms[uniformMap.clampResult], this.clampResult);\n\n      // gl.setParameter(uniform + 'useConstantColor', this.flags && 0x400);\n      // gl.setParameter(uniform + 'constantColor', this.model.getValue(this.color, sequence, frame));\n      // gl.setParameter(settings + 'uvSource', this.uvSource);\n\n      gl.uniform1f(uniforms[uniformMap.uvCoordinate], this.uvCoordinate);\n    }\n  }\n\n  unbind(shader: Shader): void {\n    if (this.active) {\n      this.gl.uniform1f(shader.uniforms[this.uniformMap.enabled], 0);\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/model.ts",
    "content": "import Parser from '../../../parsers/m3/model';\nimport M3ParserModel from '../../../parsers/m3/modelheader';\nimport M3ParserDivision from '../../../parsers/m3/division';\nimport StandardMaterial from '../../../parsers/m3/standardmaterial';\nimport Sequence from '../../../parsers/m3/sequence';\nimport Region from '../../../parsers/m3/region';\nimport Bone from '../../../parsers/m3/bone';\nimport Stc from '../../../parsers/m3/stc';\nimport Sts from '../../../parsers/m3/sts';\nimport Stg from '../../../parsers/m3/stg';\nimport AttachmentPoint from '../../../parsers/m3/attachmentpoint';\nimport Camera from '../../../parsers/m3/camera';\nimport Model from '../../model';\nimport { M3StandardMaterial } from './standardmaterial';\nimport M3Bone from './bone';\nimport M3Sequence from './sequence';\nimport M3Sts from './sts';\nimport M3Stc from './stc';\nimport M3Stg from './stg';\nimport M3AttachmentPoint from './attachment';\nimport M3Camera from './camera';\nimport M3Region from './region';\nimport M3ModelInstance from './modelinstance';\nimport M3Batch from './batch';\nimport { HandlerResourceData } from '../../handlerresource';\nimport Division from '../../../parsers/m3/division';\nimport Batch from '../../../parsers/m3/batch';\nimport MaterialReference from '../../../parsers/m3/materialreference';\n\n/**\n * An M3 model.\n */\nexport default class M3Model extends Model {\n  name = '';\n  batches: M3Batch[] = [];\n  materials: [unknown[], M3StandardMaterial[]] = [[], []]; // 2D array for the possibility of adding more material types in the future\n  materialMaps: MaterialReference[] = [];\n  bones: M3Bone[] = [];\n  boneLookup: Uint16Array;\n  sequences: M3Sequence[] = [];\n  sts: M3Sts[] = [];\n  stc: M3Stc[] = [];\n  stg: M3Stg[] = [];\n  attachments: M3AttachmentPoint[] = [];\n  cameras: M3Camera[] = [];\n  regions: M3Region[] = [];\n  initialReference: Float32Array[] = [];\n  elementBuffer: WebGLBuffer | null = null;\n  arrayBuffer: WebGLBuffer | null = null;\n  vertexSize = 0;\n  uvSetCount = 0;\n\n  constructor(bufferOrParser: ArrayBuffer | Parser, resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    let parser;\n\n    if (bufferOrParser instanceof Parser) {\n      parser = bufferOrParser;\n    } else {\n      parser = new Parser();\n\n      parser.load(bufferOrParser);\n    }\n\n    const model = <M3ParserModel>parser.model;\n    const div = <Division>model.divisions.first();\n\n    this.name = <string>model.modelName.get();\n\n    this.setupGeometry(model, div);\n\n    const materialMaps = <MaterialReference[]>model.materialReferences.get();\n\n    this.materialMaps = materialMaps;\n\n    // Create concrete material objects for standard materials\n\n    const standardMaterials = <StandardMaterial[]>model.materials[0].get();\n\n    for (let i = 0, l = standardMaterials.length; i < l; i++) {\n      this.materials[1].push(new M3StandardMaterial(this, i, standardMaterials[i]));\n    }\n\n    // Create concrete batch objects\n    for (const batch of <Batch[]>div.batches.get()) {\n      const regionId = batch.regionIndex;\n      const materialMap = materialMaps[batch.materialReferenceIndex];\n\n      if (materialMap.materialType === 1) {\n        this.batches.push(new M3Batch(this.regions[regionId], this.materials[1][materialMap.materialIndex]));\n      }\n    }\n\n    /*\n    var batchGroups = [[], [], [], [], [], []];\n\n    for (i = 0, l = batches.length; i < l; i++) {\n    var blendMode = batches[i].material.blendMode;\n\n    batchGroups[blendMode].push(batches[i]);\n    }\n\n    function sortByPriority(a, b) {\n    var a = a.material.priority;\n    var b = b.material.priority;\n\n    if (a < b) {\n    return 1;\n    } else if (a == b) {\n    return 0;\n    } else {\n    return -1;\n    }\n    }\n\n    for (i = 0; i < 6; i++) {\n    batchGroups[i].sort(sortByPriority);\n    }\n    */\n    /*\n    // In the EggPortrait model the batches seem to be sorted by blend mode. Is this true for every model?\n    this.batches.sort(function (a, b) {\n    var ba = a.material.blendMode;\n    var bb = b.material.blendMode;\n\n    if (ba < bb) {\n    return -1;\n    } else if (ba == bb) {\n    return 0;\n    } else {\n    return 1;\n    }\n    });\n    */\n\n    // this.batches = batchGroups[0].concat(batchGroups[1]).concat(batchGroups[2]).concat(batchGroups[3]).concat(batchGroups[4]).concat(batchGroups[5]);\n\n    this.initialReference = <Float32Array[]>model.absoluteInverseBoneRestPositions.get();\n\n    for (const bone of <Bone[]>model.bones.get()) {\n      this.bones.push(new M3Bone(bone));\n    }\n\n    this.boneLookup = <Uint16Array>model.boneLookup.get();\n\n    const sequences = model.sequences.get();\n    if (sequences) {\n      for (const sequence of <Sequence[]>sequences) {\n        this.sequences.push(new M3Sequence(sequence));\n      }\n    }\n\n    const stss = model.sts.get();\n    if (stss) {\n      for (const sts of <Sts[]>stss) {\n        this.sts.push(new M3Sts(sts));\n      }\n    }\n\n    const stcs = model.stc.get();\n    if (stcs) {\n      for (const stc of <Stc[]>stcs) {\n        this.stc.push(new M3Stc(stc));\n      }\n    }\n\n    const stgs = model.stg.get();\n    if (stgs) {\n      for (const stg of <Stg[]>stgs) {\n        this.stg.push(new M3Stg(stg, this.sts, this.stc));\n      }\n    }\n\n    this.addGlobalAnims();\n\n    /*\n    if (parser.fuzzyHitTestObjects.length > 0) {\n        for (i = 0, l = parser.fuzzyHitTestObjects.length; i < l; i++) {\n            this.boundingShapes[i] = new M3BoundingShape(parser.fuzzyHitTestObjects[i], parser.bones, gl);\n        }\n    }\n    */\n    /*\n    if (parser.particleEmitters.length > 0) {\n    this.particleEmitters = [];\n \n    for (i = 0, l = parser.particleEmitters.length; i < l; i++) {\n    this.particleEmitters[i] = new M3ParticleEmitter(parser.particleEmitters[i], this);\n    }\n    }\n    */\n\n    const attachmentPoints = model.attachmentPoints.get();\n    if (attachmentPoints) {\n      for (const attachment of <AttachmentPoint[]>attachmentPoints) {\n        this.attachments.push(new M3AttachmentPoint(attachment));\n      }\n    }\n\n    const cameras = model.cameras.get();\n    if (cameras) {\n      for (const camera of <Camera[]>cameras) {\n        this.cameras.push(new M3Camera(camera));\n      }\n    }\n  }\n\n  addInstance(): M3ModelInstance {\n    return new M3ModelInstance(this);\n  }\n\n  setupGeometry(parser: M3ParserModel, div: M3ParserDivision): void {\n    const gl = this.viewer.gl;\n    let uvSetCount = 1;\n    const vertexFlags = parser.vertexFlags;\n\n    if (vertexFlags & 0x40000) {\n      uvSetCount = 2;\n    } else if (vertexFlags & 0x80000) {\n      uvSetCount = 3;\n    } else if (vertexFlags & 0x100000) {\n      uvSetCount = 4;\n    }\n\n    const regions = <Region[]>div.regions.get();\n    let totalElements = 0;\n    const offsets = [];\n\n    for (let i = 0, l = regions.length; i < l; i++) {\n      offsets[i] = totalElements;\n      totalElements += regions[i].triangleIndicesCount;\n    }\n\n    const elementArray = new Uint16Array(totalElements);\n\n    const triangles = <Uint16Array>div.triangles.get();\n\n    for (let i = 0, l = regions.length; i < l; i++) {\n      this.regions.push(new M3Region(this, regions[i], triangles, elementArray, offsets[i]));\n    }\n\n    const vertices = <Uint8Array>parser.vertices.get();\n\n    this.elementBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, elementArray, gl.STATIC_DRAW);\n\n    const arrayBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, arrayBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n    this.arrayBuffer = arrayBuffer;\n    this.vertexSize = (7 + uvSetCount) * 4;\n    this.uvSetCount = uvSetCount;\n  }\n\n  mapMaterial(index: number): M3StandardMaterial {\n    const materialMap = this.materialMaps[index];\n\n    // return this.materials[materialMap.materialType][materialMap.materialIndex];\n    return this.materials[1][materialMap.materialIndex];\n  }\n\n  addGlobalAnims(): void {\n    /*\n    var i, l;\n    var glbirth, glstand, gldeath;\n    var stgs = this.stg;\n    var stg, name;\n \n    for (i = 0, l = stgs.length; i < l; i++) {\n    stg = stgs[i];\n    name = stg.name.toLowerCase(); // Because obviously there will be a wrong case in some model...\n \n    if (name === 'glbirth') {\n    glbirth = stg;\n    } else if (name === 'glstand') {\n    glstand = stg;\n    } else if (name === 'gldeath') {\n    gldeath = stg;\n    }\n    }\n \n    for (i = 0, l = stgs.length; i < l; i++) {\n    stg = stgs[i];\n    name = stg.name.toLowerCase(); // Because obviously there will be a wrong case in some model...\n \n    if (name !== 'glbirth' && name !== 'glstand' && name !== 'gldeath') {\n    if (name.indexOf('birth') !== -1 && glbirth) {\n    stg.stcIndices = stg.stcIndices.concat(glbirth.stcIndices);\n    } else  if (name.indexOf('death') !== -1 && gldeath) {\n    stg.stcIndices = stg.stcIndices.concat(gldeath.stcIndices);\n    } else if (glstand) {\n    stg.stcIndices = stg.stcIndices.concat(glstand.stcIndices);\n    }\n    }\n    }\n    */\n  }\n\n  // getValue(animRef: M3ParserAnimationReference, sequence: number, frame: number) {\n  //   if (sequence !== -1) {\n  //     return this.stg[sequence].getValue(animRef, frame);\n  //   } else {\n  //     return animRef.initValue;\n  //   }\n  // }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/modelinstance.ts",
    "content": "import { mat4 } from 'gl-matrix';\nimport DataTexture from '../../gl/datatexture';\nimport Scene from '../../scene';\nimport ModelInstance from '../../modelinstance';\nimport Texture from '../../texture';\nimport M3Model from './model';\nimport M3Skeleton from './skeleton';\nimport { STANDARD_MATERIAL_OFFSET } from './standardmaterial';\nimport { M3HandlerObject } from './handler';\nimport M3Node from './node';\n\nconst boneHeap = mat4.create();\n\n/**\n * An M3 model instance.\n */\nexport default class M3ModelInstance extends ModelInstance {\n  skeleton: M3Skeleton | null = null;\n  teamColor = 0;\n  vertexColor = new Float32Array([1, 1, 1, 1]);\n  sequence = -1;\n  frame = 0;\n  sequenceLoopMode = 0;\n  sequenceEnded = false;\n  forced = true;\n  boneTexture: DataTexture | null = null;\n\n  constructor(model: M3Model) {\n    super(model);\n\n    this.skeleton = new M3Skeleton(this);\n\n    // This takes care of calling setSequence before the model is loaded.\n    // In this case, this.sequence will be set, but nothing else is changed.\n    // Now that the model is loaded, set it again to do the real work.\n    if (this.sequence !== -1) {\n      this.setSequence(this.sequence);\n    }\n\n    this.boneTexture = new DataTexture(model.viewer.gl, 3, model.boneLookup.length * 4, 1);\n  }\n\n  /**\n   * Override the texture of the layer at the given index in the material at the given index.\n   * \n   * If a texture isn't given, removes the override if there was one.\n   */\n  setTexture(material: number, layer: number, texture?: Texture): void {\n    this.overrideTexture(material * STANDARD_MATERIAL_OFFSET + layer, texture);\n  }\n\n  updateSkeletonAndBoneTexture(dt: number): void {\n    const model = <M3Model>this.model;\n    const viewer = model.viewer;\n    const buffer = viewer.buffer;\n    const boneLookup = model.boneLookup;\n    const skeleton = <M3Skeleton>this.skeleton;\n    const nodes = skeleton.nodes;\n    const bindPose = model.initialReference;\n    const count = boneLookup.length;\n    const isAnimated = this.sequence !== -1;\n    const boneTexture = <DataTexture>this.boneTexture;\n\n    skeleton.update(dt);\n\n    // Ensure there is enough memory for all of the instances data.\n    buffer.reserve(count * 48);\n\n    const floatView = <Float32Array>buffer.floatView;\n    let finalMatrix;\n\n    if (isAnimated) {\n      finalMatrix = boneHeap;\n    } else {\n      finalMatrix = this.worldMatrix;\n    }\n\n    for (let i = 0; i < count; i++) {\n      const offset = i * 12;\n\n      if (isAnimated) {\n        const bone = boneLookup[i];\n\n        // Every bone has to be multiplied by its bind pose counterpart for rendering.\n        finalMatrix = mat4.mul(boneHeap, nodes[bone].worldMatrix, <mat4>bindPose[bone]);\n      }\n\n      floatView[offset + 0] = finalMatrix[0];\n      floatView[offset + 1] = finalMatrix[1];\n      floatView[offset + 2] = finalMatrix[2];\n      floatView[offset + 3] = finalMatrix[4];\n      floatView[offset + 4] = finalMatrix[5];\n      floatView[offset + 5] = finalMatrix[6];\n      floatView[offset + 6] = finalMatrix[8];\n      floatView[offset + 7] = finalMatrix[9];\n      floatView[offset + 8] = finalMatrix[10];\n      floatView[offset + 9] = finalMatrix[12];\n      floatView[offset + 10] = finalMatrix[13];\n      floatView[offset + 11] = finalMatrix[14];\n    }\n\n    boneTexture.bindAndUpdate(floatView, boneTexture.width, 1);\n  }\n\n  override renderOpaque(): void {\n    const model = <M3Model>this.model;\n    const batches = model.batches;\n\n    if (batches.length) {\n      const viewer = model.viewer;\n      const m3Cache = <M3HandlerObject>viewer.sharedCache.get('m3');\n      const gl = viewer.gl;\n      const vertexSize = model.vertexSize;\n      const uvSetCount = model.uvSetCount;\n      const shader = m3Cache.standardShaders[uvSetCount - 1];\n      const attribs = shader.attribs;\n      const uniforms = shader.uniforms;\n      const scene = <Scene>this.scene;\n      const camera = scene.camera;\n      const textureOverrides = this.textureOverrides;\n      const boneTexture = <DataTexture>this.boneTexture;\n\n      shader.use();\n\n      gl.uniform1f(uniforms['u_teamColor'], this.teamColor);\n      gl.uniform4fv(uniforms['u_vertexColor'], this.vertexColor);\n\n      gl.uniformMatrix4fv(uniforms['u_VP'], false, camera.viewProjectionMatrix);\n      gl.uniformMatrix4fv(uniforms['u_MV'], false, camera.viewMatrix);\n\n      gl.uniform3fv(uniforms['u_eyePos'], camera.location);\n      gl.uniform3fv(uniforms['u_lightPos'], scene.lightPosition);\n\n      boneTexture.bind(15);\n      gl.uniform1i(uniforms['u_boneMap'], 15);\n      gl.uniform1f(uniforms['u_vectorSize'], 1 / boneTexture.width);\n      gl.uniform1f(uniforms['u_rowSize'], 1);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, model.arrayBuffer);\n      gl.vertexAttribPointer(attribs['a_position'], 3, gl.FLOAT, false, vertexSize, 0);\n      gl.vertexAttribPointer(attribs['a_weights'], 4, gl.UNSIGNED_BYTE, false, vertexSize, 12);\n      gl.vertexAttribPointer(attribs['a_bones'], 4, gl.UNSIGNED_BYTE, false, vertexSize, 16);\n      gl.vertexAttribPointer(attribs['a_normal'], 4, gl.UNSIGNED_BYTE, false, vertexSize, 20);\n\n      for (let i = 0; i < uvSetCount; i++) {\n        gl.vertexAttribPointer(attribs[`a_uv${i}`], 2, gl.SHORT, false, vertexSize, 24 + i * 4);\n      }\n\n      gl.vertexAttribPointer(attribs['a_tangent'], 4, gl.UNSIGNED_BYTE, false, vertexSize, 24 + uvSetCount * 4);\n\n      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.elementBuffer);\n\n      for (const batch of batches) {\n        const material = batch.material;\n        const region = batch.region;\n\n        material.bind(shader, textureOverrides);\n\n        region.render(shader);\n\n        material.unbind(shader); // This is required to not use by mistake layers from this material that were bound and are not overwritten by the next material\n      }\n    }\n  }\n\n  override updateAnimations(dt: number): void {\n    const sequenceId = this.sequence;\n\n    if (sequenceId !== -1) {\n      const model = <M3Model>this.model;\n      const sequence = model.sequences[sequenceId];\n      const interval = sequence.interval;\n\n      this.frame += dt * 1000;\n\n      if (this.frame > interval[1]) {\n        if ((this.sequenceLoopMode === 0 && !(sequence.flags & 0x1)) || this.sequenceLoopMode === 2) {\n          this.frame = interval[0];\n        } else {\n          this.frame = interval[1];\n        }\n\n        this.sequenceEnded = true;\n      } else {\n        this.sequenceEnded = false;\n      }\n    }\n\n    if (this.forced || sequenceId !== -1) {\n      this.forced = false;\n\n      this.updateSkeletonAndBoneTexture(dt);\n    }\n  }\n\n  setTeamColor(id: number): this {\n    this.teamColor = id;\n\n    return this;\n  }\n\n  setVertexColor(color: Uint8Array): this {\n    this.vertexColor.set(color);\n\n    return this;\n  }\n\n  setSequence(id: number): this {\n    const model = <M3Model>this.model;\n    this.sequence = id;\n    this.frame = 0;\n\n    if (id < -1 || id > model.sequences.length - 1) {\n      id = -1;\n\n      this.sequence = id;\n    }\n\n    // Do a forced update, so non-animated data can be skipped in future updates\n    this.forced = true;\n\n    return this;\n  }\n\n  setSequenceLoopMode(mode: number): this {\n    this.sequenceLoopMode = mode;\n\n    return this;\n  }\n\n  getAttachment(id: number): M3Node | undefined {\n    const model = <M3Model>this.model;\n    const attachment = model.attachments[id];\n\n    if (attachment) {\n      return (<M3Skeleton>this.skeleton).nodes[attachment.bone];\n    }\n\n    return;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/node.ts",
    "content": "import { quat } from 'gl-matrix';\nimport { SkeletalNode } from '../../skeletalnode';\n\n/**\n * An M3 node.\n */\nexport default class M3Node extends SkeletalNode {\n  override convertBasis(rotation: quat): void {\n    const halfPI = Math.PI / 2;\n\n    quat.rotateZ(rotation, rotation, halfPI);\n    quat.rotateY(rotation, rotation, -halfPI);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/region.ts",
    "content": "import M3ParserRegion from '../../../parsers/m3/region';\nimport Shader from '../../gl/shader';\nimport M3Model from './model';\n\n/**\n * An M3 region.\n */\nexport default class M3Region {\n  gl: WebGLRenderingContext;\n  firstBoneLookupIndex: number;\n  boneWeightPairsCount: number;\n  offset: number;\n  verticesCount: number;\n  elements: number;\n\n  constructor(model: M3Model, region: M3ParserRegion, triangles: Uint16Array, elementArray: Uint16Array, offset: number) {\n    const firstVertexIndex = region.firstVertexIndex;\n    const triangleIndicesCount = region.triangleIndicesCount;\n    const firstTriangleIndex = region.firstTriangleIndex;\n\n    // Note for implementors: the one original vertex indices array could be used with access to the base-vertex draw elements function.\n    // See https://www.opengl.org/sdk/docs/man3/xhtml/glDrawElementsBaseVertex.xml\n    // firstTriangleIndex is the indices offset.\n    // firstVertexIndex is the base vertex.\n    for (let i = 0; i < triangleIndicesCount; i++) {\n      elementArray[offset + i] = triangles[firstTriangleIndex + i] + firstVertexIndex;\n    }\n\n    this.gl = model.viewer.gl;\n    this.firstBoneLookupIndex = region.firstBoneLookupIndex;\n    this.boneWeightPairsCount = region.boneWeightPairsCount;\n    this.offset = offset * 2;\n    this.verticesCount = region.verticesCount;\n    this.elements = triangleIndicesCount;\n  }\n\n  render(shader: Shader): void {\n    const gl = this.gl;\n\n    gl.uniform1f(shader.uniforms['u_firstBoneLookupIndex'], this.firstBoneLookupIndex);\n    gl.uniform1f(shader.uniforms['u_boneWeightPairsCount'], this.boneWeightPairsCount);\n\n    gl.drawElements(gl.TRIANGLES, this.elements, gl.UNSIGNED_SHORT, this.offset);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/sd.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { clamp, lerp } from '../../../common/math';\nimport { AnimationReference } from '../../../parsers/m3/animationreference';\nimport M3ParserSd from '../../../parsers/m3/sd';\n\nconst vectorHeap = vec3.create();\nconst quatHeap = quat.create();\n\n/**\n * Sequence data.\n */\nclass M3Sd {\n  keys: Int32Array;\n  values: vec3[] | quat[] | number[];\n  biggestKey: number;\n\n  constructor(sd: M3ParserSd) {\n    this.keys = <Int32Array>sd.keys.get();\n    this.values = <vec3[]>sd.values.get(); // Fake typecasting to avoid a TS error.\n    this.biggestKey = sd.biggestKey;\n  }\n}\n\n/**\n * A sequence data container.\n */\nexport default class M3SdContainer {\n  sd: M3Sd[] = [];\n\n  addSds(sds: M3ParserSd[]): void {\n    for (const sd of sds) {\n      this.sd.push(new M3Sd(sd));\n    }\n  }\n\n  getValueUnsafe(index: number, animationReference: AnimationReference, frame: number, runsConcurrent: number): number | vec3 | quat | Uint8Array | null {\n    const sd = this.sd[index];\n\n    if (runsConcurrent) {\n      frame = frame % sd.biggestKey;\n    }\n\n    const keys = sd.keys;\n    const values = sd.values;\n\n    // getInterval\n    let a = keys.length;\n    let b = 0;\n\n    while (b !== keys.length && frame > keys[b]) {\n      a = b;\n      b++;\n    }\n\n    const length = keys.length;\n\n    if (a === length) {\n      if (b === length) {\n        return animationReference.initValue;\n      } else {\n        return values[b];\n      }\n    }\n\n    if (b === length || a >= b) {\n      return values[a];\n    }\n\n    const t = clamp((frame - keys[a]) / (keys[b] - keys[a]), 0, 1);\n    const va = values[a];\n    const vb = values[b];\n    const interpolationType = animationReference.interpolationType;\n    const fakeVa = <vec3>va; /// UGLY!!!\n\n    if (fakeVa.length === 4) {\n      if (interpolationType === 0) {\n        return quat.copy(quatHeap, <quat>va);\n      } else {\n        return quat.slerp(quatHeap, <quat>va, <quat>vb, t);\n      }\n    } else if (fakeVa.length === 3) {\n      if (interpolationType === 0) {\n        return vec3.copy(vectorHeap, <vec3>va);\n      } else {\n        return vec3.lerp(vectorHeap, <vec3>va, <vec3>vb, t);\n      }\n    } else {\n      if (interpolationType === 0) {\n        return <number>va;\n      } else {\n        return lerp(<number>va, <number>vb, t);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/sequence.ts",
    "content": "import M3ParserSequence from '../../../parsers/m3/sequence';\nimport M3ParserBoundingSphere from '../../../parsers/m3/boundingsphere';\n\n/**\n * An M3 sequence.\n */\nexport default class M3Sequence {\n  name: string;\n  interval: Uint32Array;\n  movementSpeed: number;\n  frequency: number;\n  boundingSphere: M3ParserBoundingSphere;\n  flags: number;\n\n  constructor(sequence: M3ParserSequence) {\n    this.name = <string>sequence.name.get();\n    this.interval = sequence.interval;\n    this.movementSpeed = sequence.movementSpeed;\n    this.frequency = sequence.frequency;\n    this.boundingSphere = sequence.boundingSphere;\n    this.flags = sequence.flags;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/shaders/layers.glsl.ts",
    "content": "const shader = `\nvarying vec3 v_normal;\nvarying vec4 v_uv[2];\nvarying vec3 v_lightDir;\n// varying vec3 v_eyeVec;\nvarying vec3 v_halfVec;\nvarying vec3 v_teamColor;\nvarying vec4 v_vertexColor;\n\nstruct LayerSettings {\n  bool enabled;\n  float op;\n  float channels;\n  float teamColorMode;\n  // vec3 multAddAlpha;\n  // bool useAlphaFactor;\n  bool invert;\n  // bool multColor;\n  // bool addColor;\n  bool clampResult;\n  // bool useConstantColor;\n  // vec4 constantColor;\n  // float uvSource;\n  float uvCoordinate;\n  // float fresnelMode;\n  // float fresnelTransformMode;\n  // mat4 fresnelTransform;\n  // bool fresnelClamp;\n  // vec3 fresnelExponentBiasScale;\n};\n\nuniform float u_specularity;\nuniform float u_specMult;\nuniform float u_emisMult;\nuniform vec4 u_lightAmbient;\n\nuniform LayerSettings u_diffuseLayerSettings;\nuniform sampler2D u_diffuseMap;\nuniform LayerSettings u_decalLayerSettings;\nuniform sampler2D u_decalMap;\nuniform LayerSettings u_specularLayerSettings;\nuniform sampler2D u_specularMap;\nuniform LayerSettings u_glossLayerSettings;\nuniform sampler2D u_glossMap;\nuniform LayerSettings u_emissiveLayerSettings;\nuniform sampler2D u_emissiveMap;\nuniform LayerSettings u_emissive2LayerSettings;\nuniform sampler2D u_emissive2Map;\nuniform LayerSettings u_evioLayerSettings;\nuniform sampler2D u_evioMap;\nuniform LayerSettings u_evioMaskLayerSettings;\nuniform sampler2D u_evioMaskMap;\nuniform LayerSettings u_alphaLayerSettings;\nuniform sampler2D u_alphaMap;\nuniform LayerSettings u_alphaMaskLayerSettings;\nuniform sampler2D u_alphaMaskMap;\nuniform LayerSettings u_normalLayerSettings;\nuniform sampler2D u_normalMap;\nuniform LayerSettings u_heightLayerSettings;\nuniform sampler2D u_heightMap;\nuniform LayerSettings u_lightMapLayerSettings;\nuniform sampler2D u_lightMapMap;\nuniform LayerSettings u_aoLayerSettings;\nuniform sampler2D u_aoMap;\n\n#define SPECULAR_RGB 0.0\n#define SPECULAR_A_ONLY 1.0\n\n#define FRESNELMODE_NONE 0.0\n#define FRESNELMODE_STANDARD 1.0\n#define FRESNELMODE_INVERTED 2.0\n\n#define FRESNELTRANSFORM_NONE 0.0\n#define FRESNELTRANSFORM_SIMPLE 1.0\n#define FRESNELTRANSFORM_NORMALIZED 2.0\n\n#define UVMAP_EXPLICITUV0 0.0\n#define UVMAP_EXPLICITUV1 1.0\n#define UVMAP_REFLECT_CUBICENVIO 2.0\n#define UVMAP_REFLECT_SPHERICALENVIO 3.0\n#define UVMAP_PLANARLOCALZ 4.0\n#define UVMAP_PLANARWORLDZ 5.0\n#define UVMAP_PARTICLE_FLIPBOOK 6.0\n#define UVMAP_CUBICENVIO 7.0\n#define UVMAP_SPHERICALENVIO 8.0\n#define UVMAP_EXPLICITUV2 9.0\n#define UVMAP_EXPLICITUV3 10.0\n#define UVMAP_PLANARLOCALX 11.0\n#define UVMAP_PLANARLOCALY 12.0\n#define UVMAP_PLANARWORLDX 13.0\n#define UVMAP_PLANARWORLDY 14.0\n#define UVMAP_SCREENSPACE 15.0\n#define UVMAP_TRIPLANAR_LOCAL 16.0\n#define UVMAP_TRIPLANAR_WORLD 17.0\n#define UVMAP_TRIPLANAR_WORLD_LOCAL_Z 18.0\n\n#define CHANNELSELECT_RGB 0.0\n#define CHANNELSELECT_RGBA 1.0\n#define CHANNELSELECT_A 2.0\n#define CHANNELSELECT_R 3.0\n#define CHANNELSELECT_G 4.0\n#define CHANNELSELECT_B 5.0\n\n#define TEAMCOLOR_NONE 0.0\n#define TEAMCOLOR_DIFFUSE 1.0\n#define TEAMCOLOR_EMISSIVE 2.0\n\n#define LAYEROP_MOD 0.0\n#define LAYEROP_MOD2X 1.0\n#define LAYEROP_ADD 2.0\n#define LAYEROP_LERP 3.0\n#define LAYEROP_TEAMCOLOR_EMISSIVE_ADD 4.0\n#define LAYEROP_TEAMCOLOR_DIFFUSE_ADD 5.0\n#define LAYEROP_ADD_NO_ALPHA 6.0\n\n// float calculateFresnelTerm(vec3 normal, vec3 eyeToVertex, float exponent, mat4 fresnelTransform, float fresnelTransformMode, bool fresnelClamp) {\n//   vec3 fresnelDir = eyeToVertex;\n//   float result;\n\n//   if (fresnelTransformMode != FRESNELTRANSFORM_NONE) {\n//     fresnelDir = (fresnelTransform * vec4(fresnelDir, 1.0)).xyz;\n\n//     if (fresnelTransformMode == FRESNELTRANSFORM_NORMALIZED) {\n//       fresnelDir = normalize(fresnelDir);\n//     }\n//   }\n\n//   if (fresnelClamp) {\n//     result = 1.0 - clamp(-dot(normal, fresnelDir), 0.0, 1.0);\n//   } else {\n//     result = 1.0 - abs(dot(normal, fresnelDir));\n//   }\n\n//   result = max(result, 0.0000001);\n\n//   return pow(result, exponent);\n// }\n\nvec3 combineLayerColor(vec4 color, vec3 result, LayerSettings layerSettings) {\n  if (layerSettings.op == LAYEROP_MOD) {\n    result *= color.rgb;\n  } else if (layerSettings.op == LAYEROP_MOD2X) {\n    result *= color.rgb * 2.0;\n  } else if (layerSettings.op == LAYEROP_ADD) {\n    result += color.rgb * color.a;\n  } else if (layerSettings.op == LAYEROP_ADD_NO_ALPHA) {\n    result += color.rgb;\n  } else if (layerSettings.op == LAYEROP_LERP) {\n    result = mix(result, color.rgb, color.a);\n  } else if (layerSettings.op == LAYEROP_TEAMCOLOR_EMISSIVE_ADD) {\n    result += color.a * v_teamColor;\n  } else if (layerSettings.op == LAYEROP_TEAMCOLOR_DIFFUSE_ADD) {\n    result += color.a * v_teamColor;\n  }\n\n  return result;\n}\n\nvec4 chooseChannel(float channel, vec4 texel) {\n  if (channel == CHANNELSELECT_R) {\n    texel = texel.rrrr;\n  } else if (channel == CHANNELSELECT_G) {\n    texel = texel.gggg;\n  } else if (channel == CHANNELSELECT_B) {\n    texel = texel.bbbb;\n  } else if (channel == CHANNELSELECT_A) {\n    texel = texel.aaaa;\n  } else if (channel == CHANNELSELECT_RGB) {\n    texel.a = 1.0;\n  }\n\n  return texel;\n}\n\nvec2 getUV(LayerSettings layerSettings) {\n  if (layerSettings.uvCoordinate == 1.0) {\n    return v_uv[0].zw;\n  } else if (layerSettings.uvCoordinate == 2.0) {\n    return v_uv[1].xy;\n  } else if (layerSettings.uvCoordinate == 3.0) {\n    return v_uv[1].zw;\n  }\n\n  return v_uv[0].xy;\n}\n\nvec4 sampleLayer(sampler2D layer, LayerSettings layerSettings) {\n  // if (layerSettings.useConstantColor) {\n  //   return layerSettings.constantColor;\n  // }\n\n  return texture2D(layer, getUV(layerSettings));\n}\n\nvec4 computeLayerColor(sampler2D layer, LayerSettings layerSettings) {\n  vec4 color = sampleLayer(layer, layerSettings);\n\n  // if (layerSettings.useMask) {\n  //   result *= mask;\n  // }\n\n  vec4 result = chooseChannel(layerSettings.channels, color);\n\n  // if (layerSettings.useAlphaFactor) {\n  //   result.a *= layerSettings.multiplyAddAlpha.z;\n  // }\n\n  if (layerSettings.teamColorMode == TEAMCOLOR_DIFFUSE) {\n    result = vec4(mix(v_teamColor, result.rgb, color.a), 1.0);\n  } else if (layerSettings.teamColorMode == TEAMCOLOR_EMISSIVE) {\n    result = vec4(mix(v_teamColor, result.rgb, color.a), 1.0);\n  }\n\n  if (layerSettings.invert) {\n    result = vec4(1.0) - result;\n  }\n\n  // if (layerSettings.multiplyEnable) {\n  //   result *= layerSettings.multiplyAddAlpha.x;\n  // }\n\n  // if (layerSettings.addEnable) {\n  //   result += layerSettings.multiplyAddAlpha.y;\n  // }\n\n  if (layerSettings.clampResult) {\n    result = clamp(result, 0.0, 1.0);\n  }\n\n  // if (layerSettings.fresnelMode != FRESNELMODE_NONE) {\n  //   float fresnelTerm = calculateFresnelTerm(v_normal, v_eyeVec, layerSettings.fresnelExponentBiasScale.x, layerSettings.fresnelTransform, layerSettings.fresnelTransformMode, layerSettings.fresnelClamp);\n    \n  //   if (layerSettings.fresnelMode == FRESNELMODE_INVERTED) {\n  //     fresnelTerm = 1.0 - fresnelTerm;\n  //   }\n    \n  //   fresnelTerm = clamp(fresnelTerm * layerSettings.fresnelExponentBiasScale.z + layerSettings.fresnelExponentBiasScale.y, 0.0, 1.0);\n    \n  //   result *= fresnelTerm;\n  // }\n\n  return result;\n}\n\nvec3 decodeNormal(sampler2D map) {\n  vec4 texel = texture2D(map, v_uv[0].xy);\n  vec3 normal;\n\n  normal.xy = 2.0 * texel.wy - 1.0;\n  normal.z = sqrt(max(0.0, 1.0 - dot(normal.xy, normal.xy)));\n\n  return normal;\n}\n\nvec4 computeSpecular(sampler2D specularMap, LayerSettings layerSettings, float specularity, float specMult, vec3 normal) {\n  vec4 color;\n\n  if (layerSettings.enabled) {\n    color = computeLayerColor(specularMap, layerSettings);\n  } else {\n    color = vec4(0);\n  }\n\n  float factor = pow(max(-dot(v_halfVec, normal), 0.0), specularity) * specMult;\n\n  return color * factor;\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/m3/shaders/standard.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\nimport layers from './layers.glsl';\n\nconst shader = `\n${precision}\n\n${layers}\n\nvoid main() {\n  vec3 color;\n  vec4 final = u_lightAmbient;\n  vec3 normal;\n  vec3 lightMapDiffuse;\n\n  if (u_normalLayerSettings.enabled) {\n    normal = decodeNormal(u_normalMap);\n  } else {\n    normal = v_normal;\n  }\n\n  float lambertFactor = max(dot(normal, v_lightDir), 0.0);\n\n  if (lambertFactor > 0.0) {\n    if (u_diffuseLayerSettings.enabled) {\n      vec4 diffuseColor = computeLayerColor(u_diffuseMap, u_diffuseLayerSettings);\n\n      color = combineLayerColor(diffuseColor, color, u_diffuseLayerSettings);\n    }\n\n    if (u_decalLayerSettings.enabled) {\n      vec4 decalColor = computeLayerColor(u_decalMap, u_decalLayerSettings);\n\n      color = combineLayerColor(decalColor, color, u_decalLayerSettings);\n    }\n\n    vec4 specularColor = computeSpecular(u_specularMap, u_specularLayerSettings, u_specularity, u_specMult, normal);\n\n    if (u_lightMapLayerSettings.enabled) {\n      vec4 lightMapColor = computeLayerColor(u_lightMapMap, u_lightMapLayerSettings) * 2.0;\n\n      lightMapDiffuse = lightMapColor.rgb;\n    }\n\n    // final.rgb = color * lightMapDiffuse + specularColor.rgb;\n    final.rgb = (color + specularColor.rgb) * lambertFactor;\n\n    bool addEmissive = false;\n    vec3 emissiveColor;\n    vec4 tempColor;\n\n    if (u_emissiveLayerSettings.enabled) {\n      tempColor = computeLayerColor(u_emissiveMap, u_emissiveLayerSettings);\n\n      if (u_emissiveLayerSettings.op == LAYEROP_MOD || u_emissiveLayerSettings.op == LAYEROP_MOD2X || u_emissiveLayerSettings.op == LAYEROP_LERP) {\n        final.rgb = combineLayerColor(tempColor, final.rgb, u_emissiveLayerSettings);\n      } else {\n        emissiveColor = combineLayerColor(tempColor, emissiveColor, u_emissiveLayerSettings);\n        addEmissive = true;\n      }\n    }\n\n    if (u_emissive2LayerSettings.enabled) {\n      tempColor = computeLayerColor(u_emissive2Map, u_emissive2LayerSettings);\n\n      if (!addEmissive && (u_emissive2LayerSettings.op == LAYEROP_MOD || u_emissive2LayerSettings.op == LAYEROP_MOD2X || u_emissive2LayerSettings.op == LAYEROP_LERP)) {\n        final.rgb = combineLayerColor(tempColor, final.rgb, u_emissive2LayerSettings);\n      } else {\n        emissiveColor = combineLayerColor(tempColor, emissiveColor, u_emissive2LayerSettings);\n        addEmissive = true;\n      }\n    }\n\n    if (addEmissive) {\n      final.rgb += emissiveColor * u_emisMult;\n    }\n  }\n\n  gl_FragColor = final * v_vertexColor;\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/m3/shaders/standard.vert.ts",
    "content": "import boneTexture from '../../shaders/bonetexture.glsl';\n\nconst shader = `\nuniform mat4 u_VP;\nuniform mat4 u_MV;\nuniform vec3 u_eyePos;\nuniform vec3 u_lightPos;\nuniform float u_firstBoneLookupIndex;\nuniform float u_boneWeightPairsCount;\nuniform vec3 u_teamColors[14];\nuniform float u_teamColor;\nuniform vec4 u_vertexColor;\n\nattribute vec3 a_position;\nattribute vec4 a_normal;\nattribute vec2 a_uv0;\n\n#ifdef EXPLICITUV1\nattribute vec2 a_uv1;\n#endif\n#ifdef EXPLICITUV2\nattribute vec2 a_uv1, a_uv2;\n#endif\n#ifdef EXPLICITUV3\nattribute vec2 a_uv1, a_uv2, a_uv3;\n#endif\n\nattribute vec4 a_tangent;\nattribute vec4 a_bones;\nattribute vec4 a_weights;\n\nvarying vec3 v_normal;\nvarying vec4 v_uv[2]; // Pack 4 vec2 in 2 vec4, to reduce the varyings count\nvarying vec3 v_lightDir;\n// varying vec3 v_eyeVec;\nvarying vec3 v_halfVec;\nvarying vec3 v_teamColor;\nvarying vec4 v_vertexColor;\n\n${boneTexture}\n\nvec3 TBN(vec3 vector, vec3 tangent, vec3 binormal, vec3 normal) {\n  return vec3(dot(vector, tangent), dot(vector, binormal), dot(vector, normal));\n}\n\nvec4 decodeVector(vec4 v) {\n  return ((v / 255.0) * 2.0) - 1.0;\n}\n\nvoid transform(inout vec3 position, inout vec3 normal, inout vec3 tangent, inout vec3 binormal, vec4 bones, vec4 weights) {\n  if (u_boneWeightPairsCount > 0.0) {\n    mat4 bone;\n\n    if (u_boneWeightPairsCount == 1.0) {\n      bone = fetchMatrix(bones[0], 0.0);\n    } else {\n      bone += fetchMatrix(bones[0], 0.0) * weights[0];\n      bone += fetchMatrix(bones[1], 0.0) * weights[1];\n      bone += fetchMatrix(bones[2], 0.0) * weights[2];\n      bone += fetchMatrix(bones[3], 0.0) * weights[3];\n    }\n\n    position = vec3(bone * vec4(position, 1.0));\n    normal = mat3(bone) * normal;\n    tangent = vec3(bone * vec4(tangent, 0.0));\n    binormal = vec3(bone * vec4(binormal, 0.0));\n  }\n}\n\nvoid main() {\n  vec4 decodedNormal = decodeVector(a_normal);\n\n  vec3 position = a_position;\n  vec3 normal = decodedNormal.xyz;\n  vec3 tangent = vec3(decodeVector(a_tangent));\n  vec3 binormal = cross(normal, tangent) * decodedNormal.w;\n\n  transform(position, normal, tangent, binormal, a_bones + u_firstBoneLookupIndex, a_weights / 255.0);\n\n  vec3 position_mv = vec3(u_MV * vec4(position, 1));\n\n  mat3 mv = mat3(u_MV);\n  vec3 t = normalize(mv * tangent);\n  vec3 b = normalize(mv * binormal);\n  vec3 n = normalize(mv * normal);\n\n  vec3 lightDir = normalize(u_lightPos - position_mv);\n\n  v_lightDir = normalize(TBN(lightDir, t, b, n));\n\n  vec3 eyeVec = normalize(u_eyePos - position_mv);\n  vec3 halfVec = normalize(eyeVec - u_lightPos);\n\n  // v_eyeVec = TBN(eyeVec, t, b, n);\n  v_halfVec = TBN(halfVec, t, b, n);\n\n  v_normal = n;\n\n  vec4 uv0, uv1;\n\n  uv0.xy = a_uv0 / 2048.0;\n\n  #ifdef EXPLICITUV1\n  uv0.zw = a_uv1 / 2048.0;\n  #endif\n\n  #ifdef EXPLICITUV2\n  uv0.zw = a_uv1 / 2048.0;\n  uv1.xy = a_uv2 / 2048.0;\n  #endif\n\n  #ifdef EXPLICITUV3\n  uv0.zw = a_uv1 / 2048.0;\n  uv1.xy = a_uv2 / 2048.0;\n  uv1.zw = a_uv3 / 2048.0;\n  #endif\n\n  v_uv[0] = uv0;\n  v_uv[1] = uv1;\n\n  v_teamColor = u_teamColors[int(u_teamColor)];\n  v_vertexColor = u_vertexColor;\n\n  gl_Position = u_VP * vec4(position, 1.0);\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/m3/skeleton.ts",
    "content": "import { AnimationReference } from '../../../parsers/m3/animationreference';\nimport { createSkeletalNodes } from '../../skeletalnode';\nimport M3Node from './node';\nimport M3ModelInstance from './modelinstance';\nimport M3Bone from './bone';\nimport M3Sts from './sts';\nimport M3Stc from './stc';\nimport M3Stg from './stg';\nimport M3Model from './model';\nimport { quat, vec3 } from 'gl-matrix';\n\n/**\n * M3 skeleton.\n */\nexport default class M3Skeleton {\n  nodes: M3Node[];\n  worldMatrices: Float32Array;\n  instance: M3ModelInstance;\n  modelNodes: M3Bone[];\n  initialReference: Float32Array[];\n  sts: M3Sts[];\n  stc: M3Stc[];\n  stg: M3Stg[];\n  boneLookup: Uint16Array;\n\n  constructor(instance: M3ModelInstance) {\n    const model = <M3Model>instance.model;\n    const bones = model.bones;\n    const boneLookup = model.boneLookup;\n    const sharedNodeData = createSkeletalNodes(bones.length, M3Node);\n    const nodes = sharedNodeData.nodes;\n\n    this.nodes = nodes;\n    this.worldMatrices = sharedNodeData.worldMatrices;\n    this.instance = instance;\n    this.modelNodes = bones;\n    this.initialReference = model.initialReference;\n    this.sts = model.sts;\n    this.stc = model.stc;\n    this.stg = model.stg;\n    this.boneLookup = boneLookup;\n\n    // Set the bone parent references\n    for (let i = 0, l = bones.length; i < l; i++) {\n      const bone = bones[i];\n\n      if (bone.parent === -1) {\n        nodes[i].parent = instance;\n      } else {\n        nodes[i].parent = nodes[bone.parent];\n      }\n\n      if (bone.billboard1) {\n        nodes[i].billboarded = true;\n      }\n    }\n  }\n\n  update(dt: number): void {\n    const instance = this.instance;\n    const nodes = this.nodes;\n    const modelNodes = this.modelNodes;\n\n    for (let i = 0, l = nodes.length; i < l; i++) {\n      const node = nodes[i];\n      const modelNode = modelNodes[i];\n\n      this.getValue4(<Float32Array>node.localRotation, modelNode.rotation, instance);\n      this.getValue3(<Float32Array>node.localLocation, modelNode.location, instance);\n      this.getValue3(<Float32Array>node.localScale, modelNode.scale, instance);\n\n      node.recalculateTransformation(instance);\n\n      // Recalculate and update child nodes.\n      // Note that this only affects normal nodes such as instances, and not skeletal nodes.\n      for (const child of node.children) {\n        child.recalculateTransformation();\n        child.update(dt);\n      }\n    }\n  }\n\n  getValueUnsafe(animRef: AnimationReference, instance: M3ModelInstance): number | vec3 | quat | Uint8Array | null {\n    const sequence = instance.sequence;\n\n    if (sequence !== -1) {\n      return this.stg[sequence].getValueUnsafe(animRef, instance);\n    }\n\n    return animRef.initValue;\n  }\n\n  getValue(animRef: AnimationReference, instance: M3ModelInstance): number {\n    return <number>this.getValueUnsafe(animRef, instance);\n  }\n\n  getValue2(out: Float32Array, animRef: AnimationReference, instance: M3ModelInstance): Float32Array {\n    const unsafeHeap = <Float32Array>this.getValueUnsafe(animRef, instance);\n\n    out[0] = unsafeHeap[0];\n    out[1] = unsafeHeap[1];\n\n    return out;\n  }\n\n  getValue3(out: Float32Array, animRef: AnimationReference, instance: M3ModelInstance): Float32Array {\n    const unsafeHeap = <Float32Array>this.getValueUnsafe(animRef, instance);\n\n    out[0] = unsafeHeap[0];\n    out[1] = unsafeHeap[1];\n    out[2] = unsafeHeap[2];\n\n    return out;\n  }\n\n  getValue4(out: Float32Array, animRef: AnimationReference, instance: M3ModelInstance): Float32Array {\n    const unsafeHeap = <Float32Array>this.getValueUnsafe(animRef, instance);\n\n    out[0] = unsafeHeap[0];\n    out[1] = unsafeHeap[1];\n    out[2] = unsafeHeap[2];\n    out[3] = unsafeHeap[3];\n\n    return out;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/standardmaterial.ts",
    "content": "import M3ParserStandardMaterial from '../../../parsers/m3/standardmaterial';\nimport Shader from '../../gl/shader';\nimport Texture from '../../texture';\nimport M3Model from './model';\nimport M3Layer from './layer';\n\n\nexport const STANDARD_MATERIAL_OFFSET = 100;\n\n/**\n * An M3 standard material.\n */\nexport class M3StandardMaterial {\n  model: M3Model;\n  gl: WebGLRenderingContext;\n  index: number;\n  name: string;\n  flags: number;\n  blendMode: number;\n  priority: number;\n  specularity: number;\n  specMult: number;\n  emisMult: number;\n  layerBlendType: number;\n  emisBlendType: number;\n  emisMode: number;\n  doubleSided: number;\n  layers: M3Layer[];\n\n  constructor(model: M3Model, index: number, material: M3ParserStandardMaterial) {\n    this.model = model;\n    this.gl = model.viewer.gl;\n    this.index = index;\n    this.name = <string>material.name.get();\n    this.flags = material.flags;\n    this.blendMode = material.blendMode;\n    this.priority = material.priority;\n    this.specularity = material.specularity;\n    this.specMult = material.specMult;\n    this.emisMult = material.emisMult;\n    this.layerBlendType = material.layerBlendType;\n    this.emisBlendType = material.emisBlendType;\n    this.emisMode = material.emisMode;\n    this.doubleSided = material.flags & 0x8;\n\n    this.layers = [\n      new M3Layer(this, 0, material.diffuseLayer, 'diffuse', 2),\n      new M3Layer(this, 1, material.decalLayer, 'decal', 2),\n      new M3Layer(this, 2, material.specularLayer, 'specular', 2),\n      new M3Layer(this, 3, material.glossLayer, 'gloss', 2),\n      new M3Layer(this, 4, material.emissiveLayer, 'emissive', material.emisBlendType),\n      new M3Layer(this, 5, material.emissive2Layer, 'emissive2', material.emisMode),\n      new M3Layer(this, 6, material.evioLayer, 'evio', 2),\n      new M3Layer(this, 7, material.evioMaskLayer, 'evioMask', 2),\n      new M3Layer(this, 8, material.alphaMaskLayer, 'alphaMask', 2),\n      new M3Layer(this, 9, material.alphaMask2Layer, 'alphaMask2', 2),\n      new M3Layer(this, 10, material.normalLayer, 'normal', 2),\n      new M3Layer(this, 11, material.heightLayer, 'heightMap', 2),\n      new M3Layer(this, 12, material.lightMapLayer, 'lightMap', 2),\n      new M3Layer(this, 13, material.ambientOcclusionLayer, 'ao', 2),\n    ];\n  }\n\n  bindCommon(): void {\n    const gl = this.gl;\n\n    if (this.blendMode === 1) {\n      gl.enable(gl.BLEND);\n      gl.blendFunc(gl.ONE, gl.ONE);\n    } else if (this.blendMode === 2) {\n      gl.enable(gl.BLEND);\n      gl.blendFunc(gl.ONE, gl.ONE);\n    } else {\n      gl.disable(gl.BLEND);\n    }\n\n    if (this.doubleSided) {\n      gl.disable(gl.CULL_FACE);\n    } else {\n      gl.enable(gl.CULL_FACE);\n    }\n\n    // Flags somewhere?\n    // Per layer?\n    gl.enable(gl.DEPTH_TEST);\n    gl.depthMask(true);\n  }\n\n  bind(shader: Shader, textureOverrides: Map<number, Texture>): void {\n    const gl = this.gl;\n\n    this.bindCommon();\n\n    gl.uniform1f(shader.uniforms['u_specularity'], this.specularity);\n    gl.uniform1f(shader.uniforms['u_specMult'], this.specMult);\n    gl.uniform1f(shader.uniforms['u_emisMult'], this.emisMult);\n    gl.uniform4f(shader.uniforms['u_lightAmbient'], 0.02, 0.02, 0.02, 0);\n\n    const layers = this.layers;\n\n    layers[0].bind(shader, textureOverrides);\n    layers[1].bind(shader, textureOverrides);\n    layers[2].bind(shader, textureOverrides);\n    layers[4].bind(shader, textureOverrides);\n    layers[5].bind(shader, textureOverrides);\n    layers[10].bind(shader, textureOverrides);\n    layers[12].bind(shader, textureOverrides);\n  }\n\n  unbind(shader: Shader): void {\n    const gl = this.gl;\n\n    gl.disable(gl.BLEND);\n    gl.enable(gl.CULL_FACE);\n\n    const layers = this.layers;\n\n    layers[0].unbind(shader);\n    layers[1].unbind(shader);\n    layers[2].unbind(shader);\n    layers[4].unbind(shader);\n    layers[5].unbind(shader);\n    layers[10].unbind(shader);\n    layers[12].unbind(shader);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/stc.ts",
    "content": "import M3ParserStc from '../../../parsers/m3/stc';\nimport { AnimationReference } from '../../../parsers/m3/animationreference';\nimport M3ModelInstance from './modelinstance';\nimport M3SdContainer from './sd';\nimport M3ParserSd from '../../../parsers/m3/sd';\nimport { quat, vec3 } from 'gl-matrix';\n\n/**\n * M3 sequence data.\n */\nexport default class M3Stc {\n  name: string;\n  runsConcurrent: number;\n  priority: number;\n  stsIndex: number;\n  animRefs: number[][] = [];\n  sd: M3SdContainer[] = [];\n\n  constructor(stc: M3ParserStc) {\n    const animIds = <Uint32Array>stc.animIds.get();\n\n    this.name = <string>stc.name.get();\n    this.runsConcurrent = stc.runsConcurrent;\n    this.priority = stc.priority;\n    this.stsIndex = stc.stsIndex;\n\n    const uints = <Uint32Array>stc.animRefs.get();\n    const animRefs = new Uint16Array(uints.buffer);\n\n    // Allows direct checks instead of loops\n    for (let i = 0, l = animIds.length; i < l; i++) {\n      this.animRefs[animIds[i]] = [animRefs[i * 2 + 1], animRefs[i * 2]];\n    }\n\n    for (const sd of stc.sd) {\n      const container = new M3SdContainer();\n\n      const sds = sd.get();\n      if (sds) {\n        container.addSds(<M3ParserSd[]>sds);\n      }\n\n      this.sd.push(container);\n    }\n  }\n\n  getValueUnsafe(animRef: AnimationReference, instance: M3ModelInstance): number | vec3 | quat | Uint8Array | null {\n    const ref = this.animRefs[animRef.animId];\n\n    if (ref) {\n      return this.sd[ref[0]].getValueUnsafe(ref[1], animRef, instance.frame, this.runsConcurrent);\n    }\n\n    return animRef.initValue;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/stg.ts",
    "content": "import M3ParserStg from '../../../parsers/m3/stg';\nimport { AnimationReference } from '../../../parsers/m3/animationreference';\nimport M3ModelInstance from './modelinstance';\nimport M3Sts from './sts';\nimport M3Stc from './stc';\nimport { quat, vec3 } from 'gl-matrix';\n\n/**\n * M3 animation data getter.\n */\nexport default class M3Stg {\n  name: string;\n  stcIndices: Uint32Array;\n  sts: M3Sts[];\n  stc: M3Stc[];\n\n  constructor(stg: M3ParserStg, sts: M3Sts[], stc: M3Stc[]) {\n    this.name = <string>stg.name.get();\n    this.stcIndices = <Uint32Array>stg.stcIndices.get();\n    this.sts = sts;\n    this.stc = stc;\n  }\n\n  getValueUnsafe(animRef: AnimationReference, instance: M3ModelInstance): number | vec3 | quat | Uint8Array | null {\n    const stcIndices = this.stcIndices;\n    const stcs = this.stc;\n    const stss = this.sts;\n\n    for (let i = 0, l = stcIndices.length; i < l; i++) {\n      const stc = stcs[stcIndices[i]];\n      const sts = stss[stc.stsIndex];\n\n      // First check if this STC actually has data for this animation reference\n      if (sts.hasData(animRef)) {\n        // Since this STC has data for this animation reference, return it\n        return stc.getValueUnsafe(animRef, instance);\n      }\n    }\n\n    // No STC referenced by the STG had data for this animation reference\n    return animRef.initValue;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/sts.ts",
    "content": "import M3ParserSts from '../../../parsers/m3/sts';\nimport { AnimationReference } from '../../../parsers/m3/animationreference';\n\n/**\n * M3 animation data validator.\n */\nexport default class M3Sts {\n  animIds = new Map<number, number>();\n\n  constructor(sts: M3ParserSts) {\n    const animIds = <Uint32Array>sts.animIds.get();\n\n    // Allows direct checks instead of loops\n    for (let i = 0, l = animIds.length; i < l; i++) {\n      this.animIds.set(animIds[i], i);\n    }\n  }\n\n  hasData(animRef: AnimationReference): boolean {\n    return this.animIds.has(animRef.animId);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/m3/texture.ts",
    "content": "import Texture from '../../texture';\n\n/**\n * An M3 texture.\n */\nexport default class M3Texture {\n  texture: Texture | null = null;\n  wrapS = 0x812f; // CLAMP_TO_EDGE\n  wrapT = 0x812f;\n\n  constructor(repeatS: boolean, repeatT: boolean) {\n    if (repeatS) {\n      this.wrapS = 0x2901; // REPEAT\n    }\n\n    if (repeatT) {\n      this.wrapT = 0x2901;\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/animatedobject.ts",
    "content": "import MdlxAnimatedObject from '../../../parsers/mdlx/animatedobject';\nimport MdxModel from './model';\nimport { Sd, createTypedSd } from './sd';\n\n/**\n * An animation object.\n */\nexport default class AnimatedObject {\n  model: MdxModel;\n  animations: Map<string, Sd> = new Map();\n  variants: {[key: string]: Uint8Array } = {};\n\n  constructor(model: MdxModel, object: MdlxAnimatedObject) {\n    this.model = model;\n\n    for (const animation of object.animations) {\n      this.animations.set(animation.name, createTypedSd(model, animation));\n    }\n  }\n\n  getScalarValue(out: Uint32Array | Float32Array, name: string, sequence: number, frame: number, counter: number, defaultValue: number): number {\n    if (sequence !== -1) {\n      const animation = this.animations.get(name);\n\n      if (animation) {\n        return animation.getValue(out, sequence, frame, counter);\n      }\n    }\n\n    out[0] = defaultValue;\n\n    return -1;\n  }\n\n  getVectorValue(out: Float32Array, name: string, sequence: number, frame: number, counter: number, defaultValue: Float32Array): number {\n    if (sequence !== -1) {\n      const animation = this.animations.get(name);\n\n      if (animation) {\n        return animation.getValue(out, sequence, frame, counter);\n      }\n    }\n\n    out[0] = defaultValue[0];\n    out[1] = defaultValue[1];\n    out[2] = defaultValue[2];\n\n    return -1;\n  }\n\n  getQuatValue(out: Float32Array, name: string, sequence: number, frame: number, counter: number, defaultValue: Float32Array): number {\n    if (sequence !== -1) {\n      const animation = this.animations.get(name);\n\n      if (animation) {\n        return animation.getValue(out, sequence, frame, counter);\n      }\n    }\n\n    out[0] = defaultValue[0];\n    out[1] = defaultValue[1];\n    out[2] = defaultValue[2];\n    out[3] = defaultValue[3];\n\n    return -1;\n  }\n\n  addVariants(name: string, variantName: string): void {\n    const animation = this.animations.get(name);\n    const sequences = this.model.sequences.length;\n    const variants = new Uint8Array(sequences);\n\n    if (animation) {\n      for (let i = 0; i < sequences; i++) {\n        if (animation.isVariant(i)) {\n          variants[i] = 1;\n        }\n      }\n    }\n\n    this.variants[variantName] = variants;\n  }\n\n  addVariantIntersection(names: string[], variantName: string): void {\n    const sequences = this.model.sequences.length;\n    const variants = new Uint8Array(sequences);\n\n    for (let i = 0; i < sequences; i++) {\n      for (const name of names) {\n        if (this.variants[name][i]) {\n          variants[i] = 1;\n        }\n      }\n    }\n\n    this.variants[variantName] = variants;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/attachment.ts",
    "content": "import MdlxAttachment from '../../../parsers/mdlx/attachment';\nimport GenericObject from './genericobject';\nimport MdxModel from './model';\n\n/**\n * An MDX attachment.\n */\nexport default class Attachment extends GenericObject {\n  path: string;\n  attachmentId: number;\n  internalModel: MdxModel | null = null;\n\n  constructor(model: MdxModel, attachment: MdlxAttachment, index: number) {\n    super(model, attachment, index);\n\n    const path = attachment.path.replace(/\\\\/g, '/').toLowerCase().replace('.mdl', '.mdx');\n\n    this.path = path;\n    this.attachmentId = attachment.attachmentId;\n\n    // Second condition is against custom resources using arbitrary paths...\n    if (path !== '' && path.indexOf('.mdx') != -1) {\n      const promise = model.viewer.load(path, model.pathSolver, model.solverParams);\n\n      promise.then((model) => {\n        if (model) {\n          this.internalModel = <MdxModel>model;\n        }\n      });\n\n      model.blockers.push(promise);\n    }\n  }\n\n  override getVisibility(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KATV', sequence, frame, counter, 1);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/attachmentinstance.ts",
    "content": "import MdxModel from './model';\nimport MdxModelInstance from './modelinstance';\nimport Attachment from './attachment';\n\n// Heap allocations needed for this module.\nconst visibilityHeap = new Float32Array(1);\n\n/**\n * An attachment instance.\n */\nexport default class AttachmentInstance {\n  instance: MdxModelInstance;\n  attachment: Attachment;\n  internalInstance: MdxModelInstance;\n\n  constructor(instance: MdxModelInstance, attachment: Attachment) {\n    const internalModel = <MdxModel>attachment.internalModel;\n    const internalInstance = internalModel.addInstance();\n\n    internalInstance.setSequenceLoopMode(2);\n    internalInstance.dontInheritScaling = false;\n    internalInstance.hide();\n    internalInstance.setParent(instance.nodes[attachment.objectId]);\n\n    this.instance = instance;\n    this.attachment = attachment;\n    this.internalInstance = internalInstance;\n  }\n\n  update(): void {\n    const instance = this.instance;\n    const internalInstance = this.internalInstance;\n\n    if (instance.scene && instance.sequence !== -1) {\n      this.attachment.getVisibility(visibilityHeap, instance.sequence, instance.frame, instance.counter);\n\n      if (visibilityHeap[0] > 0.1) {\n        // The parent instance might not actually be in a scene.\n        // This happens if loading a local model, where loading is instant and adding to a scene always comes afterwards.\n        // Therefore, do it here dynamically.\n        instance.scene.addInstance(internalInstance);\n\n        if (internalInstance.hidden()) {\n          internalInstance.show();\n\n          // Every time the attachment becomes visible again, restart its first sequence.\n          internalInstance.setSequence(0);\n        }\n      } else {\n        internalInstance.hide();\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/batch.ts",
    "content": "import Geoset from './geoset';\nimport Layer from './layer';\nimport Material from './material';\n\n/**\n * The type of skinning a batch uses.\n * \n * Vertex groups are used for SD batches with a range of 0-4 bones per vertex.\n * \n * Extended vertex groups are used for SD batches with a range of 0-8 bones per vertex.\n * \n * Skin is used for HD batches with a range of 0-4 bones per vertex.\n */\nexport enum SkinningType  {\n  VertexGroups,\n  ExtendedVertexGroups,\n  Skin,\n}\n\n/**\n * An MDX batch.\n */\nexport class Batch {\n  index: number;\n  geoset: Geoset;\n  layer: Layer;\n  material: Material | null;\n  skinningType: SkinningType;\n  isHd: boolean;\n\n  constructor(index: number, geoset: Geoset, layerOrMaterial: Layer | Material, skinningType: SkinningType, isHd: boolean) {\n    let material;\n    let layer;\n\n    if (isHd) {\n      material = <Material>layerOrMaterial;\n      layer = material.layers[0];\n    } else {\n      material = null;\n      layer = <Layer>layerOrMaterial;\n    }\n\n    this.index = index;\n    this.geoset = geoset;\n    this.skinningType = skinningType;\n    this.isHd = isHd;\n    this.layer = layer;\n    this.material = material;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/batchgroup.ts",
    "content": "import Scene from '../../scene';\nimport Texture from '../../texture';\nimport MdxModel from './model';\nimport MdxModelInstance from './modelinstance';\nimport Material from './material';\nimport mdxHandler, { MdxHandlerObject } from './handler';\nimport { SkinningType } from './batch';\n\n/**\n * A group of batches that are going to be rendered together.\n */\nexport default class BatchGroup {\n  model: MdxModel;\n  skinningType: SkinningType;\n  isHd: boolean;\n  objects: number[] = [];\n\n  constructor(model: MdxModel, skinningType: SkinningType, isHd: boolean) {\n    this.model = model;\n    this.skinningType = skinningType;\n    this.isHd = isHd;\n  }\n\n  render(instance: MdxModelInstance): void {\n    const scene = <Scene>instance.scene;\n    const camera = scene.camera;\n    const textureOverrides = instance.textureOverrides;\n    const layerAlphas = instance.layerAlphas;\n    const model = this.model;\n    const textures = model.textures;\n    const batches = model.batches;\n    const viewer = model.viewer;\n    const mdxCache = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n    const gl = viewer.gl;\n    const webgl = viewer.webgl;\n    const skinningType = this.skinningType;\n    const isHd = this.isHd;\n    const teamColors = mdxCache.teamColors;\n    const teamGlows = mdxCache.teamGlows;\n    const shader = mdxHandler.getBatchShader(viewer, skinningType, isHd);\n\n    shader.use();\n\n    const uniforms = shader.uniforms;\n\n    gl.uniformMatrix4fv(uniforms['u_VP'], false, camera.viewProjectionMatrix);\n\n    const boneTexture = instance.boneTexture;\n\n    // Instances of models with no bones don't have a bone texture.\n    if (boneTexture) {\n      boneTexture.bind(15);\n\n      gl.uniform1f(uniforms['u_hasBones'], 1);\n      gl.uniform1i(uniforms['u_boneMap'], 15);\n      gl.uniform1f(uniforms['u_vectorSize'], 1 / boneTexture.width);\n      gl.uniform1f(uniforms['u_rowSize'], 1);\n    } else {\n      gl.uniform1f(uniforms['u_hasBones'], 0);\n    }\n\n    gl.uniform3fv(uniforms['u_lightPos'], scene.lightPosition);\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, model.arrayBuffer);\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.elementBuffer);\n\n    if (isHd) {\n      gl.uniform1i(uniforms['u_diffuseMap'], 0);\n      gl.uniform1i(uniforms['u_normalsMap'], 1);\n      gl.uniform1i(uniforms['u_ormMap'], 2);\n      gl.uniform1i(uniforms['u_emissiveMap'], 3);\n      gl.uniform1i(uniforms['u_teamColorMap'], 4);\n      gl.uniform1i(uniforms['u_environmentMap'], 5);\n\n      // gl.uniform1i(uniforms['u_lutMap'], 6);\n      // gl.uniform1i(uniforms['u_envDiffuseMap'], 7);\n      // gl.uniform1i(uniforms['u_envSpecularMap'], 8);\n\n      gl.disable(gl.BLEND);\n      gl.enable(gl.DEPTH_TEST);\n      gl.depthMask(true);\n\n      gl.uniformMatrix4fv(uniforms['u_MV'], false, camera.viewMatrix);\n\n      gl.uniform3fv(uniforms['u_eyePos'], camera.location);\n\n      for (const index of this.objects) {\n        const batch = batches[index];\n        const geoset = batch.geoset;\n        const material = <Material>batch.material;\n        const [diffuseLayer, normalsLayer, ormLayer, emissiveLayer, teamColorLayer, environmentMapLayer] = material.layers;\n        const layerAlpha = layerAlphas[diffuseLayer.index];\n\n        if (layerAlpha > 0) {\n          gl.uniform1f(uniforms['u_layerAlpha'], layerAlpha);\n          gl.uniform1f(uniforms['u_filterMode'], diffuseLayer.filterMode);\n\n          const diffuseId = diffuseLayer.textureId;\n          const normalsId = normalsLayer.textureId;\n          const ormId = ormLayer.textureId;\n          const emissiveId = emissiveLayer.textureId;\n          const teamColorId = teamColorLayer.textureId;\n          const environmentMapId = environmentMapLayer.textureId;\n\n          const diffuseTexture = textures[diffuseId];\n          const normalsTexture = textures[normalsId];\n          const ormTexture = textures[ormId];\n          const emissiveTexture = textures[emissiveId];\n          let teamColorTexture = textures[teamColorId];\n          const environmentMapTexture = textures[environmentMapId];\n\n          if (teamColorTexture.replaceableId === 0 || teamColorTexture.replaceableId === 1) {\n            teamColorTexture = teamColors[instance.teamColor];\n          }\n          \n          const actualDiffuseTexture = textureOverrides.get(diffuseId) || diffuseTexture.texture;\n          const actualNormalsTexture = textureOverrides.get(normalsId) || normalsTexture.texture;\n          const actualOrmTexture = textureOverrides.get(ormId) || ormTexture.texture;\n          const actualEmissiveTexture = textureOverrides.get(emissiveId) || emissiveTexture.texture;\n          const actualTeamColorTexture = textureOverrides.get(teamColorId) || teamColorTexture.texture;\n          const actualEnvironmentMapTexture = textureOverrides.get(environmentMapId) || environmentMapTexture.texture;\n\n          webgl.bindTextureAndWrap(actualDiffuseTexture, 0, diffuseTexture.wrapS, diffuseTexture.wrapT);\n          webgl.bindTextureAndWrap(actualNormalsTexture, 1, normalsTexture.wrapS, normalsTexture.wrapT);\n          webgl.bindTextureAndWrap(actualOrmTexture, 2, ormTexture.wrapS, ormTexture.wrapT);\n          webgl.bindTextureAndWrap(actualEmissiveTexture, 3, emissiveTexture.wrapS, emissiveTexture.wrapT);\n          webgl.bindTextureAndWrap(actualTeamColorTexture, 4, teamColorTexture.wrapS, teamColorTexture.wrapT);\n          webgl.bindTextureAndWrap(actualEnvironmentMapTexture, 5, environmentMapTexture.wrapS, environmentMapTexture.wrapT);\n\n          // const { lutTexture, envDiffuseTexture, envSpecularTexture }= mdxCache;\n          // if (lutTexture && envDiffuseTexture && envSpecularTexture) {\n          //   webgl.bindTextureAndWrap(lutTexture.texture, 6, lutTexture.wrapS, lutTexture.wrapT);\n          //   webgl.bindTextureAndWrap(envDiffuseTexture.texture, 7, envDiffuseTexture.wrapS, envDiffuseTexture.wrapT);\n          //   webgl.bindTextureAndWrap(envSpecularTexture.texture, 8, envSpecularTexture.wrapS, envSpecularTexture.wrapT);\n          // }\n\n          geoset.bindHd(shader, batch.skinningType, diffuseLayer.coordId);\n          geoset.render();\n        }\n      }\n    } else {\n      const geosetColors = instance.geosetColors;\n      const layerTextures = instance.layerTextures;\n      const uvAnims = instance.uvAnims;\n\n      gl.uniform4fv(uniforms['u_vertexColor'], instance.vertexColor);\n      gl.uniform1i(uniforms['u_texture'], 0);\n      \n      for (const object of this.objects) {\n        const batch = batches[object];\n        const geoset = batch.geoset;\n        const layer = batch.layer;\n        const geosetIndex = geoset.index;\n        const layerIndex = layer.index;\n        const geosetColor = geosetColors[geosetIndex];\n        const layerAlpha = layerAlphas[layerIndex];\n\n        if (geosetColor[3] > 0.01 && layerAlpha > 0.01) {\n          const textureIndex = layerTextures[layerIndex];\n          const layerTexture = textures[textureIndex];\n          const uvAnim = uvAnims[layerIndex];\n\n          gl.uniform4fv(uniforms['u_geosetColor'], geosetColor);\n\n          gl.uniform1f(uniforms['u_layerAlpha'], layerAlpha);\n          gl.uniform1f(uniforms['u_unshaded'], layer.unshaded);\n\n          gl.uniform2f(uniforms['u_uvTrans'], uvAnim[0], uvAnim[1]);\n          gl.uniform2f(uniforms['u_uvRot'], uvAnim[2], uvAnim[3]);\n          gl.uniform1f(uniforms['u_uvScale'], uvAnim[4]);\n\n          layer.bind(shader);\n\n          let texture: Texture | null | undefined = textureOverrides.get(textureIndex);\n\n          if (!texture) {\n            const replaceable = layerTexture.replaceableId;\n            let mdxTexture;\n\n            if (replaceable === 1) {\n              mdxTexture = teamColors[instance.teamColor];\n            } else if (replaceable === 2) {\n              mdxTexture = teamGlows[instance.teamColor];\n            } else {\n              mdxTexture = layerTexture;\n            }\n\n            if (mdxTexture) {\n              texture = mdxTexture.texture;\n            }\n          }\n\n          webgl.bindTextureAndWrap(texture, 0, layerTexture.wrapS, layerTexture.wrapT);\n\n          if (skinningType === SkinningType.ExtendedVertexGroups) {\n            geoset.bindExtended(shader, layer.coordId);\n          } else {\n            geoset.bind(shader, layer.coordId);\n          }\n\n          geoset.render();\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/bone.ts",
    "content": "import MdlxBone from '../../../parsers/mdlx/bone';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\nimport GeosetAnimation from './geosetanimation';\n\n/**\n * An MDX bone.\n */\nexport default class Bone extends GenericObject {\n  geosetAnimation: GeosetAnimation;\n\n  constructor(model: MdxModel, bone: MdlxBone, index: number) {\n    super(model, bone, index);\n\n    this.geosetAnimation = model.geosetAnimations[bone.geosetAnimationId];\n  }\n\n  override getVisibility(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    if (this.geosetAnimation) {\n      return this.geosetAnimation.getAlpha(out, sequence, frame, counter);\n    }\n\n    out[0] = 1;\n\n    return -1;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/camera.ts",
    "content": "import { VEC3_ZERO } from '../../../common/gl-matrix-addon';\nimport MdlxCamera from '../../../parsers/mdlx/camera';\nimport AnimatedObject from './animatedobject';\nimport MdxModel from './model';\n\n/**\n * An MDX camera.\n */\nexport default class Camera extends AnimatedObject {\n  name: string;\n  position: Float32Array;\n  fieldOfView: number;\n  farClippingPlane: number;\n  nearClippingPlane: number;\n  targetPosition: Float32Array;\n\n  constructor(model: MdxModel, camera: MdlxCamera) {\n    super(model, camera);\n\n    this.name = camera.name;\n    this.position = camera.position;\n    this.fieldOfView = camera.fieldOfView;\n    this.farClippingPlane = camera.farClippingPlane;\n    this.nearClippingPlane = camera.nearClippingPlane;\n    this.targetPosition = camera.targetPosition;\n  }\n\n  getTranslation(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KCTR', sequence, frame, counter, <Float32Array>VEC3_ZERO);\n  }\n\n  getTargetTranslation(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KTTR', sequence, frame, counter, <Float32Array>VEC3_ZERO);\n  }\n\n  getRotation(out: Uint32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KCRL', sequence, frame, counter, 0);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/collisionshape.ts",
    "content": "import MdlxCollisionShape, { Shape } from '../../../parsers/mdlx/collisionshape';\nimport GenericObject from './genericobject';\nimport MdxModel from './model';\n\n/**\n * A collision shape.\n */\nexport default class CollisionShape extends GenericObject {\n  type: Shape;\n  vertices: Float32Array[];\n  boundsRadius: number;\n\n  constructor(model: MdxModel, collisionShape: MdlxCollisionShape, index: number) {\n    super(model, collisionShape, index);\n\n    this.type = collisionShape.type;\n    this.vertices = collisionShape.vertices;\n    this.boundsRadius = collisionShape.boundsRadius;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/emitter.ts",
    "content": "import Emitter from '../../emitter';\nimport ParticleEmitterObject from './particleemitterobject';\nimport ParticleEmitter2Object from './particleemitter2object';\nimport RibbonEmitterObject from './ribbonemitterobject';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\nimport MdxModelInstance from './modelinstance';\n\n/**\n * The base of all MDX emitters.\n */\nexport default abstract class MdxEmitter extends Emitter {\n  emitterObject: ParticleEmitterObject | ParticleEmitter2Object | RibbonEmitterObject | EventObjectEmitterObject;\n\n  constructor(instance: MdxModelInstance, emitterObject: ParticleEmitterObject | ParticleEmitter2Object | RibbonEmitterObject | EventObjectEmitterObject) {\n    super(instance);\n\n    this.emitterObject = emitterObject;\n  }\n\n  override update(dt: number): void {\n    if (this.emitterObject.ok) {\n      super.update(dt);\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/emittergroup.ts",
    "content": "import Scene from '../../scene';\nimport MdxModel from './model';\nimport MdxModelInstance from './modelinstance';\nimport { GeometryEmitter, renderEmitter } from './geometryemitterfuncs';\nimport { MdxHandlerObject } from './handler';\n\n/**\n * A group of emitters that are going to be rendered together.\n */\nexport default class EmitterGroup {\n  model: MdxModel;\n  objects: number[] = [];\n\n  constructor(model: MdxModel) {\n    this.model = model;\n  }\n\n  render(instance: MdxModelInstance): void {\n    const scene = <Scene>instance.scene;\n    const nodes = instance.nodes;\n    const model = instance.model;\n    const viewer = model.viewer;\n    const gl = viewer.gl;\n    const instancedArrays = <ANGLE_instanced_arrays>viewer.webgl.extensions['ANGLE_instanced_arrays'];\n    const mdxCache = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n    const shader = mdxCache.particlesShader;\n    const uniforms = shader.uniforms;\n    const attribs = shader.attribs;\n    const rectBuffer = mdxCache.rectBuffer;\n\n    gl.depthMask(false);\n    gl.enable(gl.BLEND);\n    gl.disable(gl.CULL_FACE);\n    gl.enable(gl.DEPTH_TEST);\n\n    shader.use();\n\n    gl.uniformMatrix4fv(uniforms['u_VP'], false, scene.camera.viewProjectionMatrix);\n    gl.uniform1i(uniforms['u_texture'], 0);\n\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_position'], 0);\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);\n    gl.vertexAttribPointer(attribs['a_position'], 1, gl.UNSIGNED_BYTE, false, 0, 0);\n\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p0'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p1'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p2'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p3'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_health'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_color'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_tail'], 1);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_leftRightTop'], 1);\n\n    for (const index of this.objects) {\n      renderEmitter(<GeometryEmitter>nodes[index].object, shader);\n    }\n\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_leftRightTop'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_tail'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_color'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_health'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p3'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p2'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p1'], 0);\n    instancedArrays.vertexAttribDivisorANGLE(attribs['a_p0'], 0);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectemitter.ts",
    "content": "import MdxModelInstance from './modelinstance';\nimport MdxEmitter from './emitter';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\n\nconst valueHeap = new Uint32Array(1);\n\n/**\n * The abstract base MDX event object emitter.\n */\nexport default abstract class EventObjectEmitter extends MdxEmitter {\n  lastValue = 0;\n\n  updateEmission(_dt: number): void {\n    const instance = <MdxModelInstance>this.instance;\n\n    if (instance.allowParticleSpawn) {\n      const emitterObject = <EventObjectEmitterObject>this.emitterObject;\n\n      emitterObject.getValue(valueHeap, instance);\n\n      const value = valueHeap[0];\n\n      if (value === 1 && value !== this.lastValue) {\n        this.currentEmission += 1;\n      }\n\n      this.lastValue = value;\n    }\n  }\n\n  emit(): void {\n    this.emitObject();\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectemitterobject.ts",
    "content": "import EventObject from '../../../parsers/mdlx/eventobject';\nimport Texture from '../../texture';\nimport GenericResource from '../../genericresource';\nimport mdxHandler from './handler';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\nimport { emitterFilterMode } from './filtermode';\nimport { EMITTER_SPLAT, EMITTER_UBERSPLAT } from './geometryemitterfuncs';\nimport MdxModelInstance from './modelinstance';\nimport MdxTexture from './texture';\nimport { WrapMode } from '../../../parsers/mdlx/texture';\n\n/**\n * An event object.\n */\nexport default class EventObjectEmitterObject extends GenericObject {\n  geometryEmitterType = -1;\n  type: string;\n  id: string;\n  tracks: Uint32Array;\n  globalSequence = -1;\n  defval = new Uint32Array(1);\n  internalModel: MdxModel | null = null;\n  internalTexture: MdxTexture | null = null;\n  colors: Float32Array[] = [];\n  intervalTimes = new Float32Array(3);\n  scale = 0;\n  columns = 0;\n  rows = 0;\n  lifeSpan = 0;\n  blendSrc = 0;\n  blendDst = 0;\n  intervals: Float32Array[] = [];\n  distanceCutoff = 0;\n  maxDistance = 0;\n  minDistance = 0;\n  pitch = 0;\n  pitchVariance = 0;\n  volume = 0;\n  decodedBuffers: AudioBuffer[] = [];\n  ok = false;\n\n  constructor(model: MdxModel, eventObject: EventObject, index: number) {\n    super(model, eventObject, index);\n\n    const viewer = model.viewer;\n    const name = eventObject.name;\n    let type = name.substring(0, 3);\n    const id = name.substring(4);\n\n    // Same thing\n    if (type === 'FPT') {\n      type = 'SPL';\n    }\n\n    if (type === 'SPL') {\n      this.geometryEmitterType = EMITTER_SPLAT;\n    } else if (type === 'UBR') {\n      this.geometryEmitterType = EMITTER_UBERSPLAT;\n    }\n\n    this.type = type;\n    this.id = id;\n    this.tracks = eventObject.tracks;\n\n    const globalSequenceId = eventObject.globalSequenceId;\n    if (globalSequenceId !== -1) {\n      this.globalSequence = model.globalSequences[globalSequenceId];\n    }\n\n    // If this is a sound event object, and the viewer doesn't have audio enabled, don't do anything.\n    // This saves bandwidth when audio is not desired.\n    if (type === 'SND' && !viewer.audioEnabled) {\n      return;\n    }\n\n    // It's not possible to know ahead of time what file(s) event objects would need.\n    // This is because the SLKs are lazily loaded, and might not exist at this point.\n    // Therefore make a promise, and resolve it after all of the files loaded.\n    const resolve = viewer.promise();\n\n    mdxHandler.getEventObjectData(viewer, type, id, model.hd)\n      .then((data) => {\n        // Now the promise can be resolved to allow the viewer to handle events correctly.\n        resolve();\n\n        if (data) {\n          const { row, resources } = data;\n\n          this.ok = true;\n\n          if (type === 'SPN') {\n            this.internalModel = <MdxModel>resources[0];\n          } else if (type === 'SPL' || type === 'UBR') {\n            this.internalTexture = new MdxTexture(0, WrapMode.WrapBoth);\n            this.internalTexture.texture = <Texture>resources[0];\n\n            this.scale = row.number('Scale');\n            this.colors[0] = new Float32Array([row.number('StartR'), row.number('StartG'), row.number('StartB'), row.number('StartA')]);\n            this.colors[1] = new Float32Array([row.number('MiddleR'), row.number('MiddleG'), row.number('MiddleB'), row.number('MiddleA')]);\n            this.colors[2] = new Float32Array([row.number('EndR'), row.number('EndG'), row.number('EndB'), row.number('EndA')]);\n\n            if (type === 'SPL') {\n              this.columns = row.number('Columns');\n              this.rows = row.number('Rows');\n              this.lifeSpan = row.number('Lifespan') + row.number('Decay');\n\n              this.intervalTimes[0] = row.number('Lifespan');\n              this.intervalTimes[1] = row.number('Decay');\n\n              this.intervals[0] = new Float32Array([row.number('UVLifespanStart'), row.number('UVLifespanEnd'), row.number('LifespanRepeat')]);\n              this.intervals[1] = new Float32Array([row.number('UVDecayStart'), row.number('UVDecayEnd'), row.number('DecayRepeat')]);\n            } else {\n              this.columns = 1;\n              this.rows = 1;\n              this.lifeSpan = row.number('BirthTime') + row.number('PauseTime') + row.number('Decay');\n\n              this.intervalTimes[0] = row.number('BirthTime');\n              this.intervalTimes[1] = row.number('PauseTime');\n              this.intervalTimes[2] = row.number('Decay');\n            }\n\n            const blendModes = emitterFilterMode(row.number('BlendMode'), viewer.gl);\n\n            this.blendSrc = blendModes[0];\n            this.blendDst = blendModes[1];\n          } else {\n            this.distanceCutoff = row.number('DistanceCutoff');\n            this.maxDistance = row.number('MaxDistance');\n            this.minDistance = row.number('MinDistance');\n            this.pitch = row.number('Pitch');\n            this.pitchVariance = row.number('PitchVariance');\n            this.volume = row.number('Volume');\n\n            for (const resource of resources) {\n              this.decodedBuffers.push(<AudioBuffer>(<GenericResource>resource).data);\n            }\n          }\n        }\n      });\n  }\n\n  getValue(out: Uint32Array, instance: MdxModelInstance): number {\n    if (this.globalSequence !== -1) {\n      const globalSequence = this.globalSequence;\n\n      return this.getValueAtTime(out, instance.counter % globalSequence, 0, globalSequence);\n    } else if (instance.sequence !== -1) {\n      const interval = this.model.sequences[instance.sequence].interval;\n\n      return this.getValueAtTime(out, instance.frame, interval[0], interval[1]);\n    } else {\n      out[0] = this.defval[0];\n\n      return -1;\n    }\n  }\n\n  getValueAtTime(out: Uint32Array, frame: number, start: number, end: number): number {\n    const tracks = this.tracks;\n\n    if (frame >= start && frame <= end) {\n      for (let i = tracks.length - 1; i > -1; i--) {\n        if (tracks[i] < start) {\n          out[0] = 0;\n\n          return i;\n        } else if (tracks[i] <= frame) {\n          out[0] = 1;\n\n          return i;\n        }\n      }\n    }\n\n    out[0] = 0;\n\n    return -1;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectsnd.ts",
    "content": "import Scene from '../../scene';\nimport EmittedObject from '../../emittedobject';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport EventObjectSndEmitter from './eventobjectsndemitter';\n\n/**\n * An MDX spawned sound object.\n */\nexport default class EventObjectSnd extends EmittedObject {\n  bind(): void {\n    const emitter = <EventObjectSndEmitter>this.emitter;\n    const instance = <MdxModelInstance>emitter.instance;\n    const viewer = instance.model.viewer;\n    const scene = <Scene>instance.scene;\n\n    // Is audio enabled both viewer-wide and in this scene?\n    if (viewer.audioEnabled && scene.audioEnabled) {\n      const emitterObject = <EventObjectEmitterObject>emitter.emitterObject;\n      const node = instance.nodes[emitterObject.index];\n      const audioContext = <AudioContext>scene.audioContext;\n      const decodedBuffers = emitterObject.decodedBuffers;\n      const panner = audioContext.createPanner();\n      const source = audioContext.createBufferSource();\n      const location = node.worldLocation;\n\n      // Panner settings.\n      panner.positionX.value = location[0];\n      panner.positionY.value = location[1];\n      panner.positionZ.value = location[2];\n      panner.maxDistance = emitterObject.distanceCutoff;\n      panner.refDistance = emitterObject.minDistance;\n      panner.connect(audioContext.destination);\n\n      // Source.\n      source.buffer = decodedBuffers[(Math.random() * decodedBuffers.length) | 0];\n      source.connect(panner);\n\n      // Make a sound.\n      source.start(0);\n    }\n  }\n\n  update(_dt: number): void {\n\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectsndemitter.ts",
    "content": "import EventObjectEmitter from './eventobjectemitter';\nimport EventObjectSnd from './eventobjectsnd';\n\n/**\n * An MDX sound emitter.\n */\nexport default class EventObjectSndEmitter extends EventObjectEmitter {\n  createObject(): EventObjectSnd {\n    return new EventObjectSnd(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectsplemitter.ts",
    "content": "import EventObjectEmitter from './eventobjectemitter';\nimport EventObjectSplUbr from './eventobjectsplubr';\n\n/**\n * An MDX splat emitter.\n */\nexport default class EventObjectSplEmitter extends EventObjectEmitter {\n  createObject(): EventObjectSplUbr {\n    return new EventObjectSplUbr(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectsplubr.ts",
    "content": "import { vec3 } from 'gl-matrix';\nimport EmittedObject from '../../emittedobject';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport EventObjectSplEmitter from './eventobjectsplemitter';\nimport EventObjectUbrEmitter from './eventobjectubremitter';\n\nconst vertexHeap = vec3.create();\n\n/**\n * An MDX splat or ubersplat object.\n */\nexport default class EventObjectSplUbr extends EmittedObject {\n  vertices = new Float32Array(12);\n\n  bind(): void {\n    const emitter = <EventObjectSplEmitter | EventObjectUbrEmitter>this.emitter;\n    const instance = <MdxModelInstance>emitter.instance;\n    const emitterObject = <EventObjectEmitterObject>emitter.emitterObject;\n    const vertices = this.vertices;\n    const scale = emitterObject.scale;\n    const { worldLocation, worldRotation } = instance.nodes[emitterObject.index];\n\n    this.health = emitterObject.lifeSpan;\n\n    vec3.set(vertexHeap, scale, scale, 0);\n    vec3.transformQuat(vertexHeap, vertexHeap, worldRotation);\n    vec3.add(<vec3>vertices.subarray(0, 2), vertexHeap, worldLocation);\n\n    vec3.set(vertexHeap, -scale, scale, 0);\n    vec3.transformQuat(vertexHeap, vertexHeap, worldRotation);\n    vec3.add(<vec3>vertices.subarray(3, 5), vertexHeap, worldLocation);\n\n    vec3.set(vertexHeap, -scale, -scale, 0);\n    vec3.transformQuat(vertexHeap, vertexHeap, worldRotation);\n    vec3.add(<vec3>vertices.subarray(6, 8), vertexHeap, worldLocation);\n\n    vec3.set(vertexHeap, scale, -scale, 0);\n    vec3.transformQuat(vertexHeap, vertexHeap, worldRotation);\n    vec3.add(<vec3>vertices.subarray(9, 11), vertexHeap, worldLocation);\n  }\n\n  update(dt: number): void {\n    this.health -= dt;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectspn.ts",
    "content": "import Scene from '../../scene';\nimport EmittedObject from '../../emittedobject';\nimport MdxModel from './model';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport EventObjectSpnEmitter from './eventobjectspnemitter';\n\n/**\n * An MDX spawned model object.\n */\nexport default class EventObjectSpn extends EmittedObject {\n  internalInstance: MdxModelInstance;\n\n  constructor(emitter: EventObjectSpnEmitter) {\n    super(emitter);\n\n    const emitterObject = <EventObjectEmitterObject>emitter.emitterObject;\n    const internalModel = <MdxModel>emitterObject.internalModel;\n\n    this.internalInstance = internalModel.addInstance();\n  }\n\n  bind(): void {\n    const emitter = <EventObjectSpnEmitter>this.emitter;\n    const instance = <MdxModelInstance>emitter.instance;\n    const scene = <Scene>instance.scene;\n    const node = instance.nodes[emitter.emitterObject.index];\n    const internalInstance = this.internalInstance;\n\n    internalInstance.setScene(scene);\n    internalInstance.setSequence(0);\n    internalInstance.setTransformation(node.worldLocation, node.worldRotation, node.worldScale);\n    internalInstance.show();\n\n    this.health = 1;\n  }\n\n  update(_dt: number): void{\n    const instance = this.internalInstance;\n    const model = <MdxModel>instance.model;\n\n    // Once the sequence finishes, this event object dies\n    if (instance.frame >= model.sequences[0].interval[1]) {\n      this.health = 0;\n\n      instance.hide();\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectspnemitter.ts",
    "content": "import EventObjectEmitter from './eventobjectemitter';\nimport EventObjectSpn from './eventobjectspn';\n\n/**\n * An MDX model emitter.\n */\nexport default class EventObjectSpnEmitter extends EventObjectEmitter {\n  createObject(): EventObjectSpn {\n    return new EventObjectSpn(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/eventobjectubremitter.ts",
    "content": "import EventObjectEmitter from './eventobjectemitter';\nimport EventObjectSplUbr from './eventobjectsplubr';\n\n/**\n * An MDX ubersplat emitter.\n */\nexport default class EventObjectUbrEmitter extends EventObjectEmitter {\n  createObject(): EventObjectSplUbr {\n    return new EventObjectSplUbr(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/filtermode.ts",
    "content": "import { FilterMode as LayerFilterMode } from '../../../parsers/mdlx/layer';\nimport { FilterMode as Particle2FilterMode } from '../../../parsers/mdlx/particleemitter2';\n\nexport function layerFilterMode(filterMode: LayerFilterMode, gl: WebGLRenderingContext): number[] {\n  if (filterMode === LayerFilterMode.Blend) {\n    return [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA];\n  } else if (filterMode === LayerFilterMode.Additive) {\n    return [gl.SRC_ALPHA, gl.ONE];\n  } else if (filterMode === LayerFilterMode.AddAlpha) {\n    return [gl.SRC_ALPHA, gl.ONE];\n  } else if (filterMode === LayerFilterMode.Modulate) {\n    return [gl.ZERO, gl.SRC_COLOR];\n  } else if (filterMode === LayerFilterMode.Modulate2x) {\n    return [gl.DST_COLOR, gl.SRC_COLOR];\n  } else {\n    return [0, 0];\n  }\n}\n\nexport function emitterFilterMode(filterMode: Particle2FilterMode, gl: WebGLRenderingContext): number[] {\n  if (filterMode === Particle2FilterMode.Blend) {\n    return [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA];\n  } else if (filterMode === Particle2FilterMode.Additive) {\n    return [gl.SRC_ALPHA, gl.ONE];\n  } else if (filterMode === Particle2FilterMode.Modulate) {\n    return [gl.ZERO, gl.SRC_COLOR];\n  } else if (filterMode === Particle2FilterMode.Modulate2x) {\n    return [gl.DST_COLOR, gl.SRC_COLOR];\n  } else if (filterMode === Particle2FilterMode.AlphaKey) {\n    return [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA];\n  } else {\n    return [0, 0];\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/genericobject.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { VEC3_ZERO, VEC3_ONE, QUAT_DEFAULT } from '../../../common/gl-matrix-addon';\nimport MdlxGenericObject, { Flags } from '../../../parsers/mdlx/genericobject';\nimport AnimatedObject from './animatedobject';\nimport MdxModel from './model';\n\n/**\n * An MDX generic object.\n */\nexport default class GenericObject extends AnimatedObject {\n  index: number;\n  name: string;\n  objectId: number;\n  parentId: number;\n  pivot: vec3;\n  dontInheritTranslation: boolean;\n  dontInheritRotation: boolean;\n  dontInheritScaling: boolean;\n  billboarded: boolean;\n  billboardedX: boolean;\n  billboardedY: boolean;\n  billboardedZ: boolean;\n  cameraAnchored: boolean;\n  anyBillboarding: boolean;\n\n  constructor(model: MdxModel, object: MdlxGenericObject, index: number) {\n    super(model, object);\n\n    this.index = index;\n    this.name = object.name;\n    this.objectId = object.objectId;\n    this.parentId = object.parentId;\n    this.pivot = <vec3>model.pivotPoints[object.objectId] || vec3.create();\n\n    const flags = object.flags;\n    this.dontInheritTranslation = (flags & Flags.DontInheritTranslation) > 0;\n    this.dontInheritRotation = (flags & Flags.DontInheritRotation) > 0;\n    this.dontInheritScaling = (flags & Flags.DontInheritScaling) > 0;\n    this.billboarded = (flags & Flags.Billboarded) > 0;\n    this.billboardedX = (flags & Flags.BillboardedLockX) > 0;\n    this.billboardedY = (flags & Flags.BillboardedLockY) > 0;\n    this.billboardedZ = (flags & Flags.BillboardedLockZ) > 0;\n    this.cameraAnchored = (flags & Flags.CameraAnchored) > 0;\n    this.anyBillboarding = this.billboarded || this.billboardedX || this.billboardedY || this.billboardedZ;\n\n    if (object.objectId === object.parentId) {\n      this.parentId = -1;\n    }\n\n    this.addVariants('KGTR', 'translation');\n    this.addVariants('KGRT', 'rotation');\n    this.addVariants('KGSC', 'scale');\n    this.addVariantIntersection(['translation', 'rotation', 'scale'], 'generic');\n  }\n\n  /**\n   * Give a consistent visibility getter for all generic objects.\n   * \n   * Many of the generic objects have animated visibilities, and will override this.\n   */\n  getVisibility(out: Float32Array, _sequence: number, _frame: number, _counter: number): number {\n    out[0] = 1;\n\n    return -1;\n  }\n\n  getTranslation(out: vec3, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(<Float32Array>out, 'KGTR', sequence, frame, counter, <Float32Array>VEC3_ZERO);\n  }\n\n  getRotation(out: quat, sequence: number, frame: number, counter: number): number {\n    return this.getQuatValue(<Float32Array>out, 'KGRT', sequence, frame, counter, <Float32Array>QUAT_DEFAULT);\n  }\n\n  getScale(out: vec3, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(<Float32Array>out, 'KGSC', sequence, frame, counter, <Float32Array>VEC3_ONE);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/geometryemitterfuncs.ts",
    "content": "import { vec3 } from 'gl-matrix';\nimport Scene from '../../scene';\nimport Shader from '../../gl/shader';\nimport ClientBuffer from '../../gl/clientbuffer';\nimport Texture from '../../texture';\nimport ParticleEmitter2Object from './particleemitter2object';\nimport RibbonEmitterObject from './ribbonemitterobject';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport ParticleEmitter2 from './particleemitter2';\nimport RibbonEmitter from './ribbonemitter';\nimport EventObjectSplEmitter from './eventobjectsplemitter';\nimport EventObjectUbrEmitter from './eventobjectubremitter';\nimport Particle2 from './particle2';\nimport Ribbon from './ribbon';\nimport EventObjectSplUbr from './eventobjectsplubr';\nimport MdxTexture from './texture';\nimport { HeadOrTail } from '../../../parsers/mdlx/particleemitter2';\nimport { MdxHandlerObject } from './handler';\n\nconst locationHeap = vec3.create();\nconst startHeap = vec3.create();\nconst endHeap = vec3.create();\n\n// The total storage that emitted objects can use.\n// This is enough to support all of the MDX geometry emitters.\n// The memory layout is the same as this C struct:\n//\n//   struct {\n//     float p0[3]\n//     float p1[3]\n//     float p2[3]\n//     float p3[3]\n//     float health\n//     byte color[4]\n//     byte tail\n//     byte leftRightTop[3]\n//   }\n//\nexport const BYTES_PER_OBJECT = 60;\nexport const FLOATS_PER_OBJECT = BYTES_PER_OBJECT >> 2;\n\n// Offsets into the emitted object structure.\nexport const BYTE_OFFSET_P0 = 0;\nexport const BYTE_OFFSET_P1 = 12;\nexport const BYTE_OFFSET_P2 = 24;\nexport const BYTE_OFFSET_P3 = 36;\nexport const BYTE_OFFSET_HEALTH = 48;\nexport const BYTE_OFFSET_COLOR = 52;\nexport const BYTE_OFFSET_TAIL = 56;\nexport const BYTE_OFFSET_LEFT_RIGHT_TOP = 57;\n\n// Offset aliases.\nexport const FLOAT_OFFSET_P0 = BYTE_OFFSET_P0 >> 2;\nexport const FLOAT_OFFSET_P1 = BYTE_OFFSET_P1 >> 2;\nexport const FLOAT_OFFSET_P2 = BYTE_OFFSET_P2 >> 2;\nexport const FLOAT_OFFSET_P3 = BYTE_OFFSET_P3 >> 2;\nexport const FLOAT_OFFSET_HEALTH = BYTE_OFFSET_HEALTH >> 2;\nexport const BYTE_OFFSET_TEAM_COLOR = BYTE_OFFSET_LEFT_RIGHT_TOP;\n\n// Emitter types\nexport const EMITTER_PARTICLE2 = 0;\nexport const EMITTER_RIBBON = 1;\nexport const EMITTER_SPLAT = 2;\nexport const EMITTER_UBERSPLAT = 3;\n\n// Offsets for overriding emitter textures using setResource().\nexport const EMITTER_PARTICLE2_TEXTURE_OFFSET = 1000;\nexport const EMITTER_EVENT_TEXTURE_OFFSET = 10000;\n\n// The game scales the emission rate of particle emitters depending on the particles setting.\n// High seems to double the emission.\nexport const SETTING_PARTICLES_HIGH = 2;\n\nexport type GeometryEmitter = ParticleEmitter2 | RibbonEmitter | EventObjectSplEmitter | EventObjectUbrEmitter;\nexport type GeometryEmitterObject = ParticleEmitter2Object | RibbonEmitterObject | EventObjectEmitterObject;\n\nfunction bindParticleEmitter2Buffer(emitter: ParticleEmitter2, buffer: ClientBuffer): void {\n  const instance = <MdxModelInstance>emitter.instance;\n  const objects = <Particle2[]>emitter.objects;\n  const byteView = <Uint8Array>buffer.byteView;\n  const floatView = <Float32Array>buffer.floatView;\n  const emitterObject = <ParticleEmitter2Object>emitter.emitterObject;\n  const modelSpace = emitterObject.modelSpace;\n  const tailLength = emitterObject.tailLength;\n  const node = emitter.node;\n  const teamColor = instance.teamColor;\n  let offset = 0;\n\n  for (const object of objects) {\n    const byteOffset = offset * BYTES_PER_OBJECT;\n    const floatOffset = offset * FLOATS_PER_OBJECT;\n    const p0Offset = floatOffset + FLOAT_OFFSET_P0;\n    let location = object.location;\n    const scale = object.scale;\n    const tail = object.tail;\n\n    if (tail === HeadOrTail.Head) {\n      // If this is a model space emitter, the location is in local space, so convert it to world space.\n      if (modelSpace) {\n        location = vec3.transformMat4(locationHeap, location, node.worldMatrix);\n      }\n\n      floatView[p0Offset + 0] = location[0];\n      floatView[p0Offset + 1] = location[1];\n      floatView[p0Offset + 2] = location[2];\n\n      // Used to rotate XY particles to face their velocity on the XY plane.\n      floatView[p0Offset + 3] = object.facing;\n    } else {\n      const velocity = object.velocity;\n      let start = startHeap;\n      let end = location;\n\n      start[0] = end[0] - tailLength * velocity[0];\n      start[1] = end[1] - tailLength * velocity[1];\n      start[2] = end[2] - tailLength * velocity[2];\n\n      // If this is a model space emitter, the start and end are in local space, so convert them to world space.\n      if (modelSpace) {\n        start = vec3.transformMat4(start, start, node.worldMatrix);\n        end = vec3.transformMat4(endHeap, end, node.worldMatrix);\n      }\n\n      floatView[p0Offset + 0] = start[0];\n      floatView[p0Offset + 1] = start[1];\n      floatView[p0Offset + 2] = start[2];\n      floatView[p0Offset + 3] = end[0];\n      floatView[p0Offset + 4] = end[1];\n      floatView[p0Offset + 5] = end[2];\n    }\n\n    floatView[p0Offset + 6] = scale[0];\n    floatView[p0Offset + 7] = scale[0];\n    floatView[p0Offset + 8] = scale[0];\n\n    floatView[floatOffset + FLOAT_OFFSET_HEALTH] = object.health;\n\n    byteView[byteOffset + BYTE_OFFSET_TAIL] = tail;\n    byteView[byteOffset + BYTE_OFFSET_TEAM_COLOR] = teamColor;\n\n    offset += 1;\n  }\n}\n\nfunction bindParticleEmitter2Shader(emitter: ParticleEmitter2, shader: Shader): void {\n  const instance = <MdxModelInstance>emitter.instance;\n  const textureOverrides = instance.textureOverrides;\n  const scene = <Scene>instance.scene;\n  const camera = scene.camera;\n  const emitterObject = <ParticleEmitter2Object>emitter.emitterObject;\n  const model = emitterObject.model;\n  const viewer = model.viewer;\n  const gl = viewer.gl;\n  const mdxCache = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n  const uniforms = shader.uniforms;\n  const colors = emitterObject.colors;\n  const intervals = emitterObject.intervals;\n  const replaceable = emitterObject.replaceableId;\n  let vectors;\n  let mdxTexture = <MdxTexture>emitterObject.internalTexture;\n\n  gl.blendFunc(emitterObject.blendSrc, emitterObject.blendDst);\n  gl.uniform1f(uniforms['u_filterMode'], emitterObject.filterMode);\n\n  // Determine where this texture is coming from.\n  // This is to get the texture wrap modes.\n  // The texture is either a replaceable in which case it's stored internally, a team color in which case it's stored in the handler, or a reference to one of the model textures.\n  if (emitterObject.internalTexture) {\n    mdxTexture = emitterObject.internalTexture;\n  } else if (replaceable === 1) {\n    mdxTexture = mdxCache.teamColors[instance.teamColor];\n  } else if (replaceable === 2) {\n    mdxTexture = mdxCache.teamGlows[instance.teamColor];\n  } else {\n    mdxTexture = model.textures[emitterObject.textureId];\n  }\n\n  // Now get the actual texture itself.\n  // First check if there is an override for this particle emitter.\n  let texture: Texture | null | undefined = textureOverrides.get(EMITTER_PARTICLE2_TEXTURE_OFFSET + emitterObject.index);\n\n  if (!texture) {\n    // Next check if there is an override for model textures if this is one.\n    if (replaceable === 0) {\n      texture = textureOverrides.get(emitterObject.textureId);\n    }\n\n    // If there is still no override, get it from the existing texture object.\n    if (!texture) {\n      texture = mdxTexture.texture;\n    }\n  }\n\n  viewer.webgl.bindTextureAndWrap(texture, 0, mdxTexture.wrapS, mdxTexture.wrapT);\n\n  // Choose between a default rectangle or a billboarded one\n  if (emitterObject.xYQuad) {\n    vectors = camera.vectors;\n  } else {\n    vectors = camera.billboardedVectors;\n  }\n\n  gl.uniform1f(uniforms['u_lifeSpan'], emitterObject.lifeSpan);\n  gl.uniform1f(uniforms['u_timeMiddle'], emitterObject.timeMiddle);\n  gl.uniform1f(uniforms['u_columns'], emitterObject.columns);\n  gl.uniform1f(uniforms['u_rows'], emitterObject.rows);\n  gl.uniform1f(uniforms['u_teamColored'], emitterObject.teamColored);\n\n  gl.uniform3fv(uniforms['u_intervals[0]'], intervals[0]);\n  gl.uniform3fv(uniforms['u_intervals[1]'], intervals[1]);\n  gl.uniform3fv(uniforms['u_intervals[2]'], intervals[2]);\n  gl.uniform3fv(uniforms['u_intervals[3]'], intervals[3]);\n\n  gl.uniform4fv(uniforms['u_colors[0]'], colors[0]);\n  gl.uniform4fv(uniforms['u_colors[1]'], colors[1]);\n  gl.uniform4fv(uniforms['u_colors[2]'], colors[2]);\n\n  gl.uniform3fv(uniforms['u_scaling'], emitterObject.scaling);\n\n  if (emitterObject.head) {\n    gl.uniform3fv(uniforms['u_vertices[0]'], vectors[0]);\n    gl.uniform3fv(uniforms['u_vertices[1]'], vectors[1]);\n    gl.uniform3fv(uniforms['u_vertices[2]'], vectors[2]);\n    gl.uniform3fv(uniforms['u_vertices[3]'], vectors[3]);\n  }\n\n  if (emitterObject.tail) {\n    gl.uniform3fv(uniforms['u_cameraZ'], camera.directionZ);\n  }\n}\n\nfunction bindRibbonEmitterBuffer(emitter: RibbonEmitter, buffer: ClientBuffer): void {\n  let object = <Ribbon>emitter.first;\n  const byteView = <Uint8Array>buffer.byteView;\n  const floatView = <Float32Array>buffer.floatView;\n  const emitterObject = <RibbonEmitterObject>emitter.emitterObject;\n  const columns = emitterObject.columns;\n  const alive = emitter.alive;\n  const chainLengthFactor = 1 / (alive - 1);\n  let offset = 0;\n\n  while (object.next) {\n    const next = object.next.vertices;\n    const byteOffset = offset * BYTES_PER_OBJECT;\n    const floatOffset = offset * FLOATS_PER_OBJECT;\n    const p0Offset = floatOffset + FLOAT_OFFSET_P0;\n    const colorOffset = byteOffset + BYTE_OFFSET_COLOR;\n    const leftRightTopOffset = byteOffset + BYTE_OFFSET_LEFT_RIGHT_TOP;\n    const left = ((object.slot % columns) + (1 - (offset * chainLengthFactor) - chainLengthFactor)) / columns;\n    const top = object.slot / columns;\n    const right = left + chainLengthFactor;\n    const vertices = object.vertices;\n    const color = object.color;\n\n    floatView[p0Offset + 0] = vertices[0];\n    floatView[p0Offset + 1] = vertices[1];\n    floatView[p0Offset + 2] = vertices[2];\n    floatView[p0Offset + 3] = vertices[3];\n    floatView[p0Offset + 4] = vertices[4];\n    floatView[p0Offset + 5] = vertices[5];\n    floatView[p0Offset + 6] = next[3];\n    floatView[p0Offset + 7] = next[4];\n    floatView[p0Offset + 8] = next[5];\n    floatView[p0Offset + 9] = next[0];\n    floatView[p0Offset + 10] = next[1];\n    floatView[p0Offset + 11] = next[2];\n\n    byteView[colorOffset + 0] = color[0];\n    byteView[colorOffset + 1] = color[1];\n    byteView[colorOffset + 2] = color[2];\n    byteView[colorOffset + 3] = color[3];\n\n    byteView[leftRightTopOffset + 0] = left * 255;\n    byteView[leftRightTopOffset + 1] = right * 255;\n    byteView[leftRightTopOffset + 2] = top * 255;\n\n    object = object.next;\n    offset += 1;\n  }\n}\n\nfunction bindRibbonEmitterShader(emitter: RibbonEmitter, shader: Shader): void {\n  const textureOverrides = emitter.instance.textureOverrides;\n  const emitterObject = <RibbonEmitterObject>emitter.emitterObject;\n  const layer = emitterObject.layer;\n  const model = emitterObject.model;\n  const gl = model.viewer.gl;\n  const uniforms = shader.uniforms;\n  const texture = model.textures[layer.textureId];\n  const actualTexture = textureOverrides.get(layer.textureId) || texture.texture;\n\n  layer.bind(shader);\n\n  gl.uniform1f(uniforms['u_filterMode'], layer.filterMode);\n\n  model.viewer.webgl.bindTextureAndWrap(actualTexture, 0, texture.wrapS, texture.wrapT);\n\n  gl.uniform1f(uniforms['u_columns'], emitterObject.columns);\n  gl.uniform1f(uniforms['u_rows'], emitterObject.rows);\n}\n\nfunction bindEventObjectEmitterBuffer(emitter: EventObjectSplEmitter | EventObjectUbrEmitter, buffer: ClientBuffer): void {\n  const objects = <EventObjectSplUbr[]>emitter.objects;\n  const floatView = <Float32Array>buffer.floatView;\n  let offset = 0;\n\n  for (const object of objects) {\n    const floatOffset = offset * FLOATS_PER_OBJECT;\n    const p0Offset = floatOffset + FLOAT_OFFSET_P0;\n    const vertices = object.vertices;\n\n    floatView[p0Offset + 0] = vertices[0];\n    floatView[p0Offset + 1] = vertices[1];\n    floatView[p0Offset + 2] = vertices[2];\n    floatView[p0Offset + 3] = vertices[3];\n    floatView[p0Offset + 4] = vertices[4];\n    floatView[p0Offset + 5] = vertices[5];\n    floatView[p0Offset + 6] = vertices[6];\n    floatView[p0Offset + 7] = vertices[7];\n    floatView[p0Offset + 8] = vertices[8];\n    floatView[p0Offset + 9] = vertices[9];\n    floatView[p0Offset + 10] = vertices[10];\n    floatView[p0Offset + 11] = vertices[11];\n\n    floatView[floatOffset + FLOAT_OFFSET_HEALTH] = object.health;\n\n    offset += 1;\n  }\n}\n\nfunction bindEventObjectSplEmitterShader(emitter: EventObjectSplEmitter, shader: Shader): void {\n  const textureOverrides = emitter.instance.textureOverrides;\n  const emitterObject = <EventObjectEmitterObject>emitter.emitterObject;\n  const intervalTimes = emitterObject.intervalTimes;\n  const intervals = emitterObject.intervals;\n  const colors = emitterObject.colors;\n  const model = emitterObject.model;\n  const gl = model.viewer.gl;\n  const uniforms = shader.uniforms;\n  const texture = <MdxTexture>emitterObject.internalTexture;\n  const actualTexture = textureOverrides.get(EMITTER_EVENT_TEXTURE_OFFSET + emitterObject.index) || texture.texture;\n\n  gl.blendFunc(emitterObject.blendSrc, emitterObject.blendDst);\n\n  model.viewer.webgl.bindTextureAndWrap(actualTexture, 0, texture.wrapS, texture.wrapT);\n\n  gl.uniform1f(uniforms['u_lifeSpan'], emitterObject.lifeSpan);\n  gl.uniform1f(uniforms['u_columns'], emitterObject.columns);\n  gl.uniform1f(uniforms['u_rows'], emitterObject.rows);\n\n  // 3 because the uniform is shared with UBR, which has 3 values.\n  gl.uniform3f(uniforms['u_intervalTimes'], intervalTimes[0], intervalTimes[1], 0);\n\n  gl.uniform3fv(uniforms['u_intervals[0]'], intervals[0]);\n  gl.uniform3fv(uniforms['u_intervals[1]'], intervals[1]);\n\n  gl.uniform4fv(uniforms['u_colors[0]'], colors[0]);\n  gl.uniform4fv(uniforms['u_colors[1]'], colors[1]);\n  gl.uniform4fv(uniforms['u_colors[2]'], colors[2]);\n}\n\nfunction bindEventObjectUbrEmitterShader(emitter: EventObjectUbrEmitter, shader: Shader): void {\n  const textureOverrides = emitter.instance.textureOverrides;\n  const emitterObject = <EventObjectEmitterObject>emitter.emitterObject;\n  const intervalTimes = emitterObject.intervalTimes;\n  const colors = emitterObject.colors;\n  const model = emitterObject.model;\n  const viewer = model.viewer;\n  const gl = viewer.gl;\n  const uniforms = shader.uniforms;\n  const texture = <MdxTexture>emitterObject.internalTexture;\n  const actualTexture = textureOverrides.get(EMITTER_EVENT_TEXTURE_OFFSET + emitterObject.index) || texture.texture;\n\n  gl.blendFunc(emitterObject.blendSrc, emitterObject.blendDst);\n\n  model.viewer.webgl.bindTextureAndWrap(actualTexture, 0, texture.wrapS, texture.wrapT);\n\n  gl.uniform1f(uniforms['u_lifeSpan'], emitterObject.lifeSpan);\n  gl.uniform1f(uniforms['u_columns'], emitterObject.columns);\n  gl.uniform1f(uniforms['u_rows'], emitterObject.rows);\n\n  gl.uniform3fv(uniforms['u_intervalTimes'], intervalTimes);\n\n  gl.uniform4fv(uniforms['u_colors[0]'], colors[0]);\n  gl.uniform4fv(uniforms['u_colors[1]'], colors[1]);\n  gl.uniform4fv(uniforms['u_colors[2]'], colors[2]);\n}\n\nexport function renderEmitter(emitter: GeometryEmitter, shader: Shader): void {\n  let alive = emitter.alive;\n  const emitterObject = <GeometryEmitterObject>emitter.emitterObject;\n  const emitterType = emitterObject.geometryEmitterType;\n\n  if (emitterType === EMITTER_RIBBON) {\n    alive -= 1;\n  }\n\n  if (alive > 0) {\n    const viewer = emitter.instance.model.viewer;\n    const buffer = viewer.buffer;\n    const gl = viewer.gl;\n    const instancedArrays = <ANGLE_instanced_arrays>viewer.webgl.extensions['ANGLE_instanced_arrays'];\n    const size = alive * BYTES_PER_OBJECT;\n    const attribs = shader.attribs;\n\n    buffer.reserve(size);\n\n    if (emitterType === EMITTER_PARTICLE2) {\n      bindParticleEmitter2Buffer(<ParticleEmitter2>emitter, buffer);\n      bindParticleEmitter2Shader(<ParticleEmitter2>emitter, shader);\n    } else if (emitterType === EMITTER_RIBBON) {\n      bindRibbonEmitterBuffer(<RibbonEmitter>emitter, buffer);\n      bindRibbonEmitterShader(<RibbonEmitter>emitter, shader);\n    } else if (emitterType === EMITTER_SPLAT) {\n      bindEventObjectEmitterBuffer(<EventObjectSplEmitter>emitter, buffer);\n      bindEventObjectSplEmitterShader(<EventObjectSplEmitter>emitter, shader);\n    } else {\n      bindEventObjectEmitterBuffer(<EventObjectUbrEmitter>emitter, buffer);\n      bindEventObjectUbrEmitterShader(<EventObjectUbrEmitter>emitter, shader);\n    }\n\n    buffer.bindAndUpdate(size);\n\n    gl.uniform1i(shader.uniforms['u_emitter'], emitterType);\n\n    gl.vertexAttribPointer(attribs['a_p0'], 3, gl.FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P0);\n    gl.vertexAttribPointer(attribs['a_p1'], 3, gl.FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P1);\n    gl.vertexAttribPointer(attribs['a_p2'], 3, gl.FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P2);\n    gl.vertexAttribPointer(attribs['a_p3'], 3, gl.FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P3);\n    gl.vertexAttribPointer(attribs['a_health'], 1, gl.FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_HEALTH);\n    gl.vertexAttribPointer(attribs['a_color'], 4, gl.UNSIGNED_BYTE, true, BYTES_PER_OBJECT, BYTE_OFFSET_COLOR);\n    gl.vertexAttribPointer(attribs['a_tail'], 1, gl.UNSIGNED_BYTE, false, BYTES_PER_OBJECT, BYTE_OFFSET_TAIL);\n    gl.vertexAttribPointer(attribs['a_leftRightTop'], 3, gl.UNSIGNED_BYTE, false, BYTES_PER_OBJECT, BYTE_OFFSET_LEFT_RIGHT_TOP);\n\n    instancedArrays.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, alive);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/geoset.ts",
    "content": "import Shader from '../../gl/shader';\nimport MdxModel from './model';\nimport GeosetAnimation from './geosetanimation';\nimport { SkinningType } from './batch';\n\n/**\n * A geoset.\n */\nexport default class Geoset {\n  model: MdxModel;\n  index: number;\n  positionOffset: number;\n  normalOffset: number;\n  uvOffset: number;\n  tangentOffset: number;\n  skinOffset: number;\n  faceOffset: number;\n  vertices: number;\n  elements: number;\n  faceType: number;\n  geosetAnimation: GeosetAnimation | null = null;\n\n  constructor(model: MdxModel, index: number, positionOffset: number, normalOffset: number, uvOffset: number, tangentOffset: number, skinOffset: number, faceOffset: number, vertices: number, elements: number, faceType: number) {\n    this.model = model;\n    this.index = index;\n    this.positionOffset = positionOffset;\n    this.normalOffset = normalOffset;\n    this.uvOffset = uvOffset;\n    this.tangentOffset = tangentOffset;\n    this.skinOffset = skinOffset;\n    this.faceOffset = faceOffset;\n    this.vertices = vertices;\n    this.elements = elements;\n    this.faceType = faceType;\n\n    for (const geosetAnimation of model.geosetAnimations) {\n      if (geosetAnimation.geosetId === index) {\n        this.geosetAnimation = geosetAnimation;\n      }\n    }\n  }\n\n  bindShared(gl: WebGLRenderingContext, attribs: {[key: string]: number }, coordId: number): void {\n    gl.vertexAttribPointer(attribs['a_position'], 3, gl.FLOAT, false, 0, this.positionOffset);\n    gl.vertexAttribPointer(attribs['a_normal'], 3, gl.FLOAT, false, 0, this.normalOffset);\n    gl.vertexAttribPointer(attribs['a_uv'], 2, gl.FLOAT, false, 0, this.uvOffset + coordId * this.vertices * 8);\n  }\n\n  bindVertexGroups(gl: WebGLRenderingContext, attribs: {[key: string]: number }): void {\n    const model = this.model;\n    const skinDataType = model.skinDataType;\n    const bytesPerSkinElement = model.bytesPerSkinElement;\n\n    gl.vertexAttribPointer(attribs['a_bones'], 4, skinDataType, false, 5 * bytesPerSkinElement, this.skinOffset);\n    gl.vertexAttribPointer(attribs['a_boneNumber'], 1, skinDataType, false, 5 * bytesPerSkinElement, this.skinOffset + 4 * bytesPerSkinElement);\n  }\n\n  bindVertexGroupsExtended(gl: WebGLRenderingContext, attribs: {[key: string]: number }): void {\n    const model = this.model;\n    const skinDataType = model.skinDataType;\n    const bytesPerSkinElement = model.bytesPerSkinElement;\n\n    gl.vertexAttribPointer(attribs['a_bones'], 4, skinDataType, false, 9 * bytesPerSkinElement, this.skinOffset);\n    gl.vertexAttribPointer(attribs['a_extendedBones'], 4, skinDataType, false, 9 * bytesPerSkinElement, this.skinOffset + 4 * bytesPerSkinElement);\n    gl.vertexAttribPointer(attribs['a_boneNumber'], 1, skinDataType, false, 9 * bytesPerSkinElement, this.skinOffset + 8 * bytesPerSkinElement);\n  }\n\n  bindSkin(gl: WebGLRenderingContext, attribs: {[key: string]: number }): void {\n    gl.vertexAttribPointer(attribs['a_bones'], 4, gl.UNSIGNED_BYTE, false, 8, this.skinOffset);\n    gl.vertexAttribPointer(attribs['a_weights'], 4, gl.UNSIGNED_BYTE, true, 8, this.skinOffset + 4);\n  }\n\n  bind(shader: Shader, coordId: number): void {\n    const gl = this.model.viewer.gl;\n    const attribs = shader.attribs;\n\n    this.bindShared(gl, attribs, coordId);\n    if (attribs['a_weights'] !== undefined) {\n      this.bindSkin(gl, attribs);\n    } else {\n      this.bindVertexGroups(gl, attribs);\n    }\n  }\n\n  bindExtended(shader: Shader, coordId: number): void{\n    const gl = this.model.viewer.gl;\n    const attribs = shader.attribs;\n\n    this.bindShared(gl, attribs, coordId);\n    this.bindVertexGroupsExtended(gl, attribs);\n  }\n\n  bindHd(shader: Shader, skinningType: SkinningType, coordId: number): void {\n    const gl = this.model.viewer.gl;\n    const attribs = shader.attribs;\n\n    this.bindShared(gl, attribs, coordId);\n\n    gl.vertexAttribPointer(attribs['a_tangent'], 4, gl.FLOAT, false, 0, this.tangentOffset);\n\n    if (skinningType === SkinningType.Skin) {\n      this.bindSkin(gl, attribs);\n    } else if (skinningType === SkinningType.ExtendedVertexGroups) {\n      this.bindVertexGroupsExtended(gl, attribs);\n    } else {\n      this.bindVertexGroups(gl, attribs);\n    }\n  }\n\n  render(): void {\n    const gl = this.model.viewer.gl;\n\n    gl.drawElements(this.faceType, this.elements, gl.UNSIGNED_SHORT, this.faceOffset);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/geosetanimation.ts",
    "content": "import { vec3 } from 'gl-matrix';\nimport MdlxGeosetAnimation from '../../../parsers/mdlx/geosetanimation';\nimport AnimatedObject from './animatedobject';\nimport MdxModel from './model';\n\n/**\n * A geoset animation.\n */\nexport default class GeosetAnimation extends AnimatedObject {\n  alpha: number;\n  color: vec3;\n  geosetId: number;\n\n  constructor(model: MdxModel, geosetAnimation: MdlxGeosetAnimation) {\n    super(model, geosetAnimation);\n\n    const color = geosetAnimation.color;\n\n    this.alpha = geosetAnimation.alpha;\n    this.color = vec3.fromValues(color[2], color[1], color[0]); // Stored as RGB, but animated colors are stored as BGR, so sizzle.\n    this.geosetId = geosetAnimation.geosetId;\n\n    this.addVariants('KGAO', 'alpha');\n    this.addVariants('KGAC', 'color');\n  }\n\n  getAlpha(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KGAO', sequence, frame, counter, this.alpha);\n  }\n\n  getColor(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KGAC', sequence, frame, counter, <Float32Array>this.color);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/handler.ts",
    "content": "import { extname } from '../../../common/path';\nimport { FetchDataType } from '../../../common/fetchdatatype';\nimport { decodeAudioData } from '../../../common/audio';\nimport MdlxModel from '../../../parsers/mdlx/model';\nimport { isMdx, isMdl } from '../../../parsers/mdlx/isformat';\nimport { MappedData, MappedDataRow } from '../../../utils/mappeddata';\nimport ModelViewer, { DebugRenderMode } from '../../viewer';\nimport Shader from '../../gl/shader';\nimport { PathSolver, SolverParams } from '../../handlerresource';\nimport { Resource } from '../../resource';\nimport GenericResource from '../../genericresource';\nimport Texture from '../../texture';\nimport Model from './model';\nimport MdxTexture from './texture';\nimport sdVert from './shaders/sd.vert';\nimport sdFrag from './shaders/sd.frag';\nimport hdVert from './shaders/hd.vert';\nimport hdFrag from './shaders/hd.frag';\nimport particlesVert from './shaders/particles.vert';\nimport particlesFrag from './shaders/particles.frag';\nimport { SkinningType } from './batch';\nimport { WrapMode } from '../../../parsers/mdlx/texture';\n\nexport interface EventObjectData {\n  row: MappedDataRow;\n  resources: Resource[];\n}\n\nexport interface MdxHandlerObject {\n  pathSolver?: PathSolver;\n  reforged: boolean;\n  sdShader: Shader;\n  sdSkinShader: Shader;\n  sdExtendedShader: Shader;\n  hdShader: Shader;\n  hdExtendedShader: Shader;\n  hdSkinShader: Shader;\n  particlesShader: Shader;\n  sdDebugShaders: Shader[][];\n  hdDebugShaders: Shader[][];\n  rectBuffer: WebGLBuffer;\n  teamColors: MdxTexture[];\n  teamGlows: MdxTexture[];\n  eventObjectTables: {[key: string]: GenericResource[] };\n\n  // lutTexture: MdxTexture | null;\n  // envDiffuseTexture: MdxTexture | null;\n  // envSpecularTexture: MdxTexture | null;\n}\n\nconst mappedDataCallback = (data: FetchDataType): MappedData => new MappedData(<string>data);\nconst decodedDataCallback = (data: FetchDataType): Promise<AudioBuffer | undefined> => decodeAudioData(<ArrayBuffer>data);\n\nexport default {\n  load(viewer: ModelViewer, pathSolver?: PathSolver, reforged = false): void {\n    const gl = viewer.gl;\n    const webgl = viewer.webgl;\n\n    // Bone textures.\n    if (!webgl.ensureExtension('OES_texture_float')) {\n      throw new Error('MDX: No float texture support!');\n    }\n\n    // Geometry emitters.\n    if (!webgl.ensureExtension('ANGLE_instanced_arrays')) {\n      throw new Error('MDX: No instanced rendering support!');\n    }\n\n    // Shaders. Lots of them.\n    const sdExtendedVert = '#define EXTENDED_BONES\\n' + sdVert;\n    const sdDiffuse = '#define ONLY_DIFFUSE\\n' + sdFrag;\n    const sdTexcoords = '#define ONLY_TEXCOORDS\\n' + sdFrag;\n    const sdNormals = '#define ONLY_NORMALS\\n' + sdFrag;\n    const hdExtendedVert = '#define EXTENDED_BONES\\n' + hdVert;\n    const hdSkinVert = '#define SKIN\\n' + hdVert;\n    const hdDiffuse = '#define ONLY_DIFFUSE\\n' + hdFrag;\n    const hdNormalMap = '#define ONLY_NORMAL_MAP\\n' + hdFrag;\n    const hdOcclusion = '#define ONLY_OCCLUSION\\n' + hdFrag;\n    const hdRoughness = '#define ONLY_ROUGHNESS\\n' + hdFrag;\n    const hdMetallic = '#define ONLY_METALLIC\\n' + hdFrag;\n    const hdTCFactor = '#define ONLY_TC_FACTOR\\n' + hdFrag;\n    const hdEmissive = '#define ONLY_EMISSIVE\\n' + hdFrag;\n    const hdTexCoords = '#define ONLY_TEXCOORDS\\n' + hdFrag;\n    const hdNormals = '#define ONLY_NORMALS\\n' + hdFrag;\n    const hdTangents = '#define ONLY_TANGENTS\\n' + hdFrag;\n    \n    const sdShader = webgl.createShader(sdVert, sdFrag);\n    const sdExtendedShader = webgl.createShader(sdExtendedVert, sdFrag);\n    const sdSkinVert = '#define SKIN\\n' + sdVert;\n    const sdSkinShader = webgl.createShader(sdSkinVert, sdFrag);\n    const hdShader = webgl.createShader(hdVert, hdFrag);\n    const hdExtendedShader = webgl.createShader(hdExtendedVert, hdFrag);\n    const hdSkinShader = webgl.createShader(hdSkinVert, hdFrag);\n    const particlesShader = webgl.createShader(particlesVert, particlesFrag);\n\n    const sdDebugShaders: Shader[][] = [];\n    const hdDebugShaders: Shader[][] = [];\n\n    let shaders: Shader[] = [];\n    shaders[DebugRenderMode.Diffuse] = webgl.createShader(sdVert, sdDiffuse);\n    shaders[DebugRenderMode.TexCoords] = webgl.createShader(sdVert, sdTexcoords);\n    shaders[DebugRenderMode.Normals] = webgl.createShader(sdVert, sdNormals);\n    sdDebugShaders[SkinningType.VertexGroups] = shaders;\n\n    shaders = [];\n    shaders[DebugRenderMode.Diffuse] = webgl.createShader(sdExtendedVert, sdDiffuse);\n    shaders[DebugRenderMode.TexCoords] = webgl.createShader(sdExtendedVert, sdTexcoords);\n    shaders[DebugRenderMode.Normals] = webgl.createShader(sdExtendedVert, sdNormals);\n    sdDebugShaders[SkinningType.ExtendedVertexGroups] = shaders;\n\n    shaders = [];\n    shaders[DebugRenderMode.Diffuse] = webgl.createShader(hdVert, hdDiffuse);\n    shaders[DebugRenderMode.NormalMap] = webgl.createShader(hdVert, hdNormalMap);\n    shaders[DebugRenderMode.Occlusion] = webgl.createShader(hdVert, hdOcclusion);\n    shaders[DebugRenderMode.Roughness] = webgl.createShader(hdVert, hdRoughness);\n    shaders[DebugRenderMode.Metallic] = webgl.createShader(hdVert, hdMetallic);\n    shaders[DebugRenderMode.TCFactor] = webgl.createShader(hdVert, hdTCFactor);\n    shaders[DebugRenderMode.Emissive] = webgl.createShader(hdVert, hdEmissive);\n    shaders[DebugRenderMode.TexCoords] = webgl.createShader(hdVert, hdTexCoords);\n    shaders[DebugRenderMode.Normals] = webgl.createShader(hdVert, hdNormals);\n    shaders[DebugRenderMode.Tangents] = webgl.createShader('#define ONLY_TANGENTS\\n' + hdVert, hdTangents);\n    hdDebugShaders[SkinningType.VertexGroups] = shaders;\n\n    shaders = [];\n    shaders[DebugRenderMode.Diffuse] = webgl.createShader(hdExtendedVert, hdDiffuse);\n    shaders[DebugRenderMode.NormalMap] = webgl.createShader(hdExtendedVert, hdNormalMap);\n    shaders[DebugRenderMode.Occlusion] = webgl.createShader(hdExtendedVert, hdOcclusion);\n    shaders[DebugRenderMode.Roughness] = webgl.createShader(hdExtendedVert, hdRoughness);\n    shaders[DebugRenderMode.Metallic] = webgl.createShader(hdExtendedVert, hdMetallic);\n    shaders[DebugRenderMode.TCFactor] = webgl.createShader(hdExtendedVert, hdTCFactor);\n    shaders[DebugRenderMode.Emissive] = webgl.createShader(hdExtendedVert, hdEmissive);\n    shaders[DebugRenderMode.TexCoords] = webgl.createShader(hdExtendedVert, hdTexCoords);\n    shaders[DebugRenderMode.Normals] = webgl.createShader(hdExtendedVert, hdNormals);\n    shaders[DebugRenderMode.Tangents] = webgl.createShader('#define ONLY_TANGENTS\\n' + hdExtendedVert, hdTangents);\n    hdDebugShaders[SkinningType.ExtendedVertexGroups] = shaders;\n\n    shaders = [];\n    shaders[DebugRenderMode.Diffuse] = webgl.createShader(hdSkinVert, hdDiffuse);\n    shaders[DebugRenderMode.NormalMap] = webgl.createShader(hdSkinVert, hdNormalMap);\n    shaders[DebugRenderMode.Occlusion] = webgl.createShader(hdSkinVert, hdOcclusion);\n    shaders[DebugRenderMode.Roughness] = webgl.createShader(hdSkinVert, hdRoughness);\n    shaders[DebugRenderMode.Metallic] = webgl.createShader(hdSkinVert, hdMetallic);\n    shaders[DebugRenderMode.TCFactor] = webgl.createShader(hdSkinVert, hdTCFactor);\n    shaders[DebugRenderMode.Emissive] = webgl.createShader(hdSkinVert, hdEmissive);\n    shaders[DebugRenderMode.TexCoords] = webgl.createShader(hdSkinVert, hdTexCoords);\n    shaders[DebugRenderMode.Normals] = webgl.createShader(hdSkinVert, hdNormals);\n    shaders[DebugRenderMode.Tangents] = webgl.createShader('#define ONLY_TANGENTS\\n' + hdSkinVert, hdTangents);\n    hdDebugShaders[SkinningType.Skin] = shaders;\n\n    const rectBuffer = <WebGLBuffer>gl.createBuffer();\n\n    gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([0, 1, 2, 0, 2, 3]), gl.STATIC_DRAW);\n\n    const handlerData: MdxHandlerObject = {\n      pathSolver,\n      reforged,\n      // Shaders.\n      sdShader,\n      sdSkinShader,\n      sdExtendedShader,\n      hdShader,\n      hdExtendedShader,\n      hdSkinShader,\n      particlesShader,\n      sdDebugShaders,\n      hdDebugShaders,\n      // Geometry emitters buffer.\n      rectBuffer,\n      // Team color/glow textures - loaded when the first model that uses team textures is loaded.\n      teamColors: [],\n      teamGlows: [],\n      eventObjectTables: {},\n\n      // lutTexture: null,\n      // envDiffuseTexture: null,\n      // envSpecularTexture: null,\n    };\n\n    viewer.sharedCache.set('mdx', handlerData);\n  },\n  isValidSource(object: unknown): boolean {\n    if (object instanceof MdlxModel) {\n      return true;\n    }\n\n    return isMdx(object) || isMdl(object);\n  },\n  resource: Model,\n  // async loadEnv(viewer: ModelViewer) {\n  //   const mdxHandler = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n\n  //   if (!mdxHandler.lutTexture) {\n  //     mdxHandler.lutTexture = new MdxTexture(0, WrapMode.WrapBoth);\n  //     mdxHandler.envDiffuseTexture = new MdxTexture(0, WrapMode.WrapBoth);\n  //     mdxHandler.envSpecularTexture = new MdxTexture(0, WrapMode.WrapBoth);\n\n  //     const [lutTexture, diffuseTexture, specularTexture] = await Promise.all([\n  //       viewer.load('env/lut.png'),\n  //       viewer.load('env/diffuse-sRGB.png'),\n  //       viewer.load('env/specular-sRGB.png'),\n  //     ]);\n\n  //     mdxHandler.lutTexture.texture = <Texture>lutTexture;\n  //     mdxHandler.envDiffuseTexture.texture = <Texture>diffuseTexture;\n  //     mdxHandler.envSpecularTexture.texture = <Texture>specularTexture;\n  //   }\n\n  // },\n  loadTeamTextures(viewer: ModelViewer): void {\n    const { pathSolver, reforged, teamColors, teamGlows } = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n\n    if (teamColors.length === 0) {\n      const teams = reforged ? 28 : 16;\n      const ext = reforged ? 'dds' : 'blp';\n      const params = reforged ? { reforged: true } : undefined;\n\n      for (let i = 0; i < teams; i++) {\n        const id = `${i}`.padStart(2, '0');\n        const end = `${id}.${ext}`;\n\n        const teamColor = new MdxTexture(1, WrapMode.WrapBoth);\n        const teamGlow = new MdxTexture(2, WrapMode.WrapBoth);\n\n        viewer.load(`ReplaceableTextures\\\\TeamColor\\\\TeamColor${end}`, pathSolver, params)\n          .then((texture) => teamColor.texture = <Texture>texture);\n\n        viewer.load(`ReplaceableTextures\\\\TeamGlow\\\\TeamGlow${end}`, pathSolver, params)\n          .then((texture) => teamGlow.texture = <Texture>texture);\n\n        teamColors[i] = teamColor;\n        teamGlows[i] = teamGlow;\n      }\n    }\n  },\n  getEventObjectSoundFile(file: string, reforged: boolean, isHd: boolean, tables: GenericResource[]): string | undefined {\n    if (!reforged || extname(file) === '.flac') {\n      return file;\n    }\n\n    for (let i = 1, l = tables.length; i < l; i++) {\n      const raceRow = (<MappedData>tables[i].data).getRow(file);\n\n      if (raceRow) {\n        const flags = raceRow.string('Flags');\n        const filePath = raceRow.string('Filepath');\n\n        if (flags === 'SD_ONLY') {\n          if (!isHd) {\n            return filePath;\n          }\n        } else if (flags === 'HD_ONLY') {\n          if (isHd) {\n            return filePath;\n          }\n        } else {\n          return filePath;\n        }\n      }\n    }\n\n    return;\n  },\n  async getEventObjectData(viewer: ModelViewer, type: string, id: string, isHd: boolean): Promise<EventObjectData | undefined> {\n    // Units\\Critters\\BlackStagMale\\BlackStagMale.mdx has an event object named \"Point01\".\n    if (type !== 'SPN' && type !== 'SPL' && type !== 'UBR' && type !== 'SND') {\n      return;\n    }\n\n    const { pathSolver, reforged, eventObjectTables } = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n    const params: SolverParams = reforged ? { reforged: true } : {};\n    const safePathSolver: PathSolver = (src: unknown, params?: SolverParams): unknown => {\n      if (pathSolver) {\n        return pathSolver(src, params);\n      }\n\n      return src;\n    };\n\n    if (!eventObjectTables[type]) {\n      const paths = [];\n\n      if (type === 'SPN') {\n        paths.push('Splats\\\\SpawnData.slk');\n      } else if (type === 'SPL') {\n        paths.push('Splats\\\\SplatData.slk');\n      } else if (type === 'UBR') {\n        paths.push('Splats\\\\UberSplatData.slk');\n      } else if (type === 'SND') {\n        paths.push('UI\\\\SoundInfo\\\\AnimSounds.slk');\n\n        // Reforged changed the data layout.\n        if (reforged) {\n          paths.push(\n            'UI\\\\SoundInfo\\\\DialogueHumanBase.slk',\n            'UI\\\\SoundInfo\\\\DialogueOrcBase.slk',\n            'UI\\\\SoundInfo\\\\DialogueUndeadBase.slk',\n            'UI\\\\SoundInfo\\\\DialogueNightElfBase.slk',\n            'UI\\\\SoundInfo\\\\DialogueNagaBase.slk',\n            'UI\\\\SoundInfo\\\\DialogueDemonBase.slk',\n            'UI\\\\SoundInfo\\\\DialogueCreepsBase.slk');\n        } else {\n          paths.push('UI\\\\SoundInfo\\\\AnimLookups.slk');\n        }\n      }\n\n      const promises = paths.map((path) => viewer.loadGeneric(<string>safePathSolver(path, params), 'text', mappedDataCallback));\n      const resources = await Promise.all(promises);\n\n      for (const resource of resources) {\n        if (!resource) {\n          return;\n        }\n      }\n\n      eventObjectTables[type] = <GenericResource[]>resources;\n    }\n\n    const tables = eventObjectTables[type];\n    const mappedData = <MappedData>tables[0].data;\n    let row: MappedDataRow | undefined;\n    const promises = [];\n\n    if (type === 'SND') {\n      // How to get the sound row?\n      // TFT has AnimLookups.slk, which stores a ID->Label. Give it the event object ID, get back the label to look for in AnimSounds.slk.\n      // Reforged removed AnimLookups.slk, and instead has the ID under a new column in AnimSounds.slk called AnimationEventCode.\n      // In addition, Reforged can have SD/HD flags per sound, to determine whether it should load in SD or HD modes.\n      // When a sound has both modes, the path to it in AnimSounds.slk won't be an actual file path (ending with .flac) but rather a label.\n      // This label can be queried in other sound SLKs such as DialogueHumanBase.slk, which contains the full path and the mentioned flags.\n      if (reforged) {\n        row = mappedData.findRow('AnimationEventCode', id);\n      } else {\n        const lookupRow = (<MappedData>tables[1].data).getRow(id);\n\n        if (lookupRow) {\n          row = mappedData.getRow(<string>lookupRow.string('SoundLabel'));\n        }\n      }\n\n      if (row) {\n        for (const fileName of (<string>row.string('FileNames')).split(',')) {\n          const file = this.getEventObjectSoundFile(fileName, reforged, isHd, tables);\n\n          if (file) {\n            promises.push(viewer.loadGeneric(<string>safePathSolver(file, params), 'arrayBuffer', decodedDataCallback));\n          }\n        }\n      }\n    } else {\n      // Model and texture event objects are simpler than sounds - just get the right model or texture file.\n      row = mappedData.getRow(id);\n\n      if (row) {\n        if (type === 'SPN') {\n          promises.push(viewer.load((<string>row.string('Model')).replace('.mdl', '.mdx'), safePathSolver, params));\n        } else if (type === 'SPL' || type === 'UBR') {\n          promises.push(viewer.load(`ReplaceableTextures\\\\Splats\\\\${row.string('file')}${reforged ? '.dds' : '.blp'}`, safePathSolver, params));\n        }\n      }\n    }\n\n    if (row && promises.length) {\n      const resources = await Promise.all(promises);\n\n      // Make sure the resources actually loaded properly.\n      const filtered = <Resource[]>resources.filter((resource) => resource);\n\n      if (filtered.length) {\n        return { row, resources: filtered };\n      }\n    }\n\n    return;\n  },\n  getBatchShader(viewer: ModelViewer, skinningType: SkinningType, isHd: boolean): Shader {\n    const mdxCache = <MdxHandlerObject>viewer.sharedCache.get('mdx');\n    const debugRenderMode = viewer.debugRenderMode;\n\n    if (isHd) {\n      if (debugRenderMode !== DebugRenderMode.None) {\n        const shaders = mdxCache.hdDebugShaders[skinningType];\n        if (shaders) {\n          const shader = shaders[debugRenderMode];\n          if (shader) {\n            return shader;\n          }\n        }\n      }\n      \n      if (skinningType === SkinningType.Skin) {\n        return mdxCache.hdSkinShader;\n      } else if (skinningType === SkinningType.VertexGroups) {\n        return mdxCache.hdShader;\n      } else {\n        return mdxCache.hdExtendedShader;\n      }\n    } else {\n      if (debugRenderMode !== DebugRenderMode.None) {\n        const shaders = mdxCache.sdDebugShaders[skinningType];\n        if (shaders) {\n          const shader = shaders[debugRenderMode];\n          if (shader) {\n            return shader;\n          }\n        }\n      }\n\n      if (skinningType === SkinningType.Skin) {\n        return mdxCache.sdSkinShader;\n      } else if (skinningType === SkinningType.VertexGroups) {\n        return mdxCache.sdShader;\n      } else {\n        return mdxCache.sdExtendedShader;\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "src/viewer/handlers/mdx/helper.ts",
    "content": "import GenericObject from './genericobject';\n\n/**\n * An MDX helper.\n */\nexport default class Helper extends GenericObject {}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/layer.ts",
    "content": "import MdlxLayer, { FilterMode, Flags } from '../../../parsers/mdlx/layer';\nimport MdxModel from './model';\nimport AnimatedObject from './animatedobject';\nimport TextureAnimation from './textureanimation';\nimport { layerFilterMode } from './filtermode';\nimport Shader from '../../gl/shader';\n\n/**\n * An MDX layer.\n */\nexport default class Layer extends AnimatedObject {\n  index: number;\n  priorityPlane: number;\n  filterMode: FilterMode;\n  textureId = 0;\n  coordId: number;\n  alpha: number;\n  unshaded: number;\n  sphereEnvironmentMap: number;\n  twoSided: number;\n  unfogged: number;\n  noDepthTest: number;\n  noDepthSet: number;\n  depthMaskValue: boolean;\n  blendSrc = 0;\n  blendDst = 0;\n  blended = false;\n  textureAnimation: TextureAnimation | null = null;\n\n  constructor(model: MdxModel, layer: MdlxLayer, layerId: number, priorityPlane: number) {\n    super(model, layer);\n\n    let filterMode = layer.filterMode;\n    const textureAnimationId = layer.textureAnimationId;\n    const gl = model.viewer.gl;\n\n    this.index = layerId;\n    this.priorityPlane = priorityPlane;\n\n    if (filterMode > FilterMode.Modulate2x) {\n      filterMode = FilterMode.Blend;\n    }\n\n    this.filterMode = filterMode;\n\n    if (layer.textureId !== -1) {\n      this.textureId = layer.textureId;\n    }\n\n    this.coordId = layer.coordId;\n    this.alpha = layer.alpha;\n\n    const flags = layer.flags;\n\n    this.unshaded = flags & Flags.Unshaded;\n    this.sphereEnvironmentMap = flags & Flags.SphereEnvMap;\n    this.twoSided = flags & Flags.TwoSided;\n    this.unfogged = flags & Flags.Unfogged;\n    this.noDepthTest = flags & Flags.NoDepthTest;\n    this.noDepthSet = flags & Flags.NoDepthSet;\n\n    this.depthMaskValue = (filterMode === FilterMode.None || filterMode === FilterMode.Transparent);\n\n    if (filterMode > FilterMode.Transparent) {\n      this.blended = true;\n      [this.blendSrc, this.blendDst] = layerFilterMode(filterMode, gl);\n    }\n\n    if (textureAnimationId !== -1) {\n      const textureAnimation = model.textureAnimations[textureAnimationId];\n\n      if (textureAnimation) {\n        this.textureAnimation = textureAnimation;\n      }\n    }\n\n    this.addVariants('KMTA', 'alpha');\n    this.addVariants('KMTF', 'textureId');\n  }\n\n  bind(shader: Shader): void {\n    const gl = this.model.viewer.gl;\n\n    // gl.uniform1f(shader.uniforms.u_unshaded, this.unshaded);\n    gl.uniform1f(shader.uniforms['u_filterMode'], this.filterMode);\n\n    if (this.blended) {\n      gl.enable(gl.BLEND);\n      gl.blendFunc(this.blendSrc, this.blendDst);\n    } else {\n      gl.disable(gl.BLEND);\n    }\n\n    if (this.twoSided) {\n      gl.disable(gl.CULL_FACE);\n    } else {\n      gl.enable(gl.CULL_FACE);\n    }\n\n    if (this.noDepthTest) {\n      gl.disable(gl.DEPTH_TEST);\n    } else {\n      gl.enable(gl.DEPTH_TEST);\n    }\n\n    if (this.noDepthSet) {\n      gl.depthMask(false);\n    } else {\n      gl.depthMask(this.depthMaskValue);\n    }\n  }\n\n  getAlpha(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KMTA', sequence, frame, counter, this.alpha);\n  }\n\n  getTextureId(out: Uint32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KMTF', sequence, frame, counter, this.textureId);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/light.ts",
    "content": "import MdlxLight, { LightType } from '../../../parsers/mdlx/light';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\n\n/**\n * An MDX light.\n */\nexport default class Light extends GenericObject {\n  type: LightType;\n  attenuation: Float32Array;\n  color: Float32Array;\n  intensity: number;\n  ambientColor: Float32Array;\n  ambientIntensity: number;\n\n  constructor(model: MdxModel, light: MdlxLight, index: number) {\n    super(model, light, index);\n\n    this.type = light.type;\n    this.attenuation = light.attenuation;\n    this.color = light.color;\n    this.intensity = light.intensity;\n    this.ambientColor = light.ambientColor;\n    this.ambientIntensity = light.ambientIntensity;\n  }\n\n  getAttenuationStart(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KLAS', sequence, frame, counter, this.attenuation[0]);\n  }\n\n  getAttenuationEnd(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KLAE', sequence, frame, counter, this.attenuation[1]);\n  }\n\n  getIntensity(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KLAI', sequence, frame, counter, this.intensity);\n  }\n\n  getColor(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KLAC', sequence, frame, counter, this.color);\n  }\n\n  getAmbientIntensity(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KLBI', sequence, frame, counter, this.ambientIntensity);\n  }\n\n  getAmbientColor(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KLBC', sequence, frame, counter, this.ambientColor);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/material.ts",
    "content": "import MdxModel from './model';\nimport Layer from './layer';\n\n/**\n * An MDX material.\n */\nexport default class Material {\n  model: MdxModel;\n  shader: string;\n  layers: Layer[];\n\n  constructor(model: MdxModel, shader: string, layers: Layer[]) {\n    this.model = model;\n    this.shader = shader;\n    this.layers = layers;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/model.ts",
    "content": "\nimport Parser from '../../../parsers/mdlx/model';\nimport Sequence from './sequence';\nimport { HandlerResourceData } from '../../handlerresource';\nimport Model from '../../model';\nimport Texture from '../../texture';\nimport mdxHandler from './handler';\nimport TextureAnimation from './textureanimation';\nimport Layer from './layer';\nimport Material from './material';\nimport GeosetAnimation from './geosetanimation';\nimport replaceableIds from './replaceableids';\nimport Bone from './bone';\nimport Light from './light';\nimport Helper from './helper';\nimport Attachment from './attachment';\nimport ParticleEmitterObject from './particleemitterobject';\nimport ParticleEmitter2Object from './particleemitter2object';\nimport RibbonEmitterObject from './ribbonemitterobject';\nimport Camera from './camera';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\nimport CollisionShape from './collisionshape';\nimport setupGeosets from './setupgeosets';\nimport setupGroups from './setupgroups';\nimport BatchGroup from './batchgroup';\nimport EmitterGroup from './emittergroup';\nimport GenericObject from './genericobject';\nimport { Batch } from './batch';\nimport Geoset from './geoset';\nimport MdxModelInstance from './modelinstance';\nimport MdxTexture from './texture';\n\n/**\n * An MDX model.\n */\nexport default class MdxModel extends Model {\n  reforged = false;\n  hd = false;\n  solverParams: { reforged?: boolean, hd?: boolean } = {};\n  name = '';\n  sequences: Sequence[] = [];\n  globalSequences: number[] = [];\n  materials: Material[] = [];\n  layers: Layer[] = [];\n  textures: MdxTexture[] = [];\n  textureAnimations: TextureAnimation[] = [];\n  geosets: Geoset[] = [];\n  geosetAnimations: GeosetAnimation[] = [];\n  bones: Bone[] = [];\n  lights: Light[] = [];\n  helpers: Helper[] = [];\n  attachments: Attachment[] = [];\n  pivotPoints: Float32Array[] = [];\n  particleEmitters: ParticleEmitterObject[] = [];\n  particleEmitters2: ParticleEmitter2Object[] = [];\n  ribbonEmitters: RibbonEmitterObject[] = [];\n  cameras: Camera[] = [];\n  eventObjects: EventObjectEmitterObject[] = [];\n  collisionShapes: CollisionShape[] = [];\n  hasLayerAnims = false;\n  hasGeosetAnims = false;\n  batches: Batch[] = [];\n  genericObjects: GenericObject[] = [];\n  sortedGenericObjects: GenericObject[] = [];\n  hierarchy: number[] = [];\n  opaqueGroups: BatchGroup[] = [];\n  translucentGroups: (BatchGroup | EmitterGroup)[] = [];\n  arrayBuffer: WebGLBuffer | null = null;\n  elementBuffer: WebGLBuffer | null = null;\n  skinDataType = 0;\n  bytesPerSkinElement = 1;\n\n  constructor(bufferOrParser: ArrayBuffer | string | Parser, resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    let parser;\n\n    if (bufferOrParser instanceof Parser) {\n      parser = bufferOrParser;\n    } else {\n      parser = new Parser();\n\n      try {\n        parser.load(bufferOrParser);\n      } catch (e) {\n        // If we get here, the parser failed to load.\n        // It still may have loaded enough data to support rendering though!\n        // I have encountered a model that is missing data, but still works in-game.\n        // So just let the code continue.\n        // If the handler manages to load the model, nothing happened.\n        // If critical data is missing, it will fail and throw its own exception.\n      }\n    }\n\n    const viewer = this.viewer;\n    const pathSolver = this.pathSolver;\n    const solverParams = this.solverParams;\n    const reforged = parser.version > 800;\n    const texturesExt = reforged ? '.dds' : '.blp';\n    let hasTeamColors = false;\n\n    this.reforged = reforged;\n    this.name = parser.name;\n\n    // Initialize the bounds.\n    const extent = parser.extent;\n    this.bounds.fromExtents(extent.min, extent.max);\n\n    // Sequences\n    for (const sequence of parser.sequences) {\n      this.sequences.push(new Sequence(sequence));\n    }\n\n    // Global sequences\n    for (const globalSequence of parser.globalSequences) {\n      this.globalSequences.push(globalSequence);\n    }\n\n    // Texture animations\n    for (const textureAnimation of parser.textureAnimations) {\n      this.textureAnimations.push(new TextureAnimation(this, textureAnimation));\n    }\n\n    // Materials\n    let layerId = 0;\n    for (const material of parser.materials) {\n      const layers = [];\n\n      for (const layer of material.layers) {\n        const vLayer = new Layer(this, layer, layerId++, material.priorityPlane);\n\n        layers.push(vLayer);\n\n        this.layers.push(vLayer);\n      }\n\n      this.materials.push(new Material(this, material.shader, layers));\n\n      if (material.shader !== '') {\n        this.hd = true;\n      }\n    }\n\n    if (reforged) {\n      solverParams.reforged = true;\n    }\n\n    if (this.hd) {\n      solverParams.hd = true;\n\n      // mdxHandler.loadEnv(viewer);\n    }\n\n    // Textures.\n    const textures = parser.textures;\n    for (let i = 0, l = textures.length; i < l; i++) {\n      const texture = textures[i];\n      let path = texture.path;\n      const replaceableId = texture.replaceableId;\n      const wrapMode = texture.wrapMode;\n\n      if (path === '' && replaceableId !== 0) {\n        path = `ReplaceableTextures\\\\${replaceableIds[replaceableId]}${texturesExt}`;\n\n        if (replaceableId === 1 || replaceableId === 2) {\n          hasTeamColors = true;\n        }\n      }\n\n      const mdxTexture = new MdxTexture(replaceableId, wrapMode);\n\n      viewer.load(path, pathSolver, solverParams)\n        .then((texture) => {\n          if (texture) {\n            mdxTexture.texture = <Texture>texture;\n          }\n        });\n\n      this.textures[i] = mdxTexture;\n    }\n\n    // Geoset animations\n    for (const geosetAnimation of parser.geosetAnimations) {\n      this.geosetAnimations.push(new GeosetAnimation(this, geosetAnimation));\n    }\n\n    this.pivotPoints = parser.pivotPoints;\n\n    // Tracks the IDs of all generic objects.\n    let objectId = 0;\n\n    // Bones\n    for (const bone of parser.bones) {\n      this.bones.push(new Bone(this, bone, objectId++));\n    }\n\n    // Lights\n    for (const light of parser.lights) {\n      this.lights.push(new Light(this, light, objectId++));\n    }\n\n    // Helpers\n    for (const helper of parser.helpers) {\n      this.helpers.push(new Helper(this, helper, objectId++));\n    }\n\n    // Attachments\n    for (const attachment of parser.attachments) {\n      this.attachments.push(new Attachment(this, attachment, objectId++));\n    }\n\n    // Particle emitters\n    for (const particleEmitter of parser.particleEmitters) {\n      this.particleEmitters.push(new ParticleEmitterObject(this, particleEmitter, objectId++));\n    }\n\n    // Particle emitters 2\n    for (const particleEmitter2 of parser.particleEmitters2) {\n      const emitter = new ParticleEmitter2Object(this, particleEmitter2, objectId++);\n\n      this.particleEmitters2.push(emitter);\n\n      if (emitter.teamColored) {\n        hasTeamColors = true;\n      }\n    }\n\n    // Ribbon emitters\n    for (const ribbonEmitter of parser.ribbonEmitters) {\n      this.ribbonEmitters.push(new RibbonEmitterObject(this, ribbonEmitter, objectId++));\n    }\n\n    // Cameras\n    for (const camera of parser.cameras) {\n      this.cameras.push(new Camera(this, camera));\n    }\n\n    // Event objects\n    for (const eventObject of parser.eventObjects) {\n      this.eventObjects.push(new EventObjectEmitterObject(this, eventObject, objectId++));\n    }\n\n    // Collision shapes\n    for (const collisionShape of parser.collisionShapes) {\n      this.collisionShapes.push(new CollisionShape(this, collisionShape, objectId++));\n    }\n\n    // One array for all generic objects.\n    this.genericObjects.push(...this.bones, ...this.lights, ...this.helpers, ...this.attachments, ...this.particleEmitters, ...this.particleEmitters2, ...this.ribbonEmitters, ...this.eventObjects, ...this.collisionShapes);\n\n    // Geosets\n    setupGeosets(this, parser.geosets);\n\n    // Render groups.\n    setupGroups(this);\n\n    // Creates the sorted indices array of the generic objects.\n    this.setupHierarchy(-1);\n\n    // Keep a sorted array.\n    for (let i = 0, l = this.genericObjects.length; i < l; i++) {\n      this.sortedGenericObjects[i] = this.genericObjects[this.hierarchy[i]];\n    }\n\n    // Lazy loading team colors.\n    if (hasTeamColors) {\n      mdxHandler.loadTeamTextures(viewer);\n    }\n  }\n\n  addInstance(): MdxModelInstance {\n    return new MdxModelInstance(this);\n  }\n\n  setupHierarchy(parent: number): void {\n    for (let i = 0, l = this.genericObjects.length; i < l; i++) {\n      const object = this.genericObjects[i];\n\n      if (object.parentId === parent) {\n        this.hierarchy.push(i);\n\n        this.setupHierarchy(object.objectId);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/modelinstance.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport ModelInstance from '../../modelinstance';\nimport { createSkeletalNodes, SkeletalNode } from '../../skeletalnode';\nimport DataTexture from '../../gl/datatexture';\nimport Texture from '../../texture';\nimport MdxNode from './node';\nimport AttachmentInstance from './attachmentinstance';\nimport ParticleEmitter from './particleemitter';\nimport ParticleEmitter2 from './particleemitter2';\nimport RibbonEmitter from './ribbonemitter';\nimport EventObjectEmitter from './eventobjectemitter';\nimport EventObjectSpnEmitter from './eventobjectspnemitter';\nimport EventObjectSplEmitter from './eventobjectsplemitter';\nimport EventObjectUbrEmitter from './eventobjectubremitter';\nimport EventObjectSndEmitter from './eventobjectsndemitter';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\nimport { EMITTER_PARTICLE2_TEXTURE_OFFSET, EMITTER_EVENT_TEXTURE_OFFSET } from './geometryemitterfuncs';\nimport Bounds from '../../bounds';\n\nconst visibilityHeap = new Float32Array(1);\nconst translationHeap = vec3.create();\nconst rotationHeap = quat.create();\nconst scaleHeap = vec3.create();\nconst colorHeap = new Float32Array(3);\nconst alphaHeap = new Float32Array(1);\nconst textureIdHeap = new Uint32Array(1);\n\ntype SkeletalNodeObject = AttachmentInstance | ParticleEmitter | ParticleEmitter2 | RibbonEmitter | EventObjectEmitter;\n\n/**\n * An MDX model instance.\n */\nexport default class MdxModelInstance extends ModelInstance {\n  attachments: AttachmentInstance[] = [];\n  particleEmitters: ParticleEmitter[] = [];\n  particleEmitters2: ParticleEmitter2[] = [];\n  ribbonEmitters: RibbonEmitter[] = [];\n  eventObjectEmitters: (EventObjectSpnEmitter | EventObjectSplEmitter | EventObjectUbrEmitter | EventObjectSndEmitter)[] = [];\n  nodes: SkeletalNode[] = [];\n  sortedNodes: SkeletalNode[] = [];\n  frame = 0;\n  // Global sequences\n  counter = 0;\n  sequence = -1;\n  sequenceLoopMode = 0;\n  sequenceEnded = false;\n  teamColor = 0;\n  vertexColor = new Float32Array([1, 1, 1, 1]);\n  // Particles do not spawn when the sequence is -1, or when the sequence finished and it's not repeating\n  allowParticleSpawn = false;\n  // If forced is true, everything will update regardless of variancy.\n  // Any later non-forced update can then use variancy to skip updating things.\n  // It is set to true every time the sequence is set with setSequence().\n  forced = true;\n  geosetColors: Float32Array[] = [];\n  layerAlphas: number[] = [];\n  layerTextures: number[] = [];\n  uvAnims: Float32Array[] = [];\n  worldMatrices: Float32Array | null = null;\n  boneTexture: DataTexture | null = null;\n\n  constructor(model: MdxModel) {\n    super(model);\n\n    for (let i = 0, l = model.geosets.length; i < l; i++) {\n      this.geosetColors[i] = new Float32Array(4);\n    }\n\n    for (let i = 0, l = model.layers.length; i < l; i++) {\n      this.layerAlphas[i] = 0;\n      this.layerTextures[i] = 0;\n      this.uvAnims[i] = new Float32Array(5);\n    }\n\n    // Create the needed amount of shared nodes.\n    const sharedNodeData = createSkeletalNodes(model.genericObjects.length, MdxNode);\n    const nodes = sharedNodeData.nodes;\n    let nodeIndex = 0;\n\n    this.nodes.push(...nodes);\n\n    // A shared typed array for all world matrices of the internal nodes.\n    this.worldMatrices = sharedNodeData.worldMatrices;\n\n    // And now initialize all of the nodes and objects\n    for (const bone of model.bones) {\n      this.initNode(nodes, nodes[nodeIndex++], bone);\n    }\n\n    for (const light of model.lights) {\n      this.initNode(nodes, nodes[nodeIndex++], light);\n    }\n\n    for (const helper of model.helpers) {\n      this.initNode(nodes, nodes[nodeIndex++], helper);\n    }\n\n    for (const attachment of model.attachments) {\n      let attachmentInstance;\n\n      // Attachments may have game models attached to them, such as Undead and Nightelf building animations.\n      if (attachment.internalModel) {\n        attachmentInstance = new AttachmentInstance(this, attachment);\n\n        this.attachments.push(attachmentInstance);\n      }\n\n      this.initNode(nodes, nodes[nodeIndex++], attachment, attachmentInstance);\n    }\n\n    for (const emitterObject of model.particleEmitters) {\n      const emitter = new ParticleEmitter(this, emitterObject);\n\n      this.particleEmitters.push(emitter);\n\n      this.initNode(nodes, nodes[nodeIndex++], emitterObject, emitter);\n    }\n\n    for (const emitterObject of model.particleEmitters2) {\n      const emitter = new ParticleEmitter2(this, emitterObject);\n\n      this.particleEmitters2.push(emitter);\n\n      this.initNode(nodes, nodes[nodeIndex++], emitterObject, emitter);\n    }\n\n    for (const emitterObject of model.ribbonEmitters) {\n      const emitter = new RibbonEmitter(this, emitterObject);\n\n      this.ribbonEmitters.push(emitter);\n\n      this.initNode(nodes, nodes[nodeIndex++], emitterObject, emitter);\n    }\n\n    for (const emitterObject of model.eventObjects) {\n      const type = emitterObject.type;\n      let emitter;\n\n      if (type === 'SPN') {\n        emitter = new EventObjectSpnEmitter(this, emitterObject);\n      } else if (type === 'SPL') {\n        emitter = new EventObjectSplEmitter(this, emitterObject);\n      } else if (type === 'UBR') {\n        emitter = new EventObjectUbrEmitter(this, emitterObject);\n      } else {\n        emitter = new EventObjectSndEmitter(this, emitterObject);\n      }\n\n      this.eventObjectEmitters.push(emitter);\n\n      this.initNode(nodes, nodes[nodeIndex++], emitterObject, emitter);\n    }\n\n    for (const collisionShape of model.collisionShapes) {\n      this.initNode(nodes, nodes[nodeIndex++], collisionShape);\n    }\n\n    // Save a sorted array of all of the nodes, such that every child node comes after its parent.\n    // This allows for flat iteration when updating.\n    const hierarchy = model.hierarchy;\n\n    for (let i = 0, l = nodes.length; i < l; i++) {\n      this.sortedNodes[i] = nodes[hierarchy[i]];\n    }\n\n    if (model.bones.length) {\n      this.boneTexture = new DataTexture(model.viewer.gl, 4, model.bones.length * 4, 1);\n    }\n  }\n\n\n  /**\n   * Override the texture at the given index.\n   * \n   * If a texture isn't given, removes the override if there was one.\n   */\n  setTexture(index: number, texture?: Texture): void {\n    this.overrideTexture(index, texture);\n  }\n\n  /**\n   * Override the texture of the particle emitter the given index.\n   * \n   * If a texture isn't given, removes the override if there was one.\n   */\n  setParticle2Texture(index: number, texture?: Texture): void {\n    this.overrideTexture(EMITTER_PARTICLE2_TEXTURE_OFFSET + index, texture);\n  }\n\n  /**\n   * Override the texture of the event emitter the given index.\n   * \n   * If a texture isn't given, removes the override if there was one.\n   */\n  setEventTexture(index: number, texture?: Texture): void {\n    this.overrideTexture(EMITTER_EVENT_TEXTURE_OFFSET + index, texture);\n  }\n\n  /**\n   * Clear all of the emitted objects that belong to this instance.\n   */\n  override clearEmittedObjects(): void {\n    for (const emitter of this.particleEmitters) {\n      emitter.clear();\n    }\n\n    for (const emitter of this.particleEmitters2) {\n      emitter.clear();\n    }\n\n    for (const emitter of this.ribbonEmitters) {\n      emitter.clear();\n    }\n\n    for (const emitter of this.eventObjectEmitters) {\n      emitter.clear();\n    }\n  }\n\n  /**\n   * Initialize a skeletal node.\n   */\n  initNode(nodes: SkeletalNode[], node: SkeletalNode, genericObject: GenericObject, object?: SkeletalNodeObject): void {\n    vec3.copy(node.pivot, genericObject.pivot);\n\n    if (genericObject.parentId === -1) {\n      node.parent = this;\n    } else {\n      node.parent = nodes[genericObject.parentId];\n    }\n\n    node.dontInheritTranslation = genericObject.dontInheritTranslation;\n    node.dontInheritRotation = genericObject.dontInheritRotation;\n    node.dontInheritScaling = genericObject.dontInheritScaling;\n    \n    if (genericObject.billboarded) {\n      node.billboarded = true;\n    } else if (genericObject.billboardedX) {\n      node.billboardedX = true;\n    } else if (genericObject.billboardedY) {\n      node.billboardedY = true;\n    } else if (genericObject.billboardedZ) {\n      node.billboardedZ = true;\n    }\n\n    if (object) {\n      node.object = object;\n    }\n  }\n\n  /**\n   * Overriden to hide also attachment models.\n   */\n  override hide(): void {\n    super.hide();\n\n    this.resetAttachments();\n  }\n\n  /**\n   * Updates all of this instance internal nodes and objects.\n   * Nodes that are determined to not be visible will not be updated, nor will any of their children down the hierarchy.\n   */\n  updateNodes(dt: number, forced: boolean): void {\n    const sequence = this.sequence;\n    const frame = this.frame;\n    const counter = this.counter;\n    const sortedNodes = this.sortedNodes;\n    const model = <MdxModel>this.model;\n    const sortedGenericObjects = model.sortedGenericObjects;\n\n    // Update the nodes\n    for (let i = 0, l = sortedNodes.length; i < l; i++) {\n      const genericObject = sortedGenericObjects[i];\n      const node = sortedNodes[i];\n      const parent = <MdxNode | SkeletalNode>node.parent;\n      let wasDirty = forced || parent.wasDirty || genericObject.anyBillboarding;\n      const variants = genericObject.variants;\n\n      // Local node transformation.\n      // Use variants to skip animation data when possible.\n      if (forced || variants['generic'][sequence]) {\n        wasDirty = true;\n\n        // Translation\n        if (forced || variants['translation'][sequence]) {\n          genericObject.getTranslation(node.localLocation, sequence, frame, counter);\n        }\n\n        // Rotation\n        if (forced || variants['rotation'][sequence]) {\n          genericObject.getRotation(node.localRotation, sequence, frame, counter);\n        }\n\n        // Scale\n        if (forced || variants['scale'][sequence]) {\n          genericObject.getScale(node.localScale, sequence, frame, counter);\n        }\n      }\n\n      node.wasDirty = wasDirty;\n\n      // If this is a forced update, or this node's local data was updated, or the parent node was updated, do a full world update.\n      if (wasDirty) {\n        node.recalculateTransformation(this);\n      }\n\n      // If there is an instance object associated with this node (emitter/attachment), and it is visible, update it.\n      if (node.object) {\n        genericObject.getVisibility(visibilityHeap, sequence, frame, counter);\n\n        // If the attachment/emitter is visible, update it.\n        if (visibilityHeap[0] > 0) {\n          (<SkeletalNodeObject>node.object).update(dt);\n        }\n      }\n\n      // Recalculate and update child nodes.\n      // Note that this only affects normal nodes such as instances, and not skeletal nodes.\n      for (const child of node.children) {\n        if (wasDirty) {\n          child.recalculateTransformation();\n        }\n\n        child.update(dt);\n      }\n    }\n  }\n\n  /**\n   * If a model has no sequences or is running no sequence, it will only update once since it will never be forced to update.\n   * This is generally the desired behavior, except when it is moved by the client.\n   * Therefore, if an instance is transformed, always do a forced update.\n   */\n  override recalculateTransformation(): void {\n    super.recalculateTransformation();\n\n    this.forced = true;\n  }\n\n  /**\n   * Update the batch data.\n   */\n  updateBatches(forced: boolean): void {\n    const sequence = this.sequence;\n    const frame = this.frame;\n    const counter = this.counter;\n    const model = <MdxModel>this.model;\n    const geosets = model.geosets;\n    const layers = model.layers;\n    const geosetColors = this.geosetColors;\n    const layerAlphas = this.layerAlphas;\n    const layerTextures = this.layerTextures;\n    const uvAnims = this.uvAnims;\n\n    // Geosets\n    for (let i = 0, l = geosets.length; i < l; i++) {\n      const geoset = geosets[i];\n      const geosetAnimation = geoset.geosetAnimation;\n      const geosetColor = geosetColors[i];\n\n      if (geosetAnimation) {\n        // Color\n        if (forced || geosetAnimation.variants['color'][sequence]) {\n          geosetAnimation.getColor(colorHeap, sequence, frame, counter);\n\n          geosetColor[0] = colorHeap[0];\n          geosetColor[1] = colorHeap[1];\n          geosetColor[2] = colorHeap[2];\n        }\n\n        // Alpha\n        if (forced || geosetAnimation.variants['alpha'][sequence]) {\n          geosetAnimation.getAlpha(alphaHeap, sequence, frame, counter);\n\n          geosetColor[3] = alphaHeap[0];\n        }\n      } else if (forced) {\n        geosetColor[0] = 1;\n        geosetColor[1] = 1;\n        geosetColor[2] = 1;\n        geosetColor[3] = 1;\n      }\n    }\n\n    // Layers\n    for (let i = 0, l = layers.length; i < l; i++) {\n      const layer = layers[i];\n      const textureAnimation = layer.textureAnimation;\n      const uvAnim = uvAnims[i];\n\n      // Alpha\n      if (forced || layer.variants['alpha'][sequence]) {\n        layer.getAlpha(alphaHeap, sequence, frame, counter);\n\n        layerAlphas[i] = alphaHeap[0];\n      }\n\n      // Sprite animation\n      if (forced || layer.variants['textureId'][sequence]) {\n        layer.getTextureId(textureIdHeap, sequence, frame, counter);\n\n        layerTextures[i] = textureIdHeap[0];\n      }\n\n      if (textureAnimation) {\n        // UV translation animation\n        if (forced || textureAnimation.variants['translation'][sequence]) {\n          textureAnimation.getTranslation(<Float32Array>translationHeap, sequence, frame, counter);\n\n          uvAnim[0] = translationHeap[0];\n          uvAnim[1] = translationHeap[1];\n        }\n\n        // UV rotation animation\n        if (forced || textureAnimation.variants['rotation'][sequence]) {\n          textureAnimation.getRotation(<Float32Array>rotationHeap, sequence, frame, counter);\n\n          uvAnim[2] = rotationHeap[2];\n          uvAnim[3] = rotationHeap[3];\n        }\n\n        // UV scale animation\n        if (forced || textureAnimation.variants['scale'][sequence]) {\n          textureAnimation.getScale(<Float32Array>scaleHeap, sequence, frame, counter);\n\n          uvAnim[4] = scaleHeap[0];\n        }\n      } else if (forced) {\n        uvAnim[0] = 0;\n        uvAnim[1] = 0;\n        uvAnim[2] = 0;\n        uvAnim[3] = 1;\n        uvAnim[4] = 1;\n      }\n    }\n  }\n\n  updateBoneTexture(): void {\n    if (this.boneTexture) {\n      this.boneTexture.bindAndUpdate(<Float32Array>this.worldMatrices);\n    }\n  }\n\n  override renderOpaque(): void {\n    const model = <MdxModel>this.model;\n\n    for (const group of model.opaqueGroups) {\n      group.render(this);\n    }\n  }\n\n  override renderTranslucent(): void {\n    const model = <MdxModel>this.model;\n\n    for (const group of model.translucentGroups) {\n      group.render(this);\n    }\n  }\n\n  override updateAnimations(dt: number): void {\n    const model = <MdxModel>this.model;\n    const sequenceId = this.sequence;\n\n    if (sequenceId !== -1) {\n      const sequence = model.sequences[sequenceId];\n      const interval = sequence.interval;\n      const frameTime = dt * 1000;\n\n      this.frame += frameTime;\n      this.counter += frameTime;\n      this.allowParticleSpawn = true;\n\n      if (this.frame >= interval[1]) {\n        if (this.sequenceLoopMode === 2 || (this.sequenceLoopMode === 0 && sequence.nonLooping === 0)) {\n          this.frame = interval[0];\n\n          this.resetEventEmitters();\n        } else {\n          this.frame = interval[1];\n          this.counter -= frameTime;\n          this.allowParticleSpawn = false;\n        }\n\n        this.sequenceEnded = true;\n      } else {\n        this.sequenceEnded = false;\n      }\n    }\n\n    const forced = this.forced;\n\n    if (sequenceId !== -1 || forced) {\n      // Update the nodes\n      this.updateNodes(dt, forced);\n\n      // Update the bone texture.\n      this.updateBoneTexture();\n\n      // Update the batches\n      this.updateBatches(forced);\n    }\n\n    this.forced = false;\n  }\n\n  /**\n   * Set the team color of this instance.\n   */\n  setTeamColor(id: number): this {\n    this.teamColor = id;\n\n    return this;\n  }\n\n  /**\n   * Set the vertex color of this instance.\n   */\n  setVertexColor(color: Float32Array | number[]): this {\n    this.vertexColor.set(color);\n\n    return this;\n  }\n\n  /**\n   * Set the sequence of this instance.\n   */\n  setSequence(id: number): this {\n    const model = <MdxModel>this.model;\n    const sequences = model.sequences;\n\n    this.sequence = id;\n\n    if (id < 0 || id > sequences.length - 1) {\n      this.sequence = -1;\n      this.frame = 0;\n      this.allowParticleSpawn = false;\n    } else {\n      this.frame = sequences[id].interval[0];\n    }\n\n    this.resetEventEmitters();\n    this.resetAttachments();\n\n    this.forced = true;\n\n    return this;\n  }\n\n  override getBounds(): Bounds {\n    const model = <MdxModel>this.model;\n\n    if (this.sequence === -1) {\n      return model.bounds;\n    }\n\n    const bounds = model.sequences[this.sequence].bounds;\n\n    if (bounds.r === 0) {\n      return model.bounds;\n    }\n\n    return bounds;\n  }\n\n  /**\n   * Set the sequence loop mode.\n   * 0 to never loop, 1 to loop based on the model, and 2 to always loop.\n   */\n  setSequenceLoopMode(mode: number): this {\n    this.sequenceLoopMode = mode;\n\n    return this;\n  }\n\n  /**\n   * Get an attachment node.\n   */\n  getAttachment(id: number): SkeletalNode | undefined {\n    const model = <MdxModel>this.model;\n    const attachment = model.attachments[id];\n\n    if (attachment) {\n      return this.nodes[attachment.index];\n    }\n\n    return;\n  }\n\n  resetEventEmitters(): void {\n    for (const emitter of this.eventObjectEmitters) {\n      emitter.lastValue = 0;\n    }\n  }\n\n  resetAttachments(): void {\n    for (const attachment of this.attachments) {\n      attachment.internalInstance.hide();\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/node.ts",
    "content": "import { quat } from 'gl-matrix';\nimport { SkeletalNode } from '../../skeletalnode';\n\n/**\n * An MDX node.\n */\nexport default class MdxNode extends SkeletalNode {\n  override convertBasis(rotation: quat): void {\n    quat.rotateY(rotation, rotation, -Math.PI / 2);\n    quat.rotateX(rotation, rotation, -Math.PI / 2);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/particle.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { VEC3_UNIT_Z } from '../../../common/gl-matrix-addon';\nimport { randomInRange } from '../../../common/math';\nimport Scene from '../../scene';\nimport EmittedObject from '../../emittedobject';\nimport ParticleEmitterObject from './particleemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport ParticleEmitter from './particleemitter';\nimport MdxModel from './model';\n\nconst rotationHeap = quat.create();\nconst velocityHeap = vec3.create();\nconst latitudeHeap = new Float32Array(1);\n// const longitudeHeap = new Float32Array(1);\nconst lifeSpanHeap = new Float32Array(1);\nconst gravityHeap = new Float32Array(1);\nconst speedHeap = new Float32Array(1);\n\n/**\n * A spawned model particle.\n */\nexport default class Particle extends EmittedObject {\n  internalInstance: MdxModelInstance;\n  velocity = vec3.create();\n  gravity = 0;\n\n  constructor(emitter: ParticleEmitter) {\n    super(emitter);\n\n    const emitterObject = <ParticleEmitterObject>emitter.emitterObject;\n    const model = <MdxModel>emitterObject.internalModel;\n\n    this.internalInstance = model.addInstance();\n  }\n\n  bind(): void {\n    const emitter = <ParticleEmitter>this.emitter;\n    const instance = <MdxModelInstance>emitter.instance;\n    const sequence = instance.sequence;\n    const frame = instance.frame;\n    const counter = instance.counter;\n    const scene = <Scene>instance.scene;\n    const emitterObject = <ParticleEmitterObject>emitter.emitterObject;\n    const node = instance.nodes[emitterObject.index];\n    const internalInstance = this.internalInstance;\n    const scale = node.worldScale;\n    const velocity = this.velocity;\n\n    emitterObject.getLatitude(latitudeHeap, sequence, frame, counter);\n    // emitterObject.getLongitude(longitudeHeap, sequence, frame, counter);\n    emitterObject.getLifeSpan(lifeSpanHeap, sequence, frame, counter);\n    emitterObject.getGravity(gravityHeap, sequence, frame, counter);\n    emitterObject.getSpeed(speedHeap, sequence, frame, counter);\n\n    this.health = lifeSpanHeap[0];\n    this.gravity = gravityHeap[0] * scale[2];\n\n    // Local rotation\n    quat.identity(rotationHeap);\n    quat.rotateZ(rotationHeap, rotationHeap, randomInRange(-Math.PI, Math.PI));\n    quat.rotateY(rotationHeap, rotationHeap, randomInRange(-latitudeHeap[0], latitudeHeap[0]));\n    vec3.transformQuat(velocity, VEC3_UNIT_Z, rotationHeap);\n\n    // World rotation\n    vec3.transformQuat(velocity, velocity, node.worldRotation);\n\n    // Apply speed\n    vec3.scale(velocity, velocity, speedHeap[0]);\n\n    // Apply the parent's scale\n    vec3.mul(velocity, velocity, scale);\n\n    internalInstance.setScene(scene);\n    internalInstance.setSequence(0);\n    internalInstance.setTransformation(node.worldLocation, quat.setAxisAngle(rotationHeap, VEC3_UNIT_Z, randomInRange(0, Math.PI * 2)), node.worldScale);\n    internalInstance.show();\n  }\n\n  update(dt: number): void {\n    const internalInstance = this.internalInstance;\n\n    this.health -= dt;\n\n    if (this.health > 0) {\n      const velocity = this.velocity;\n\n      velocity[2] -= this.gravity * dt;\n\n      internalInstance.move(vec3.scale(velocityHeap, velocity, dt));\n    } else {\n      internalInstance.hide();\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/particle2.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { VEC3_UNIT_Z } from '../../../common/gl-matrix-addon';\nimport { degToRad, randomInRange } from '../../../common/math';\nimport EmittedObject from '../../emittedobject';\nimport ParticleEmitter2Object from './particleemitter2object';\nimport ParticleEmitter2 from './particleemitter2';\nimport MdxModelInstance from './modelinstance';\n\nconst rotationHeap = quat.create();\nconst widthHeap = new Float32Array(1);\nconst lengthHeap = new Float32Array(1);\nconst latitudeHeap = new Float32Array(1);\nconst variationHeap = new Float32Array(1);\nconst speedHeap = new Float32Array(1);\nconst gravityHeap = new Float32Array(1);\n\n/**\n * A type 2 particle.\n */\nexport default class Particle2 extends EmittedObject {\n  tail = 0;\n  gravity = 0;\n  location = vec3.create();\n  velocity = vec3.create();\n  scale = vec3.create();\n  facing = 0; // XYQuad\n\n  bind(tail: number): void {\n    const emitter = <ParticleEmitter2>this.emitter;\n    const instance = <MdxModelInstance>emitter.instance;\n    const sequence = instance.sequence;\n    const frame = instance.frame;\n    const counter = instance.counter;\n    const emitterObject = <ParticleEmitter2Object>emitter.emitterObject;\n\n    emitterObject.getWidth(widthHeap, sequence, frame, counter);\n    emitterObject.getLength(lengthHeap, sequence, frame, counter);\n    emitterObject.getLatitude(latitudeHeap, sequence, frame, counter);\n    emitterObject.getVariation(variationHeap, sequence, frame, counter);\n    emitterObject.getSpeed(speedHeap, sequence, frame, counter);\n    emitterObject.getGravity(gravityHeap, sequence, frame, counter);\n\n    const node = emitter.node;\n    const pivot = node.pivot;\n    const scale = node.worldScale;\n    const width = widthHeap[0] * 0.5;\n    const length = lengthHeap[0] * 0.5;\n    const latitude = degToRad(latitudeHeap[0]);\n    const variation = variationHeap[0];\n    const speed = speedHeap[0];\n    const location = this.location;\n    const velocity = this.velocity;\n\n    this.health = emitterObject.lifeSpan;\n    this.tail = tail;\n    this.gravity = gravityHeap[0] * scale[2];\n\n    vec3.copy(this.scale, scale);\n\n    // Local location\n    location[0] = pivot[0] + randomInRange(-width, width);\n    location[1] = pivot[1] + randomInRange(-length, length);\n    location[2] = pivot[2];\n\n    // World location\n    if (!emitterObject.modelSpace) {\n      vec3.transformMat4(location, location, node.worldMatrix);\n    }\n\n    // Local rotation\n    quat.identity(rotationHeap);\n    quat.rotateZ(rotationHeap, rotationHeap, Math.PI / 2);\n    quat.rotateY(rotationHeap, rotationHeap, randomInRange(-latitude, latitude));\n\n    // If this is not a line emitter, emit in a sphere rather than a circle.\n    if (!emitterObject.lineEmitter) {\n      quat.rotateX(rotationHeap, rotationHeap, randomInRange(-latitude, latitude));\n    }\n\n    // World rotation\n    if (!emitterObject.modelSpace) {\n      quat.mul(rotationHeap, node.worldRotation, rotationHeap);\n    }\n\n    // Apply the rotation\n    vec3.transformQuat(velocity, VEC3_UNIT_Z, rotationHeap);\n\n    // Apply speed\n    vec3.scale(velocity, velocity, speed * (1 + randomInRange(-variation, variation)));\n\n    // Apply the parent's scale\n    if (!emitterObject.modelSpace) {\n      vec3.mul(velocity, velocity, scale);\n    }\n\n    // XY particles are rotated to face their velocity on the XY plane.\n    if (emitterObject.xYQuad) {\n      this.facing = Math.atan2(velocity[1], velocity[0]) - Math.PI + Math.PI / 8;\n    }\n  }\n\n  update(dt: number): void {\n    this.health -= dt;\n\n    if (this.health > 0) {\n      const location = this.location;\n      const velocity = this.velocity;\n\n      velocity[2] -= this.gravity * dt;\n\n      location[0] += velocity[0] * dt;\n      location[1] += velocity[1] * dt;\n      location[2] += velocity[2] * dt;\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/particleemitter.ts",
    "content": "import ParticleEmitterObject from './particleemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport MdxEmitter from './emitter';\nimport Particle from './particle';\n\nconst emissionRateHeap = new Float32Array(1);\n\n/**\n * An MDX particle emitter.\n */\nexport default class ParticleEmitter extends MdxEmitter {\n  updateEmission(dt: number): void {\n    const instance = <MdxModelInstance>this.instance;\n\n    if (instance.allowParticleSpawn) {\n      const emitterObject = <ParticleEmitterObject>this.emitterObject;\n\n      emitterObject.getEmissionRate(emissionRateHeap, instance.sequence, instance.frame, instance.counter);\n\n      this.currentEmission += emissionRateHeap[0] * dt;\n    }\n  }\n\n  emit(): void {\n    this.emitObject();\n  }\n\n  createObject(): Particle {\n    return new Particle(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/particleemitter2.ts",
    "content": "import ParticleEmitter2Object from './particleemitter2object';\nimport MdxModelInstance from './modelinstance';\nimport MdxNode from './node';\nimport MdxEmitter from './emitter';\nimport Particle2 from './particle2';\n\nconst emissionRateHeap = new Float32Array(1);\n\n/**\n * An MDX particle emitter type 2.\n */\nexport default class ParticleEmitter2 extends MdxEmitter {\n  node: MdxNode;\n  lastEmissionKey = -1;\n\n  constructor(instance: MdxModelInstance, emitterObject: ParticleEmitter2Object) {\n    super(instance, emitterObject);\n\n    this.node = instance.nodes[emitterObject.index];\n  }\n\n  updateEmission(dt: number): void {\n    const instance = <MdxModelInstance>this.instance;\n\n    if (instance.allowParticleSpawn) {\n      const emitterObject = <ParticleEmitter2Object>this.emitterObject;\n      const keyframe = emitterObject.getEmissionRate(emissionRateHeap, instance.sequence, instance.frame, instance.counter);\n\n      if (emitterObject.squirt) {\n        if (keyframe !== this.lastEmissionKey) {\n          this.currentEmission += emissionRateHeap[0];\n        }\n\n        this.lastEmissionKey = keyframe;\n      } else {\n        this.currentEmission += emissionRateHeap[0] * dt;\n      }\n    }\n  }\n\n  emit(): void {\n    const emitterObject = <ParticleEmitter2Object>this.emitterObject;\n\n    if (emitterObject.head) {\n      this.emitObject(0);\n    }\n\n    if (emitterObject.tail) {\n      this.emitObject(1);\n    }\n  }\n\n  createObject(): Particle2 {\n    return new Particle2(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/particleemitter2object.ts",
    "content": "import MdlxParticleEmitter2, { Flags, HeadOrTail } from '../../../parsers/mdlx/particleemitter2';\nimport Texture from '../../texture';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\nimport { emitterFilterMode } from './filtermode';\nimport replaceableIds from './replaceableids';\nimport { EMITTER_PARTICLE2, SETTING_PARTICLES_HIGH } from './geometryemitterfuncs';\nimport MdxTexture from './texture';\nimport { WrapMode } from '../../../parsers/mdlx/texture';\n\n/**\n * An MDX particle emitter type 2.\n */\nexport default class ParticleEmitter2Object extends GenericObject {\n  geometryEmitterType = EMITTER_PARTICLE2;\n  width: number;\n  length: number;\n  speed: number;\n  latitude: number;\n  gravity: number;\n  emissionRate: number;\n  squirt: number;\n  lifeSpan: number;\n  variation: number;\n  tailLength: number;\n  timeMiddle: number;\n  columns: number;\n  rows: number;\n  teamColored = 0;\n  internalTexture: MdxTexture | null = null;\n  replaceableId: number;\n  textureId: number;\n  head: boolean;\n  tail: boolean;\n  cellWidth: number;\n  cellHeight: number;\n  colors: Float32Array[] = [];\n  scaling: Float32Array;\n  intervals: Float32Array[];\n  filterMode: number;\n  blendSrc: number;\n  blendDst: number;\n  priorityPlane: number;\n  lineEmitter: number;\n  unfogged: number;\n  modelSpace: number;\n  xYQuad: number;\n  /**\n   * Even if the internal texture isn't loaded, it's fine to run emitters based on this emitter object.\n   * \n   * The particles will simply be black.\n   */\n  ok = true;\n\n  constructor(model: MdxModel, emitter: MdlxParticleEmitter2, index: number) {\n    super(model, emitter, index);\n\n    this.width = emitter.width;\n    this.length = emitter.length;\n    this.speed = emitter.speed;\n    this.latitude = emitter.latitude;\n    this.gravity = emitter.gravity;\n    this.emissionRate = emitter.emissionRate * SETTING_PARTICLES_HIGH;\n    this.squirt = emitter.squirt;\n    this.lifeSpan = emitter.lifeSpan;\n    this.variation = emitter.variation;\n    this.tailLength = emitter.tailLength;\n    this.timeMiddle = emitter.timeMiddle;\n\n    const flags = emitter.flags;\n    this.lineEmitter = flags & Flags.LineEmitter;\n    this.unfogged = flags & Flags.Unfogged;\n    this.modelSpace = flags & Flags.ModelSpace;\n    this.xYQuad = flags & Flags.XYQuad;\n\n    const replaceableId = emitter.replaceableId;\n\n    this.columns = emitter.columns;\n    this.rows = emitter.rows;\n\n    if (replaceableId === 1 || replaceableId === 2) {\n      this.teamColored = 1;\n    } else if (replaceableId > 2) {\n      const texturesExt = model.reforged ? '.dds' : '.blp';\n\n      this.internalTexture = new MdxTexture(replaceableId, WrapMode.RepeatBoth);\n\n      model.viewer.load(`ReplaceableTextures\\\\${replaceableIds[replaceableId]}${texturesExt}`, model.pathSolver, model.solverParams)\n        .then((texture) => {\n          if (texture) {\n            (<MdxTexture>this.internalTexture).texture = <Texture>texture;\n          }\n        });\n    }\n\n    this.replaceableId = emitter.replaceableId;\n    this.textureId = emitter.textureId;\n\n    const headOrTail = emitter.headOrTail;\n\n    this.head = (headOrTail === HeadOrTail.Head || headOrTail === HeadOrTail.Both);\n    this.tail = (headOrTail === HeadOrTail.Tail || headOrTail === HeadOrTail.Both);\n\n    this.cellWidth = 1 / emitter.columns;\n    this.cellHeight = 1 / emitter.rows;\n\n    const colors = emitter.segmentColors;\n    const alpha = emitter.segmentAlphas;\n\n    for (let i = 0; i < 3; i++) {\n      const color = colors[i];\n\n      this.colors[i] = new Float32Array([color[0], color[1], color[2], alpha[i] / 255]);\n    }\n\n    this.scaling = emitter.segmentScaling;\n\n    const headIntervals = emitter.headIntervals;\n    const tailIntervals = emitter.tailIntervals;\n\n    // Change to Float32Array instead of Uint32Array to be able to pass the intervals directly using uniform3fv().\n    this.intervals = [\n      new Float32Array(headIntervals[0]),\n      new Float32Array(headIntervals[1]),\n      new Float32Array(tailIntervals[0]),\n      new Float32Array(tailIntervals[1]),\n    ];\n\n    const blendModes = emitterFilterMode(emitter.filterMode, this.model.viewer.gl);\n\n    this.filterMode = emitter.filterMode;\n    this.blendSrc = blendModes[0];\n    this.blendDst = blendModes[1];\n\n    this.priorityPlane = emitter.priorityPlane;\n  }\n\n  getWidth(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2N', sequence, frame, counter, this.width);\n  }\n\n  getLength(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2W', sequence, frame, counter, this.length);\n  }\n\n  getSpeed(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2S', sequence, frame, counter, this.speed);\n  }\n\n  getLatitude(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2L', sequence, frame, counter, this.latitude);\n  }\n\n  getGravity(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2G', sequence, frame, counter, this.gravity);\n  }\n\n  getEmissionRate(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2E', sequence, frame, counter, this.emissionRate);\n  }\n\n  getVariation(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2R', sequence, frame, counter, this.variation);\n  }\n\n  override getVisibility(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KP2V', sequence, frame, counter, 1);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/particleemitterobject.ts",
    "content": "import ParticleEmitter from '../../../parsers/mdlx/particleemitter';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\n\n/**\n * An MDX particle emitter.\n */\nexport default class ParticleEmitterObject extends GenericObject {\n  internalModel: MdxModel | null = null;\n  speed: number;\n  latitude: number;\n  longitude: number;\n  lifeSpan: number;\n  gravity: number;\n  emissionRate: number;\n  ok = false;\n\n  constructor(model: MdxModel, emitter: ParticleEmitter, index: number) {\n    super(model, emitter, index);\n\n    this.speed = emitter.speed;\n    this.latitude = emitter.latitude;\n    this.longitude = emitter.longitude;\n    this.lifeSpan = emitter.lifeSpan;\n    this.gravity = emitter.gravity;\n    this.emissionRate = emitter.emissionRate;\n\n    model.viewer.load(emitter.path.replace(/\\\\/g, '/').toLowerCase().replace('.mdl', '.mdx'), model.pathSolver, model.solverParams)\n      .then((model) => {\n        if (model) {\n          this.internalModel = <MdxModel>model;\n          this.ok = true;\n        }\n      });\n  }\n\n  getSpeed(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPES', sequence, frame, counter, this.speed);\n  }\n\n  getLatitude(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPLTV', sequence, frame, counter, this.latitude);\n  }\n\n  getLongitude(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPLN', sequence, frame, counter, this.longitude);\n  }\n\n  getLifeSpan(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPEL', sequence, frame, counter, this.lifeSpan);\n  }\n\n  getGravity(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPEG', sequence, frame, counter, this.gravity);\n  }\n\n  getEmissionRate(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPEE', sequence, frame, counter, this.emissionRate);\n  }\n\n  override getVisibility(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KPEV', sequence, frame, counter, 1);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/replaceableids.ts",
    "content": "export default {\n  1: 'TeamColor/TeamColor00',\n  2: 'TeamGlow/TeamGlow00',\n  11: 'Cliff/Cliff0',\n  21: '', // Used by all cursor models (HumanCursor, OrcCursor, UndeadCursor, NightElfCursor)\n  31: 'LordaeronTree/LordaeronSummerTree',\n  32: 'AshenvaleTree/AshenTree',\n  33: 'BarrensTree/BarrensTree',\n  34: 'NorthrendTree/NorthTree',\n  35: 'Mushroom/MushroomTree',\n  36: 'RuinsTree/RuinsTree',\n  37: 'OutlandMushroomTree/MushroomTree',\n};\n"
  },
  {
    "path": "src/viewer/handlers/mdx/ribbon.ts",
    "content": "import { vec3 } from 'gl-matrix';\nimport EmittedObject from '../../emittedobject';\nimport RibbonEmitterObject from './ribbonemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport RibbonEmitter from './ribbonemitter';\n\nconst belowHeap = vec3.create();\nconst aboveHeap = vec3.create();\nconst colorHeap = new Float32Array(3);\nconst alphaHeap = new Float32Array(1);\nconst slotHeap = new Uint32Array(1);\n\n/**\n * A ribbon.\n */\nexport default class Ribbon extends EmittedObject {\n  vertices = new Float32Array(6);\n  color = new Uint8Array(4);\n  slot = 0;\n  prev: Ribbon | null = null;\n  next: Ribbon | null = null;\n\n  bind(): void {\n    const emitter = <RibbonEmitter>this.emitter;\n    const instance = <MdxModelInstance>emitter.instance;\n    const sequence = instance.sequence;\n    const frame = instance.frame;\n    const counter = instance.counter;\n    const emitterObject = <RibbonEmitterObject>emitter.emitterObject;\n    const node = instance.nodes[emitterObject.index];\n    const [x, y, z] = node.pivot;\n    const worldMatrix = node.worldMatrix;\n    const vertices = this.vertices;\n\n    this.health = emitter.emitterObject.lifeSpan;\n\n    emitterObject.getHeightBelow(<Float32Array>belowHeap, sequence, frame, counter);\n    emitterObject.getHeightAbove(<Float32Array>aboveHeap, sequence, frame, counter);\n\n    belowHeap[1] = y - belowHeap[0];\n    belowHeap[0] = x;\n    belowHeap[2] = z;\n\n    aboveHeap[1] = y + aboveHeap[0];\n    aboveHeap[0] = x;\n    aboveHeap[2] = z;\n\n    vec3.transformMat4(belowHeap, belowHeap, worldMatrix);\n    vec3.transformMat4(aboveHeap, aboveHeap, worldMatrix);\n\n    vertices[0] = aboveHeap[0];\n    vertices[1] = aboveHeap[1];\n    vertices[2] = aboveHeap[2];\n    vertices[3] = belowHeap[0];\n    vertices[4] = belowHeap[1];\n    vertices[5] = belowHeap[2];\n  }\n\n  update(dt: number): void {\n    this.health -= dt;\n\n    if (this.health > 0) {\n      const emitter = <RibbonEmitter>this.emitter;\n      const instance = <MdxModelInstance>emitter.instance;\n      const sequence = instance.sequence;\n      const frame = instance.frame;\n      const counter = instance.counter;\n      const emitterObject = <RibbonEmitterObject>emitter.emitterObject;\n      const color = this.color;\n      const vertices = this.vertices;\n      const gravity = emitterObject.gravity * dt * dt;\n\n      emitterObject.getColor(colorHeap, sequence, frame, counter);\n      emitterObject.getAlpha(alphaHeap, sequence, frame, counter);\n      emitterObject.getTextureSlot(slotHeap, sequence, frame, counter);\n\n      vertices[1] -= gravity;\n      vertices[4] -= gravity;\n\n      color[0] = colorHeap[0] * 255;\n      color[1] = colorHeap[1] * 255;\n      color[2] = colorHeap[2] * 255;\n      color[3] = alphaHeap[0] * 255;\n\n      this.slot = slotHeap[0];\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/ribbonemitter.ts",
    "content": "import RibbonEmitterObject from './ribbonemitterobject';\nimport MdxModelInstance from './modelinstance';\nimport MdxEmitter from './emitter';\nimport Ribbon from './ribbon';\n\n/**\n * A ribbon emitter.\n */\nexport default class RibbonEmitter extends MdxEmitter {\n  first: Ribbon | null = null;\n  last: Ribbon | null = null;\n\n  updateEmission(dt: number): void {\n    const instance = <MdxModelInstance>this.instance;\n\n    if (instance.allowParticleSpawn) {\n      const emitterObject = <RibbonEmitterObject>this.emitterObject;\n\n      // It doesn't make sense to emit more than 1 ribbon at the same time.\n      this.currentEmission += emitterObject.emissionRate * dt;\n    }\n  }\n\n  emit(): void {\n    const ribbon = <Ribbon>this.emitObject();\n    const last = this.last;\n\n    if (last) {\n      last.next = ribbon;\n      ribbon.prev = last;\n    } else {\n      this.first = ribbon;\n    }\n\n    this.last = ribbon;\n  }\n\n  override kill(object: Ribbon): void {\n    super.kill(object);\n\n    const prev = object.prev;\n    const next = object.next;\n\n    if (object === this.first) {\n      this.first = next;\n    }\n\n    if (object === this.last) {\n      this.first = null;\n      this.last = null;\n    }\n\n    if (prev) {\n      prev.next = next;\n    }\n\n    if (next) {\n      next.prev = prev;\n    }\n\n    object.prev = null;\n    object.next = null;\n  }\n\n  createObject(): Ribbon {\n    return new Ribbon(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/ribbonemitterobject.ts",
    "content": "import RibbonEmitter from '../../../parsers/mdlx/ribbonemitter';\nimport MdxModel from './model';\nimport GenericObject from './genericobject';\nimport Layer from './layer';\nimport { EMITTER_RIBBON, SETTING_PARTICLES_HIGH } from './geometryemitterfuncs';\n\n/**\n * An MDX ribbon emitter.\n */\nexport default class RibbonEmitterObject extends GenericObject {\n  geometryEmitterType = EMITTER_RIBBON;\n  layer: Layer;\n  heightAbove: number;\n  heightBelow: number;\n  alpha: number;\n  color: Float32Array;\n  lifeSpan: number;\n  textureSlot: number;\n  emissionRate: number;\n  gravity: number;\n  columns: number;\n  rows: number;\n  /**\n   * Even if the internal texture isn't loaded, it's fine to run emitters based on this emitter object.\n   * \n   * The ribbons will simply be black.\n   */\n  ok = true;\n\n  constructor(model: MdxModel, emitter: RibbonEmitter, index: number) {\n    super(model, emitter, index);\n\n    this.layer = model.materials[emitter.materialId].layers[0];\n    this.heightAbove = emitter.heightAbove;\n    this.heightBelow = emitter.heightBelow;\n    this.alpha = emitter.alpha;\n    this.color = emitter.color;\n    this.lifeSpan = emitter.lifeSpan;\n    this.textureSlot = emitter.textureSlot;\n    this.emissionRate = emitter.emissionRate * SETTING_PARTICLES_HIGH;\n    this.gravity = emitter.gravity;\n    this.columns = emitter.columns;\n    this.rows = emitter.rows;\n  }\n\n  getHeightBelow(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KRHB', sequence, frame, counter, this.heightBelow);\n  }\n\n  getHeightAbove(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KRHA', sequence, frame, counter, this.heightAbove);\n  }\n\n  getTextureSlot(out: Uint32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KRTX', sequence, frame, counter, 0);\n  }\n\n  getColor(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KRCO', sequence, frame, counter, this.color);\n  }\n\n  getAlpha(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getScalarValue(out, 'KRAL', sequence, frame, counter, this.alpha);\n  }\n\n  /**\n   * Ribbon emitters specifically have an alpha.\n   * \n   * When this alpha is 0, naturally ribbons shouldn't be emitted.\n   * \n   * Therefore first check the alpha animation, and only if it's >0 check the visibility animation.\n   */\n  override getVisibility(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    const keyframe = this.getAlpha(out, sequence,frame,counter);\n    \n    if (out[0] === 0) {\n      return keyframe;\n    }\n\n    return this.getScalarValue(out, 'KRVS', sequence, frame, counter, 1);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/sd.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { lerp, hermite, bezier } from '../../../common/math';\nimport { Animation, UintAnimation, FloatAnimation, Vector3Animation, InterpolationType } from '../../../parsers/mdlx/animations';\nimport MdxModel from './model';\n\n/**\n * Animated data for a specific sequence.\n */\nclass SdSequence {\n  sd: Sd;\n  start: number;\n  end: number;\n  frames: number[] = [];\n  values: (Uint32Array | Float32Array)[] = [];\n  inTans: (Uint32Array | Float32Array)[] = [];\n  outTans: (Uint32Array | Float32Array)[] = [];\n  constant = false;\n\n  constructor(sd: Sd, start: number, end: number, animation: Animation, isGlobal: boolean) {\n    this.sd = sd;\n    this.start = start;\n    this.end = end;\n\n    const interpolationType = sd.interpolationType;\n    const frames = animation.frames;\n    const values = animation.values;\n    const inTans = animation.inTans;\n    const outTans = animation.outTans;\n    const defval = sd.defval;\n\n    // When using a global sequence, where the first key is outside of the sequence's length, it becomes its constant value.\n    // When having one key in the sequence's range, and one key outside of it, results seem to be non-deterministic.\n    // Sometimes the second key is used too, sometimes not.\n    // It also differs depending where the model is viewed - the WE previewer, the WE itself, or the game.\n    // All three show different results, none of them make sense.\n    // Therefore, only handle the case where the first key is outside.\n    // This fixes problems spread over many models, e.g. HeroMountainKing (compare in WE and in Magos).\n    if (isGlobal && frames[0] > end) {\n      this.frames[0] = frames[0];\n      this.values[0] = values[0];\n    }\n\n    // Go over the keyframes, and add all of the ones that are in this sequence (start <= frame <= end).\n    for (let i = 0, l = frames.length; i < l; i++) {\n      const frame = frames[i];\n\n      if (frame >= start && frame <= end) {\n        this.frames.push(frame);\n        this.values.push(values[i]);\n\n        if (interpolationType > 1) {\n          this.inTans.push(inTans[i]);\n          this.outTans.push(outTans[i]);\n        }\n      }\n    }\n\n    const tracksCount = this.frames.length;\n\n    if (tracksCount === 0) {\n      // If there are no keys, use the default value directly.\n      this.constant = true;\n\n      this.frames[0] = start;\n      this.values[0] = defval;\n    } else if (tracksCount === 1) {\n      // If there's only one key, use it directly.\n      this.constant = true;\n    } else {\n      const firstValue = this.values[0];\n\n      // If all of the values in this sequence are the same, might as well make it constant.\n      this.constant = this.values.every((value) => firstValue.every((element: number, index: number) => element === value[index]));\n    }\n  }\n\n  getValue(out: Uint32Array | Float32Array, frame: number): number {\n    const frames = this.frames;\n    const length = frames.length;\n\n    // Fixed implementation copied directly from Retera's code. Thank you!\n    if (this.constant || frame < this.start) {\n      this.sd.copy(out, this.values[0]);\n\n      return -1;\n    } else {\n      let startFrameIndex = -1;\n      let endFrameIndex = -1;\n      const lengthLessOne = length - 1;\n\n      if ((frame < this.frames[0]) || (frame >= this.frames[lengthLessOne])) {\n        startFrameIndex = lengthLessOne;\n        endFrameIndex = 0;\n      } else {\n        for (let i = 1; i < length; i++) {\n          if (this.frames[i] > frame) {\n            startFrameIndex = i - 1;\n            endFrameIndex = i;\n            break;\n          }\n        }\n      }\n\n      let startFrame = this.frames[startFrameIndex];\n      const endFrame = this.frames[endFrameIndex];\n      let timeBetweenFrames = endFrame - startFrame;\n\n      if (timeBetweenFrames < 0) {\n        timeBetweenFrames += (this.end - this.start);\n\n        if (frame < startFrame) {\n          startFrame = endFrame;\n        }\n      }\n\n      const t = ((timeBetweenFrames) == 0 ? 0 : ((frame - startFrame) / timeBetweenFrames));\n      this.sd.interpolate(out, this.values, this.inTans, this.outTans, startFrameIndex, endFrameIndex, t);\n\n      return startFrameIndex;\n    }\n  }\n}\n\nconst forcedInterpMap = {\n  KLAV: InterpolationType.DontInterp,\n  KATV: InterpolationType.DontInterp,\n  KPEV: InterpolationType.DontInterp,\n  KP2V: InterpolationType.DontInterp,\n  KRVS: InterpolationType.DontInterp,\n};\n\nconst floatDefval = new Float32Array(1);\nconst uintDefval = new Uint32Array(1);\nconst visibilityDefval = new Float32Array([1]);\nconst translationDefval = vec3.create();\nconst rotationDefval = quat.create();\nconst scaleDefval = vec3.fromValues(1, 1, 1);\nconst alphaDefval = visibilityDefval;\nconst colorDefval = translationDefval;\n\nconst defVals = {\n  // LAYS\n  KMTF: floatDefval,\n  KMTA: alphaDefval,\n  // TXAN\n  KTAT: translationDefval,\n  KTAR: rotationDefval,\n  KTAS: scaleDefval,\n  // GEOA\n  KGAO: alphaDefval,\n  KGAC: colorDefval,\n  // LITE\n  KLAS: floatDefval,\n  KLAE: floatDefval,\n  KLAC: colorDefval,\n  KLAI: floatDefval,\n  KLBI: floatDefval,\n  KLBC: colorDefval,\n  KLAV: visibilityDefval,\n  // ATCH\n  KATV: visibilityDefval,\n  // PREM\n  KPEE: floatDefval,\n  KPEG: floatDefval,\n  KPLN: floatDefval,\n  KPLT: floatDefval,\n  KPEL: floatDefval,\n  KPES: floatDefval,\n  KPEV: visibilityDefval,\n  // PRE2\n  KP2S: floatDefval,\n  KP2R: floatDefval,\n  KP2L: floatDefval,\n  KP2G: floatDefval,\n  KP2E: floatDefval,\n  KP2N: floatDefval,\n  KP2W: floatDefval,\n  KP2V: visibilityDefval,\n  // RIBB\n  KRHA: floatDefval,\n  KRHB: floatDefval,\n  KRAL: new Float32Array([0]), // Ribbon emitter alphas default to 0 rather than 1.\n  KRCO: colorDefval,\n  KRTX: floatDefval,\n  KRVS: visibilityDefval,\n  // CAMS\n  KCTR: translationDefval,\n  KTTR: translationDefval,\n  KCRL: uintDefval,\n  // NODE\n  KGTR: translationDefval,\n  KGRT: rotationDefval,\n  KGSC: scaleDefval,\n};\n\n/**\n * Animated data.\n */\nexport abstract class Sd {\n  defval: Float32Array | Uint32Array;\n  model: MdxModel;\n  name: string;\n  globalSequence: SdSequence | null = null;\n  sequences: SdSequence[] = [];\n  interpolationType: InterpolationType;\n\n  abstract copy(out: Uint32Array | Float32Array | vec3 | quat, value: Uint32Array | Float32Array | vec3 | quat): void;\n  abstract interpolate(out: Uint32Array | Float32Array | vec3 | quat, values: (Uint32Array | Float32Array | vec3 | quat)[], inTans: (Uint32Array | Float32Array | vec3 | quat)[], outTans: (Uint32Array | Float32Array | vec3 | quat)[], start: number, end: number, t: number): void;\n\n  constructor(model: MdxModel, animation: Animation) {\n    const globalSequences = model.globalSequences;\n    const globalSequenceId = animation.globalSequenceId;\n    const forcedInterp = forcedInterpMap[animation.name];\n\n    this.model = model;\n    this.name = animation.name;\n    this.defval = defVals[animation.name];\n\n    // Allow to force an interpolation type.\n    // The game seems to do this with visibility tracks, where the type is forced to None.\n    // It came up as a bug report by a user who used the wrong interpolation type.\n    this.interpolationType = forcedInterp !== undefined ? forcedInterp : animation.interpolationType;\n\n    if (globalSequenceId !== -1 && globalSequences) {\n      this.globalSequence = new SdSequence(this, 0, globalSequences[globalSequenceId], animation, true);\n    } else {\n      for (const sequence of model.sequences) {\n        const interval = sequence.interval;\n\n        this.sequences.push(new SdSequence(this, interval[0], interval[1], animation, false));\n      }\n    }\n  }\n\n  getValue(out: Uint32Array | Float32Array, sequence: number, frame: number, counter: number): number {\n    if (this.globalSequence) {\n      return this.globalSequence.getValue(out, counter % this.globalSequence.end);\n    }\n\n    return this.sequences[sequence].getValue(out, frame);\n  }\n\n  isVariant(sequence: number): boolean {\n    if (this.globalSequence) {\n      return !this.globalSequence.constant;\n    } else {\n      return !this.sequences[sequence].constant;\n    }\n  }\n}\n\n/**\n * A scalar animation.\n */\nexport class ScalarSd extends Sd {\n  copy<T extends Uint32Array | Float32Array>(out: T, value: T): void {\n    out[0] = value[0];\n  }\n\n  interpolate<T extends Uint32Array | Float32Array>(out: T, values: T[], inTans: T[], outTans: T[], start: number, end: number, t: number): void {\n    const interpolationType = this.interpolationType;\n    const startValue = values[start][0];\n\n    if (interpolationType === InterpolationType.DontInterp) {\n      out[0] = startValue;\n    } else if (interpolationType === InterpolationType.Linear) {\n      out[0] = lerp(startValue, values[end][0], t);\n    } else if (interpolationType === InterpolationType.Hermite) {\n      out[0] = hermite(startValue, outTans[start][0], inTans[end][0], values[end][0], t);\n    } else if (interpolationType === InterpolationType.Bezier) {\n      out[0] = bezier(startValue, outTans[start][0], inTans[end][0], values[end][0], t);\n    }\n  }\n}\n\n/**\n * A vector animation.\n */\nexport class VectorSd extends Sd {\n  copy(out: vec3, value: vec3): void {\n    vec3.copy(out, value);\n  }\n\n  interpolate(out: vec3, values: vec3[], inTans: vec3[], outTans: vec3[], start: number, end: number, t: number): void {\n    const interpolationType = this.interpolationType;\n\n    if (interpolationType === InterpolationType.DontInterp) {\n      vec3.copy(out, values[start]);\n    } else if (interpolationType === InterpolationType.Linear) {\n      vec3.lerp(out, values[start], values[end], t);\n    } else if (interpolationType === InterpolationType.Hermite) {\n      vec3.hermite(out, values[start], outTans[start], inTans[end], values[end], t);\n    } else if (interpolationType === InterpolationType.Bezier) {\n      vec3.bezier(out, values[start], outTans[start], inTans[end], values[end], t);\n    }\n  }\n}\n\n/**\n * A quaternion animation.\n */\nexport class QuatSd extends Sd {\n  copy(out: quat, value: quat): void {\n    quat.copy(out, value);\n  }\n\n  interpolate(out: quat, values: quat[], inTans: quat[], outTans: quat[], start: number, end: number, t: number): void {\n    const interpolationType = this.interpolationType;\n\n    if (interpolationType === InterpolationType.DontInterp) {\n      quat.copy(out, values[start]);\n    } else if (interpolationType === InterpolationType.Linear) {\n      quat.slerp(out, values[start], values[end], t);\n    } else if (interpolationType === InterpolationType.Hermite || interpolationType === InterpolationType.Bezier) {\n      quat.sqlerp(out, values[start], outTans[start], inTans[end], values[end], t);\n    }\n  }\n}\n\nexport function createTypedSd(model: MdxModel, animation: Animation): ScalarSd | VectorSd | QuatSd {\n  if (animation instanceof UintAnimation || animation instanceof FloatAnimation) {\n    return new ScalarSd(model, animation);\n  } else if (animation instanceof Vector3Animation) {\n    return new VectorSd(model, animation);\n  } else {\n    return new QuatSd(model, animation);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/sequence.ts",
    "content": "import MdlxSequence from '../../../parsers/mdlx/sequence';\nimport Bounds from '../../bounds';\n\n/**\n * An MDX sequence.\n */\nexport default class Sequence {\n  name: string;\n  interval: Uint32Array;\n  nonLooping: number;\n  rarity: number;\n  bounds: Bounds;\n\n  constructor(sequence: MdlxSequence) {\n    this.name = sequence.name;\n    this.interval = sequence.interval;\n    this.nonLooping = sequence.nonLooping;\n    this.rarity = sequence.rarity;\n    this.bounds = new Bounds();\n\n    const extent = sequence.extent;\n    this.bounds.fromExtents(extent.min, extent.max);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/setupgeosets.ts",
    "content": "import MdlxGeoset from '../../../parsers/mdlx/geoset';\nimport MdxModel from './model';\nimport Geoset from './geoset';\nimport { SkinningType, Batch } from './batch';\n\nexport default function setupGeosets(model: MdxModel, geosets: MdlxGeoset[]): void {\n  if (geosets.length > 0) {\n    const gl = model.viewer.gl;\n    let positionBytes = 0;\n    let normalBytes = 0;\n    let uvBytes = 0;\n    let tangentBytes = 0;\n    let skinBytes = 0;\n    let faceBytes = 0;\n    const skinTypes: SkinningType[] = [];\n\n    for (let i = 0, l = geosets.length; i < l; i++) {\n      const geoset = geosets[i];\n\n      if (geoset.lod === 0 || geoset.lod === -1) {\n        const vertices = geoset.vertices.length / 3;\n\n        positionBytes += vertices * 12;\n        normalBytes += vertices * 12;\n        uvBytes += geoset.uvSets.length * vertices * 8;\n\n        if (geoset.tangents.length) {\n          tangentBytes += vertices * 16;\n        }\n\n        if (geoset.skin.length) {\n          skinBytes += vertices * 8;\n\n          skinTypes[i] = SkinningType.Skin;\n        } else {\n          let biggestGroup = 0;\n\n          for (const group of geoset.matrixGroups) {\n            if (group > biggestGroup) {\n              biggestGroup = group;\n            }\n          }\n\n          if (biggestGroup > 4) {\n            skinBytes += vertices * 9;\n\n            skinTypes[i] = SkinningType.ExtendedVertexGroups;\n          } else {\n            skinBytes += vertices * 5;\n\n            skinTypes[i] = SkinningType.VertexGroups;\n          }\n        }\n\n        faceBytes += geoset.faces.byteLength;\n      }\n    }\n\n    let positionOffset = 0;\n    let normalOffset = positionOffset + positionBytes;\n    let uvOffset = normalOffset + normalBytes;\n    let tangentOffset = uvOffset + uvBytes;\n    let skinOffset = tangentOffset + tangentBytes;\n    let faceOffset = 0;\n    let SkinTypedArray: typeof Uint8Array | typeof Uint16Array = Uint8Array;\n    let skinGlType = gl.UNSIGNED_BYTE;\n\n    if (model.bones.length > 255) {\n      skinBytes *= 2;\n      SkinTypedArray = Uint16Array;\n      skinGlType = gl.UNSIGNED_SHORT;\n    }\n\n    model.skinDataType = skinGlType;\n    model.bytesPerSkinElement = SkinTypedArray.BYTES_PER_ELEMENT;\n\n    model.arrayBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, model.arrayBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, skinOffset + skinBytes, gl.STATIC_DRAW);\n\n    model.elementBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.elementBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, faceBytes, gl.STATIC_DRAW);\n\n    for (let i = 0, l = geosets.length; i < l; i++) {\n      const geoset = geosets[i];\n\n      if (geoset.lod === 0 || geoset.lod === -1) {\n        const positions = geoset.vertices;\n        const normals = geoset.normals;\n        const uvSets = geoset.uvSets;\n        const tangents = geoset.tangents;\n        const faces = geoset.faces;\n        let skin;\n        const vertices = geoset.vertices.length / 3;\n        const skinType = skinTypes[i];\n\n        if (skinType === SkinningType.Skin) {\n          skin = geoset.skin;\n        } else {\n          const matrixIndices = geoset.matrixIndices;\n          const vertexGroups = geoset.vertexGroups;\n          const matrixGroups = [];\n          let offset = 0;\n\n          // Normally the shader supports up to 4 bones per vertex.\n          // This is enough for almost every existing Warcraft 3 model.\n          // That being said, there are a few models with geosets that need more, for example the Water Elemental.\n          // These geosets use a different shader, which support up to 8 bones per vertex.\n          let maxBones = 4;\n\n          if (skinType === SkinningType.ExtendedVertexGroups) {\n            maxBones = 8;\n          }\n\n          skin = new SkinTypedArray(vertices * (maxBones + 1));\n\n          // Slice the matrix groups.\n          for (const size of geoset.matrixGroups) {\n            matrixGroups.push(matrixIndices.subarray(offset, offset + size));\n            offset += size;\n          }\n\n          // Parse the skinning.\n          for (let i = 0; i < vertices; i++) {\n            const matrixGroup = matrixGroups[vertexGroups[i]];\n\n            offset = i * (maxBones + 1);\n\n            // Somehow in some bad models a vertex group index refers to an invalid matrix group.\n            // Such models are still loaded by the game.\n            if (matrixGroup) {\n              const bones = Math.min(matrixGroup.length, maxBones);\n\n              for (let j = 0; j < bones; j++) {\n                skin[offset + j] = matrixGroup[j] + 1; // 1 is added to diffrentiate between matrix 0, and no matrix.\n              }\n\n              skin[offset + maxBones] = bones;\n            }\n          }\n        }\n\n        const vGeoset = new Geoset(model, model.geosets.length, positionOffset, normalOffset, uvOffset, tangentOffset, skinOffset, faceOffset, vertices, faces.length, geoset.faceTypeGroups[0]);\n        model.geosets.push(vGeoset);\n\n        const material = model.materials[geoset.materialId];\n        const isHd = material.shader === 'Shader_HD_DefaultUnit';\n\n        if (isHd) {\n          model.batches.push(new Batch(model.batches.length, vGeoset, material, skinType, true));\n        } else {\n          for (const layer of material.layers) {\n            model.batches.push(new Batch(model.batches.length, vGeoset, layer, skinType, false));\n          }\n        }\n\n        // Positions.\n        gl.bufferSubData(gl.ARRAY_BUFFER, positionOffset, positions);\n        positionOffset += positions.byteLength;\n\n        // Normals.\n        gl.bufferSubData(gl.ARRAY_BUFFER, normalOffset, normals);\n        normalOffset += normals.byteLength;\n\n        // Texture coordinates.\n        for (const uvSet of uvSets) {\n          gl.bufferSubData(gl.ARRAY_BUFFER, uvOffset, uvSet);\n          uvOffset += uvSet.byteLength;\n        }\n\n        // Tangents.\n        if (tangents.length) {\n          gl.bufferSubData(gl.ARRAY_BUFFER, tangentOffset, tangents);\n          tangentOffset += tangents.byteLength;\n        }\n\n        // Skin.\n        gl.bufferSubData(gl.ARRAY_BUFFER, skinOffset, skin);\n        skinOffset += skin.byteLength;\n\n        // Faces.\n        gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, faceOffset, faces);\n        faceOffset += faces.byteLength;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/setupgroups.ts",
    "content": "import MdxModel from './model';\nimport { Batch } from './batch';\nimport BatchGroup from './batchgroup';\nimport EmitterGroup from './emittergroup';\nimport GenericObject from './genericobject';\nimport ParticleEmitter2Object from './particleemitter2object';\nimport RibbonEmitterObject from './ribbonemitterobject';\nimport EventObjectEmitterObject from './eventobjectemitterobject';\n\nfunction getPrio(object: Batch | ParticleEmitter2Object | RibbonEmitterObject | EventObjectEmitterObject): number {\n  if (object instanceof Batch || object instanceof RibbonEmitterObject) {\n    return object.layer.priorityPlane;\n  } else if (object instanceof ParticleEmitter2Object) {\n    return object.priorityPlane;\n  } else {\n    return 0;\n  }\n}\n\nfunction matchingGroup(group: BatchGroup | EmitterGroup, object: Batch | ParticleEmitter2Object | RibbonEmitterObject | EventObjectEmitterObject): boolean {\n  if (group instanceof BatchGroup) {\n    return (object instanceof Batch) && (object.skinningType === group.skinningType) && (object.isHd === group.isHd);\n  } else {\n    // All of the emitter objects are generic objects.\n    return (object instanceof GenericObject);\n  }\n}\n\nfunction createMatchingGroup(model: MdxModel, object: Batch | ParticleEmitter2Object | RibbonEmitterObject | EventObjectEmitterObject): BatchGroup | EmitterGroup {\n  if (object instanceof Batch) {\n    return new BatchGroup(model, object.skinningType, object.isHd);\n  } else {\n    return new EmitterGroup(model);\n  }\n}\n\nexport default function setupGroups(model: MdxModel): void {\n  const opaqueBatches = [];\n  let translucentBatches = [];\n\n  for (const batch of model.batches) {\n    if (batch.layer.filterMode < 2) {\n      opaqueBatches.push(batch);\n    } else {\n      translucentBatches.push(batch);\n    }\n  }\n\n  const opaqueGroups = model.opaqueGroups;\n  const translucentGroups = model.translucentGroups;\n  let currentGroup = null;\n\n  for (const object of opaqueBatches) {\n    if (!currentGroup || !matchingGroup(currentGroup, object)) {\n      currentGroup = <BatchGroup>createMatchingGroup(model, object);\n\n      opaqueGroups.push(currentGroup);\n    }\n\n    currentGroup.objects.push(object.index);\n  }\n\n  // Sort the translucent batches based on filter mode.\n  translucentBatches = translucentBatches.sort((a, b) => a.layer.filterMode - b.layer.filterMode);  \n\n  // Sort between all of the translucent batches and emitters based on their priority planes.\n  // Event objects have no explicit priority planes, and default to 0.\n  const objects = [...translucentBatches, ...model.eventObjects, ...model.particleEmitters2, ...model.ribbonEmitters].sort((a, b) => getPrio(a) - getPrio(b));\n\n  currentGroup = null;\n\n  for (const object of objects) {\n    if (object instanceof Batch || object.geometryEmitterType !== -1) {\n      if (!currentGroup || !matchingGroup(currentGroup, object)) {\n        currentGroup = createMatchingGroup(model, object);\n\n        translucentGroups.push(currentGroup);\n      }\n\n      currentGroup.objects.push(object.index);\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/hd.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\n\nconst shader = `\n${precision}\n\nuniform sampler2D u_diffuseMap;\nuniform sampler2D u_normalsMap;\nuniform sampler2D u_ormMap;\nuniform sampler2D u_emissiveMap;\nuniform sampler2D u_teamColorMap;\nuniform sampler2D u_environmentMap;\nuniform float u_filterMode;\n\n// uniform sampler2D u_lutMap;\n// uniform sampler2D u_envDiffuseMap;\n// uniform sampler2D u_envSpecularMap;\n\nvarying vec2 v_uv;\nvarying float v_layerAlpha;\nvarying vec3 v_lightDir;\nvarying vec3 v_eyeVec;\nvarying vec3 v_normal;\n// varying vec3 v_lightDirWorld;\n\n#if defined(ONLY_TANGENTS)\nvarying vec3 v_tangent;\n#endif\n\nvec3 decodeNormal() {\n  vec2 xy = texture2D(u_normalsMap, v_uv).xy * 2.0 - 1.0;\n  \n  return vec3(xy, sqrt(1.0 - dot(xy, xy)));\n}\n\nconst vec2 invAtan = vec2(0.1591, 0.3183);\nvec2 sampleEnvironmentMap(vec3 normal) {\n  vec2 uv = vec2(atan(normal.x, normal.y), -asin(normal.z));\n  uv *= invAtan;\n  uv += 0.5;\n  return uv;\n}\n\nvec4 getDiffuseColor() {\n  vec4 color = texture2D(u_diffuseMap, v_uv);\n\n  // 1bit Alpha\n  if (u_filterMode == 1.0 && color.a < 0.75) {\n    discard;\n  }\n\n  return color;\n}\n\nvec4 getOrmColor() {\n  return texture2D(u_ormMap, v_uv);\n}\n\nvec3 getEmissiveColor() {\n  return texture2D(u_emissiveMap, v_uv).rgb;\n}\n\nvec3 getTeamColor() {\n  return texture2D(u_teamColorMap, v_uv).rgb;\n}\n\n// const float PI = 3.14159265359;\n// const float RECIPROCAL_PI = 0.31830988618;\n// const float RECIPROCAL_PI2 = 0.15915494;\n// const float LN2 = 0.6931472;\n// const float ENV_LODS = 6.0;\n// vec4 SRGBtoLinear(vec4 srgb) {\n//     vec3 linOut = pow(srgb.xyz, vec3(2.2));\n//     return vec4(linOut, srgb.w);;\n// }\n// vec4 RGBMToLinear(in vec4 value) {\n//     float maxRange = 6.0;\n//     return vec4(value.xyz * value.w * maxRange, 1.0);\n// }\n// vec3 linearToSRGB(vec3 color) {\n//     return pow(color, vec3(1.0 / 2.2));\n// }\n// // vec3 getNormal() {\n// //     vec3 pos_dx = dFdx(vMPos.xyz);\n// //     vec3 pos_dy = dFdy(vMPos.xyz);\n// //     vec2 tex_dx = dFdx(vUv);\n// //     vec2 tex_dy = dFdy(vUv);\n// //     vec3 t = normalize(pos_dx * tex_dy.t - pos_dy * tex_dx.t);\n// //     vec3 b = normalize(-pos_dx * tex_dy.s + pos_dy * tex_dx.s);\n// //     mat3 tbn = mat3(t, b, normalize(vNormal));\n// //     vec3 n = texture2D(tNormal, vUv * uNormalUVScale).rgb * 2.0 - 1.0;\n// //     n.xy *= uNormalScale;\n// //     vec3 normal = normalize(tbn * n);\n// //     // Get world normal from view normal (normalMatrix * normal)\n// //     return normalize((vec4(normal, 0.0) * viewMatrix).xyz);\n// // }\n// vec3 specularReflection(vec3 specularEnvR0, vec3 specularEnvR90, float VdH) {\n//     return specularEnvR0 + (specularEnvR90 - specularEnvR0) * pow(clamp(1.0 - VdH, 0.0, 1.0), 5.0);\n// }\n// float geometricOcclusion(float NdL, float NdV, float roughness) {\n//     float r = roughness;\n//     float attenuationL = 2.0 * NdL / (NdL + sqrt(r * r + (1.0 - r * r) * (NdL * NdL)));\n//     float attenuationV = 2.0 * NdV / (NdV + sqrt(r * r + (1.0 - r * r) * (NdV * NdV)));\n//     return attenuationL * attenuationV;\n// }\n// float microfacetDistribution(float roughness, float NdH) {\n//     float roughnessSq = roughness * roughness;\n//     float f = (NdH * roughnessSq - NdH) * NdH + 1.0;\n//     return roughnessSq / (PI * f * f);\n// }\n// vec2 cartesianToPolar(vec3 n) {\n//     vec2 uv;\n//     uv.x = atan(n.z, n.x) * RECIPROCAL_PI2 + 0.5;\n//     uv.y = asin(n.y) * RECIPROCAL_PI + 0.5;\n//     return uv;\n// }\n// void getIBLContribution(inout vec3 diffuse, inout vec3 specular, float NdV, float roughness, vec3 n, vec3 reflection, vec3 diffuseColor, vec3 specularColor) {\n//   vec3 brdf = SRGBtoLinear(texture2D(u_lutMap, vec2(NdV, roughness))).rgb;\n//   vec3 diffuseLight = RGBMToLinear(texture2D(u_envDiffuseMap, sampleEnvironmentMap(n))).rgb;\n//   // Sample 2 levels and mix between to get smoother degradation\n//   float blend = roughness * ENV_LODS;\n//   float level0 = floor(blend);\n//   float level1 = min(ENV_LODS, level0 + 1.0);\n//   blend -= level0;\n  \n//   // Sample the specular env map atlas depending on the roughness value\n//   vec2 uvSpec = sampleEnvironmentMap(reflection);\n//   uvSpec.y /= 2.0;\n//   vec2 uv0 = uvSpec;\n//   vec2 uv1 = uvSpec;\n//   uv0 /= pow(2.0, level0);\n//   uv0.y += 1.0 - exp(-LN2 * level0);\n//   uv1 /= pow(2.0, level1);\n//   uv1.y += 1.0 - exp(-LN2 * level1);\n//   vec3 specular0 = RGBMToLinear(texture2D(u_envSpecularMap, uv0)).rgb;\n//   vec3 specular1 = RGBMToLinear(texture2D(u_envSpecularMap, uv1)).rgb;\n//   vec3 specularLight = mix(specular0, specular1, blend);\n//   diffuse = diffuseLight * diffuseColor;\n  \n//   // Bit of extra reflection for smooth materials\n//   float reflectivity = pow((1.0 - roughness), 2.0) * 0.05;\n//   specular = specularLight * (specularColor * brdf.x + brdf.y + reflectivity);\n//   // specular *= uEnvSpecular;\n// }\n\n// void PBR() {\n//   vec4 baseDiffuseColor = getDiffuseColor();\n//   vec3 baseColor = baseDiffuseColor.rgb;\n//   vec4 orm = getOrmColor();\n//   vec3 tc = getTeamColor();\n//   float tcFactor = getOrmColor().a;\n\n//   if (tcFactor > 0.1) {\n//     baseColor *= tc * tcFactor;\n//   }\n\n//   float roughness = clamp(orm.g, 0.04, 1.0);\n//   float metallic = clamp(orm.b, 0.04, 1.0);\n\n//   vec3 f0 = vec3(0.04);\n//   vec3 diffuseColor = baseColor * (vec3(1.0) - f0) * (1.0 - metallic);\n//   vec3 specularColor = mix(f0, baseColor, metallic);\n//   vec3 specularEnvR0 = specularColor;\n//   vec3 specularEnvR90 = vec3(clamp(max(max(specularColor.r, specularColor.g), specularColor.b) * 25.0, 0.0, 1.0));\n\n//   vec3 N = v_normal;\n//   vec3 V = normalize(v_eyeVec);\n//   vec3 L = normalize(v_lightDirWorld);\n//   vec3 H = normalize(L + V);\n//   vec3 reflection = normalize(reflect(-V, N));\n\n//   float NdL = clamp(dot(N, L), 0.001, 1.0);\n//   float NdV = clamp(abs(dot(N, V)), 0.001, 1.0);\n//   float NdH = clamp(dot(N, H), 0.0, 1.0);\n//   float LdH = clamp(dot(L, H), 0.0, 1.0);\n//   float VdH = clamp(dot(V, H), 0.0, 1.0);\n\n//   vec3 F = specularReflection(specularEnvR0, specularEnvR90, VdH);\n//   float G = geometricOcclusion(NdL, NdV, roughness);\n//   float D = microfacetDistribution(roughness, NdH);\n\n//   vec3 diffuseContrib = (1.0 - F) * (diffuseColor / PI);\n//   vec3 specContrib = F * G * D / (4.0 * NdL * NdV);\n  \n//   // Shading based off lights\n//   // vec3 color = NdL * uLightColor * (diffuseContrib + specContrib);\n//   vec3 color = NdL * (diffuseContrib + specContrib);\n\n//   // Calculate IBL lighting\n//   vec3 diffuseIBL;\n//   vec3 specularIBL;\n//   getIBLContribution(diffuseIBL, specularIBL, NdV, roughness, N, reflection, diffuseColor, specularColor);\n\n//   // Add IBL on top of color\n//   color +=  specularIBL;\n\n//   color *= orm.r;\n\n//   color += getEmissiveColor();\n\n//   // Convert to sRGB to display\n//   gl_FragColor.rgb = color;\n//   gl_FragColor.a = baseDiffuseColor.a;\n// }\n\nvoid onlyDiffuse() {\n  vec4 baseColor = getDiffuseColor();\n  vec3 tc = getTeamColor();\n  float tcFactor = getOrmColor().a;\n\n  if (tcFactor > 0.1) {\n    baseColor.rgb *= tc * tcFactor;\n  }\n\n  gl_FragColor = baseColor;\n}\n\nvoid onlyNormalMap() {\n  gl_FragColor = vec4(decodeNormal(), 1.0);\n}\n\nvoid onlyOcclusion() {\n  gl_FragColor = vec4(getOrmColor().rrr, 1.0);\n}\n\nvoid onlyRoughness() {\n  gl_FragColor = vec4(getOrmColor().ggg, 1.0);\n}\n\nvoid onlyMetallic() {\n  gl_FragColor = vec4(getOrmColor().bbb, 1.0);\n}\n\nvoid onlyTeamColorFactor() {\n  gl_FragColor = vec4(getOrmColor().aaa, 1.0);\n}\n\nvoid onlyEmissiveMap() {\n  gl_FragColor = vec4(getEmissiveColor(), 1.0);\n}\n\nvoid onlyTexCoords() {\n  gl_FragColor = vec4(v_uv, 0.0, 1.0);\n}\n\nvoid onlyNormals() {\n  gl_FragColor = vec4(v_normal, 1.0);\n}\n\n#if defined(ONLY_TANGENTS)\nvoid onlyTangents() {\n  gl_FragColor = vec4(v_tangent, 1.0);\n}\n#endif\n\nvoid lambert() {\n  vec4 baseColor = getDiffuseColor();\n  vec3 normal = decodeNormal();\n  vec4 orm = getOrmColor();\n  vec3 emissive = getEmissiveColor();\n  vec3 tc = getTeamColor();\n  float aoFactor = orm.r;\n  float tcFactor = orm.a;\n  float lambertFactor = clamp(dot(normal, v_lightDir), 0.0, 1.0);\n  vec3 color = baseColor.rgb;\n\n  if (tcFactor > 0.1) {\n    color *= tc * tcFactor;\n  }\n  \n  color *= clamp(lambertFactor * aoFactor + 0.1, 0.0, 1.0);\n  color += emissive;\n\n  gl_FragColor = vec4(color, baseColor.a);\n}\n\nvoid main() {\n  #if defined(ONLY_DIFFUSE)\n  onlyDiffuse();\n  #elif defined(ONLY_NORMAL_MAP)\n  onlyNormalMap();\n  #elif defined(ONLY_OCCLUSION)\n  onlyOcclusion();\n  #elif defined(ONLY_ROUGHNESS)\n  onlyRoughness();\n  #elif defined(ONLY_METALLIC)\n  onlyMetallic();\n  #elif defined(ONLY_TC_FACTOR)\n  onlyTeamColorFactor();\n  #elif defined(ONLY_EMISSIVE)\n  onlyEmissiveMap();\n  #elif defined(ONLY_TEXCOORDS)\n  onlyTexCoords();\n  #elif defined(ONLY_NORMALS)\n  onlyNormals();\n  #elif defined(ONLY_TANGENTS)\n  onlyTangents();\n  #else\n  lambert();\n  #endif\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/hd.vert.ts",
    "content": "\nimport boneTexture from '../../shaders/bonetexture.glsl';\nimport transforms from './transforms.glsl';\n\nconst shader = `\nuniform mat4 u_VP;\nuniform mat4 u_MV;\nuniform vec3 u_eyePos;\nuniform vec3 u_lightPos;\nuniform float u_layerAlpha;\nuniform bool u_hasBones;\n\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_uv;\nattribute vec4 a_tangent;\n\nvarying vec2 v_uv;\nvarying float v_layerAlpha;\nvarying vec3 v_lightDir;\nvarying vec3 v_eyeVec;\nvarying vec3 v_normal;\n// varying vec3 v_lightDirWorld;\n\n#if defined(ONLY_TANGENTS)\nvarying vec3 v_tangent;\n#endif\n\n${boneTexture}\n${transforms}\n\nvec3 TBN(vec3 vector, vec3 tangent, vec3 binormal, vec3 normal) {\n  return vec3(dot(vector, tangent), dot(vector, binormal), dot(vector, normal));\n}\n\nvoid main() {\n  vec3 position = a_position;\n  vec3 normal = a_normal;\n  vec3 tangent = a_tangent.xyz;\n\n  // Re-orthogonalize the tangent in case it wasnt normalized.\n  // See \"One last thing\" at https://learnopengl.com/Advanced-Lighting/Normal-Mapping\n  tangent = normalize(tangent - dot(tangent, normal) * normal);\n\n  vec3 binormal = cross(normal, tangent) * a_tangent.w;\n\n  if (u_hasBones) {\n    #ifdef SKIN\n      transformSkin(position, normal, tangent, binormal);\n    #else\n      transformVertexGroupsHD(position, normal, tangent, binormal);\n    #endif\n  }\n\n  vec3 position_mv = vec3(u_MV * vec4(position, 1));\n\n  mat3 mv = mat3(u_MV);\n  vec3 t = normalize(mv * tangent);\n  vec3 b = normalize(mv * binormal);\n  vec3 n = normalize(mv * normal);\n\n  v_eyeVec = normalize(u_eyePos - position_mv);\n\n  vec3 lightDir = normalize(u_lightPos - position_mv);\n  v_lightDir = normalize(TBN(lightDir, t, b, n));\n  \n  v_uv = a_uv;\n  v_layerAlpha = u_layerAlpha;\n\n  v_normal = normal;\n  // v_lightDirWorld = normalize(lightDir);\n\n  #if defined(ONLY_TANGENTS)\n  v_tangent = tangent;\n  #endif\n\n  gl_Position = u_VP * vec4(position, 1.0);\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/particles.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\n\nconst shader = `\n${precision}\n\n#define EMITTER_PARTICLE2 0\n#define EMITTER_RIBBON 1\n\nuniform sampler2D u_texture;\nuniform highp int u_emitter;\nuniform float u_filterMode;\n\nvarying vec2 v_texcoord;\nvarying vec4 v_color;\n\nvoid main() {\n  vec4 texel = texture2D(u_texture, v_texcoord);\n  vec4 color = texel * v_color;\n\n  // 1bit Alpha, used by ribbon emitters.\n  if (u_emitter == EMITTER_RIBBON && u_filterMode == 1.0 && color.a < 0.75) {\n    discard;\n  }\n\n  // \"Close to 0 alpha\"\n  if (u_emitter == EMITTER_PARTICLE2 && (u_filterMode == 2.0 || u_filterMode == 3.0) && color.a < 0.02) {\n    discard;\n  }\n\n  // Alpha key.\n  if (u_emitter == EMITTER_PARTICLE2 && (u_filterMode == 4.0) && color.a < 0.75) {\n    discard;\n  }\n\n  gl_FragColor = color;\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/particles.vert.ts",
    "content": "const shader = `\n#define EMITTER_PARTICLE2 0\n#define EMITTER_RIBBON 1\n#define EMITTER_SPLAT 2\n#define EMITTER_UBERSPLAT 3\n#define HEAD 0.0\n\nuniform mat4 u_VP;\nuniform int u_emitter;\n\n// Shared\nuniform vec4 u_colors[3];\nuniform vec3 u_vertices[4];\nuniform vec3 u_intervals[4];\nuniform float u_lifeSpan;\nuniform float u_columns;\nuniform float u_rows;\n\n// Particle2\nuniform vec3 u_scaling;\nuniform vec3 u_cameraZ;\nuniform float u_timeMiddle;\nuniform bool u_teamColored;\n\n// Splat and Uber.\nuniform vec3 u_intervalTimes;\n\n// Vertices\nattribute float a_position;\n\n// Instances\nattribute vec3 a_p0;\nattribute vec3 a_p1;\nattribute vec3 a_p2;\nattribute vec3 a_p3;\nattribute float a_health;\nattribute vec4 a_color;\nattribute float a_tail;\nattribute vec3 a_leftRightTop;\n\nvarying vec2 v_texcoord;\nvarying vec4 v_color;\n\nfloat getCell(vec3 interval, float factor) {\n  float start = interval[0];\n  float end = interval[1];\n  float repeat = interval[2];\n  float spriteCount = end - start;\n\n  if (spriteCount > 0.0) {\n    // Repeating speeds up the sprite animation, which makes it effectively run N times in its interval.\n    // E.g. if repeat is 4, the sprite animation will be seen 4 times, and thus also run 4 times as fast.\n    // The sprite index is limited to the number of actual sprites.\n    return min(start + mod(floor(spriteCount * repeat * factor), spriteCount), u_columns * u_rows - 1.0);\n  }\n\n  return start;\n}\n\nvoid particle2() {\n  float factor = (u_lifeSpan - a_health) / u_lifeSpan;\n  int index = 0;\n\n  if (factor < u_timeMiddle) {\n    factor = factor / u_timeMiddle;\n    index = 0;\n  } else {\n    factor = (factor - u_timeMiddle) / (1.0 - u_timeMiddle);\n    index = 1;\n  }\n\n  factor = min(factor, 1.0);\n\n  float scale = mix(u_scaling[index], u_scaling[index + 1], factor);\n  vec4 color = mix(u_colors[index], u_colors[index + 1], factor);\n\n  float cell = 0.0;\n\n  if (u_teamColored) {\n    cell = a_leftRightTop[0];\n  } else {\n    vec3 interval;\n\n    if (a_tail == HEAD) {\n      interval = u_intervals[index];\n    } else {\n      interval = u_intervals[index + 2];\n    }\n\n    cell = getCell(interval, factor);\n  }\n\n  float left = floor(mod(cell, u_columns));\n  float top = floor(cell / u_columns);\n  float right = left + 1.0;\n  float bottom = top + 1.0;\n\n  left /= u_columns;\n  right /= u_columns;\n  top /= u_rows;\n  bottom /= u_rows;\n\n  if (a_position == 0.0) {\n    v_texcoord = vec2(right, top);\n  } else if (a_position == 1.0) {\n    v_texcoord = vec2(left, top);\n  } else if (a_position == 2.0) {\n    v_texcoord = vec2(left, bottom);\n  } else if (a_position == 3.0) {\n    v_texcoord = vec2(right, bottom);\n  }\n\n  v_color = color;\n  \n  if (a_tail == HEAD) {\n    vec3 v = u_vertices[int(a_position)];\n    float cs = cos(a_p1.x);\n    float sn = sin(a_p1.x);\n\n    float x = v.x * cs - v.y * sn;\n    float y = v.x * sn + v.y * cs;\n\n    vec3 fv = vec3(\n      v.x * cs - v.y * sn,\n      v.x * sn + v.y * cs,\n      v.z);\n\n    gl_Position = u_VP * vec4(a_p0 + fv * scale, 1.0);\n  } else {\n    // Get the normal to the tail in camera space.\n    // This allows to build a 2D rectangle around the 3D tail.\n    vec3 normal = cross(u_cameraZ, normalize(a_p1 - a_p0));\n    vec3 boundary = normal * scale * a_p2[0];\n    vec3 position;\n\n    if (a_position == 0.0) {\n      position = a_p0 - boundary;\n    } else if (a_position == 1.0) {\n      position = a_p1 - boundary;\n    } else if (a_position == 2.0) {\n      position = a_p1 + boundary;\n    } else if (a_position == 3.0) {\n      position = a_p0 + boundary;\n    }\n\n    gl_Position = u_VP * vec4(position, 1.0);\n  }\n}\n\nvoid ribbon() {\n  vec3 position;\n  float left = a_leftRightTop[0] / 255.0;\n  float right = a_leftRightTop[1] / 255.0;\n  float top = a_leftRightTop[2] / 255.0;\n  float bottom = top + 1.0;\n\n  if (a_position == 0.0) {\n    v_texcoord = vec2(right, top);\n    position = a_p0;\n  } else if (a_position == 1.0) {\n    v_texcoord = vec2(right, bottom);\n    position = a_p1;\n  } else if (a_position == 2.0) {\n    v_texcoord = vec2(left, bottom);\n    position = a_p2;\n  } else if (a_position == 3.0) {\n    v_texcoord = vec2(left, top);\n    position = a_p3;\n  }\n\n  v_texcoord[0] /= u_columns;\n  v_texcoord[1] /= u_rows;\n\n  v_color = a_color;\n\n  gl_Position = u_VP * vec4(position, 1.0);\n}\n\nvoid splat() {\n  float factor = u_lifeSpan - a_health;\n  int index;\n\n  if (factor < u_intervalTimes[0]) {\n    factor = factor / u_intervalTimes[0];\n    index = 0;\n  } else {\n    factor = (factor - u_intervalTimes[0]) / u_intervalTimes[1];\n    index = 1;\n  }\n\n  float cell = getCell(u_intervals[index], factor);\n  float left = floor(mod(cell, u_columns));\n  float top = floor(cell / u_columns);\n  float right = left + 1.0;\n  float bottom = top + 1.0;\n  vec3 position;\n\n  if (a_position == 0.0) {\n    v_texcoord = vec2(left, top);\n    position = a_p0;\n  } else if (a_position == 1.0) {\n    v_texcoord = vec2(left, bottom);\n    position = a_p1;\n  } else if (a_position == 2.0) {\n    v_texcoord = vec2(right, bottom);\n    position = a_p2;\n  } else if (a_position == 3.0) {\n    v_texcoord = vec2(right, top);\n    position = a_p3;\n  }\n\n  v_texcoord[0] /= u_columns;\n  v_texcoord[1] /= u_rows;\n\n  v_color = mix(u_colors[index], u_colors[index + 1], factor) / 255.0;\n\n  gl_Position = u_VP * vec4(position, 1.0);\n}\n\nvoid ubersplat() {\n  float factor = u_lifeSpan - a_health;\n  vec4 color;\n\n  if (factor < u_intervalTimes[0]) {\n    color = mix(u_colors[0], u_colors[1], factor / u_intervalTimes[0]);\n  } else if (factor < u_intervalTimes[0] + u_intervalTimes[1]) {\n    color = u_colors[1];\n  } else {\n    color = mix(u_colors[1], u_colors[2], (factor - u_intervalTimes[0] - u_intervalTimes[1]) / u_intervalTimes[2]);\n  }\n\n  vec3 position;\n\n  if (a_position == 0.0) {\n    v_texcoord = vec2(0.0, 0.0);\n    position = a_p0;\n  } else if (a_position == 1.0) {\n    v_texcoord = vec2(0.0, 1.0);\n    position = a_p1;\n  } else if (a_position == 2.0) {\n    v_texcoord = vec2(1.0, 1.0);\n    position = a_p2;\n  } else if (a_position == 3.0) {\n    v_texcoord = vec2(1.0, 0.0);\n    position = a_p3;\n  }\n\n  v_color = color / 255.0;\n\n  gl_Position = u_VP * vec4(position, 1.0);\n}\n\nvoid main() {\n  if (u_emitter == EMITTER_PARTICLE2) {\n    particle2();\n  } else if (u_emitter == EMITTER_RIBBON) {\n    ribbon();\n  } else if (u_emitter == EMITTER_SPLAT) {\n    splat();\n  } else if (u_emitter == EMITTER_UBERSPLAT) {\n    ubersplat();\n  }\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/sd.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\nimport quatTransform from '../../shaders/quattransform.glsl';\n\nconst shader = `\n${precision}\n\n${quatTransform}\n\nuniform sampler2D u_texture;\nuniform float u_filterMode;\nuniform bool u_unshaded;\n\nvarying vec2 v_uv;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvarying vec4 v_uvTransRot;\nvarying float v_uvScale;\nvarying vec3 v_lightDir;\n\nvec4 getDiffuseColor() {\n  vec2 uv = v_uv;\n\n  // Translation animation\n  uv += v_uvTransRot.xy;\n\n  // Rotation animation\n  uv = quat_transform(v_uvTransRot.zw, uv - 0.5) + 0.5;\n\n  // Scale animation\n  uv = v_uvScale * (uv - 0.5) + 0.5;\n\n  vec4 texel = texture2D(u_texture, uv);\n  vec4 color = texel * v_color;\n\n  // 1bit Alpha\n  if (u_filterMode == 1.0 && color.a < 0.75) {\n    discard;\n  }\n\n  // \"Close to 0 alpha\"\n  if (u_filterMode >= 5.0 && color.a < 0.02) {\n    discard;\n  }\n\n  return color;\n}\n\nvoid onlyTexCoords() {\n  gl_FragColor = vec4(v_uv, 0.0, 1.0);\n}\n\nvoid onlyNormals() {\n  gl_FragColor = vec4(v_normal, 1.0);\n}\n\nvoid onlyDiffuse() {\n  gl_FragColor = getDiffuseColor();\n}\n\nvoid lambert() {\n  vec4 color = getDiffuseColor();\n\n  if (!u_unshaded) {\n    float lambertFactor = clamp(dot(v_normal, v_lightDir), 0.0, 1.0);\n    lambertFactor = clamp(lambertFactor + 0.7, 0.0, 1.0);\n\n    color.rgb *= lambertFactor;\n  }\n\n  gl_FragColor = color;\n}\n\nvoid main() {\n  #if defined(ONLY_DIFFUSE)\n  onlyDiffuse();\n  #elif defined(ONLY_TEXCOORDS)\n  onlyTexCoords();\n  #elif defined(ONLY_NORMALS)\n  onlyNormals();\n  #else\n  lambert();\n  #endif\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/sd.vert.ts",
    "content": "import boneTexture from '../../shaders/bonetexture.glsl';\nimport transforms from './transforms.glsl';\n\nconst shader = `\nuniform mat4 u_VP;\nuniform vec3 u_lightPos;\nuniform vec4 u_vertexColor;\nuniform vec4 u_geosetColor;\nuniform float u_layerAlpha;\nuniform vec2 u_uvTrans;\nuniform vec2 u_uvRot;\nuniform float u_uvScale;\nuniform bool u_hasBones;\n\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_uv;\n\nvarying vec2 v_uv;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvarying vec4 v_uvTransRot;\nvarying float v_uvScale;\nvarying vec3 v_lightDir;\n\n${boneTexture}\n${transforms}\n\nvoid main() {\n  vec3 position = a_position;\n  vec3 normal = a_normal;\n\n  if (u_hasBones) {\n    #ifdef SKIN\n      vec3 tangent = vec3(0.0);\n      vec3 binormal = vec3(0.0);\n      transformSkin(position, normal, tangent, binormal);\n    #else\n      transformVertexGroups(position, normal);\n    #endif\n  }\n\n  v_uv = a_uv;\n  v_normal = normal;\n  v_color = u_vertexColor * u_geosetColor.bgra * vec4(1.0, 1.0, 1.0, u_layerAlpha);\n  v_uvTransRot = vec4(u_uvTrans, u_uvRot);\n  v_uvScale = u_uvScale;\n  v_lightDir = normalize(u_lightPos - position);\n\n  gl_Position = u_VP * vec4(position, 1.0);\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/shaders/transforms.glsl.ts",
    "content": "const shader = `\n#ifdef SKIN\nattribute vec4 a_bones;\nattribute vec4 a_weights;\n\nvoid transformSkin(inout vec3 position, inout vec3 normal, inout vec3 tangent, inout vec3 binormal) {\n  mat4 bone;\n\n  bone += fetchMatrix(a_bones[0], 0.0) * a_weights[0];\n  bone += fetchMatrix(a_bones[1], 0.0) * a_weights[1];\n  bone += fetchMatrix(a_bones[2], 0.0) * a_weights[2];\n  bone += fetchMatrix(a_bones[3], 0.0) * a_weights[3];\n\n  mat3 rotation = mat3(bone);\n\n  position = vec3(bone * vec4(position, 1.0));\n  normal = rotation * normal;\n  tangent = rotation * tangent;\n  binormal = rotation * binormal;\n}\n#else\nattribute vec4 a_bones;\n#ifdef EXTENDED_BONES\nattribute vec4 a_extendedBones;\n#endif\nattribute float a_boneNumber;\n\nmat4 getVertexGroupMatrix() {\n  mat4 bone;\n\n  // For the broken models out there, since the game supports this.\n  if (a_boneNumber > 0.0) {\n    for (int i = 0; i < 4; i++) {\n      if (a_bones[i] > 0.0) {\n        bone += fetchMatrix(a_bones[i] - 1.0, 0.0);\n      }\n    }\n\n    #ifdef EXTENDED_BONES\n      for (int i = 0; i < 4; i++) {\n        if (a_extendedBones[i] > 0.0) {\n          bone += fetchMatrix(a_extendedBones[i] - 1.0, 0.0);\n        }\n      }\n    #endif\n  }\n\n  return bone / a_boneNumber;\n}\n\nvoid transformVertexGroups(inout vec3 position, inout vec3 normal) {\n  mat4 bone = getVertexGroupMatrix();\n  mat3 rotation = mat3(bone);\n\n  position = vec3(bone * vec4(position, 1.0));\n  normal = normalize(rotation * normal);\n}\n\nvoid transformVertexGroupsHD(inout vec3 position, inout vec3 normal, inout vec3 tangent, inout vec3 binormal) {\n  mat4 bone = getVertexGroupMatrix();\n  mat3 rotation = mat3(bone);\n\n  position = vec3(bone * vec4(position, 1.0));\n  normal = normalize(rotation * normal);\n  tangent = normalize(rotation * tangent);\n  binormal = normalize(rotation * binormal);\n}\n#endif\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/mdx/texture.ts",
    "content": "import { WrapMode } from '../../../parsers/mdlx/texture';\nimport Texture from '../../texture';\n\n/**\n * An MDX texture.\n */\nexport default class MdxTexture {\n  texture: Texture | null = null;\n  replaceableId: number;\n  wrapS = 0x812f; // CLAMP_TO_EDGE\n  wrapT = 0x812f;\n\n  constructor(replaceableId: number, wrapMode: WrapMode) {\n    this.replaceableId = replaceableId;\n\n    if (wrapMode & WrapMode.WrapWidth) {\n      this.wrapS = 0x2901; // REPEAT\n    }\n\n    if (wrapMode & WrapMode.WrapHeight) {\n      this.wrapT = 0x2901;\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/mdx/textureanimation.ts",
    "content": "import { VEC3_ZERO, VEC3_ONE, QUAT_DEFAULT } from '../../../common/gl-matrix-addon';\nimport MdlxTextureAnimation from '../../../parsers/mdlx/textureanimation';\nimport AnimatedObject from './animatedobject';\nimport MdxModel from './model';\n\n/**\n * An MDX texture animation.\n */\nexport default class TextureAnimation extends AnimatedObject {\n  constructor(model: MdxModel, textureAnimation: MdlxTextureAnimation) {\n    super(model, textureAnimation);\n\n    this.addVariants('KTAT', 'translation');\n    this.addVariants('KTAR', 'rotation');\n    this.addVariants('KTAS', 'scale');\n  }\n\n  getTranslation(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KTAT', sequence, frame, counter, <Float32Array>VEC3_ZERO);\n  }\n\n  getRotation(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getQuatValue(out, 'KTAR', sequence, frame, counter, <Float32Array>QUAT_DEFAULT);\n  }\n\n  getScale(out: Float32Array, sequence: number, frame: number, counter: number): number {\n    return this.getVectorValue(out, 'KTAS', sequence, frame, counter, <Float32Array>VEC3_ONE);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/shaders/bonetexture.glsl.ts",
    "content": "const shader = `\nuniform sampler2D u_boneMap;\nuniform float u_vectorSize;\nuniform float u_rowSize;\n\nmat4 fetchMatrix(float column, float row) {\n  column *= u_vectorSize * 4.0;\n  row *= u_rowSize;\n  // Add in half a texel, to sample in the middle of the texel.\n  // Otherwise, since the sample is directly on the boundary, floating point errors can cause the sample to get the wrong pixel.\n  // This is most noticeable with NPOT textures, which the bone maps are.\n  column += 0.5 * u_vectorSize;\n  row += 0.5 * u_rowSize;\n\n  return mat4(texture2D(u_boneMap, vec2(column, row)),\n              texture2D(u_boneMap, vec2(column + u_vectorSize, row)),\n              texture2D(u_boneMap, vec2(column + u_vectorSize * 2.0, row)),\n              texture2D(u_boneMap, vec2(column + u_vectorSize * 3.0, row)));\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/shaders/precision.glsl.ts",
    "content": "// Used by all fragment shaders.\nconst shader = `\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/shaders/quattransform.glsl.ts",
    "content": "const shader = `\n// A 2D quaternion*vector.\n// q is the zw components of the original quaternion.\nvec2 quat_transform(vec2 q, vec2 v) {\n  vec2 uv = vec2(-q.x * v.y, q.x * v.x);\n  vec2 uuv = vec2(-q.x * uv.y, q.x * uv.x);\n\n  return v + 2.0 * (uv * q.y + uuv);\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/tga/handler.ts",
    "content": "import TgaImage from '../../../parsers/tga/image';\nimport isTga from '../../../parsers/tga/isformat';\nimport Texture from './texture';\n\nexport default {\n  isValidSource(object: unknown): boolean {\n    if (object instanceof TgaImage) {\n      return true;\n    }\n\n    return isTga(object);\n  },\n  resource: Texture,\n};\n"
  },
  {
    "path": "src/viewer/handlers/tga/texture.ts",
    "content": "import { isPowerOfTwo } from '../../../common/math';\nimport TgaImage from '../../../parsers/tga/image';\nimport { HandlerResourceData } from '../../handlerresource';\nimport Texture from '../../texture';\n\n/**\n * A TGA texture handler.\n */\nexport default class TgaTexture extends Texture {\n  constructor(bufferOrImage: ArrayBuffer | TgaImage, resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    let image;\n\n    if (bufferOrImage instanceof TgaImage) {\n      image = bufferOrImage;\n    } else {\n      image = new TgaImage();\n\n      image.load(bufferOrImage);\n    }\n\n    const width = image.width;\n    const height = image.height;\n\n    const gl = this.viewer.gl;\n    const id = gl.createTexture();\n\n    gl.bindTexture(gl.TEXTURE_2D, id);\n\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, <ImageData>image.data);\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n    if (isPowerOfTwo(width) && isPowerOfTwo(height)) {\n      gl.generateMipmap(gl.TEXTURE_2D);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);\n    } else {\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n    }\n\n    this.webglResource = id;\n    this.width = width;\n    this.height = height;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/doodad.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { VEC3_UNIT_Z } from '../../../common/gl-matrix-addon';\nimport { MappedDataRow } from '../../../utils/mappeddata';\nimport DooDoodad from '../../../parsers/w3x/doo/doodad';\nimport MdxModel from '../mdx/model';\nimport War3MapViewerMap from './map';\nimport { Widget } from './widget';\n\n/**\n * A doodad.\n */\nexport default class Doodad extends Widget {\n  row: MappedDataRow;\n\n  constructor(map: War3MapViewerMap, model: MdxModel, row: MappedDataRow, doodad: DooDoodad) {\n    super(map, model);\n\n    const instance = this.instance;\n\n    instance.move(<vec3>doodad.location);\n    instance.rotateLocal(quat.setAxisAngle(quat.create(), VEC3_UNIT_Z, doodad.angle));\n    instance.scale(<vec3>doodad.scale);\n    instance.setScene(map.worldScene);\n\n    this.instance = instance;\n    this.row = row;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/map.ts",
    "content": "import { vec3 } from 'gl-matrix';\nimport unique from '../../../common/arrayunique';\nimport War3Map from '../../../parsers/w3x/map';\nimport War3MapW3i from '../../../parsers/w3x/w3i/file';\nimport War3MapW3e from '../../../parsers/w3x/w3e/file';\nimport Corner from '../../../parsers/w3x/w3e/corner';\nimport War3MapW3u from '../../../parsers/w3x/w3u/file';\nimport War3MapW3d from '../../../parsers/w3x/w3d/file';\nimport ModificationTable from '../../../parsers/w3x/w3u/modificationtable';\nimport { MappedData, MappedDataRow } from '../../../utils/mappeddata';\nimport Scene from '../../scene';\nimport Grid from '../../grid';\nimport { PathSolver } from '../../handlerresource';\nimport Texture from '../../texture';\nimport MdxModel from '../mdx/model';\nimport getCliffVariation from './variations';\nimport TerrainModel from './terrainmodel';\nimport Unit from './unit';\nimport Doodad from './doodad';\nimport TerrainDoodad from './terraindoodad';\nimport War3MapViewer from './viewer';\nimport War3MapDoo from '../../../parsers/w3x/doo/file';\nimport War3MapUnitsDoo from '../../../parsers/w3x/unitsdoo/file';\nimport { Resource } from '../../resource';\n\nconst normalHeap1 = vec3.create();\nconst normalHeap2 = vec3.create();\n\nexport default class War3MapViewerMap {\n  viewer: War3MapViewer;\n  map: War3Map;\n  pathSolver: PathSolver;\n  buildVersion = 0;\n  solverParams: { tileset: string, reforged?: boolean, hd?: boolean } = { tileset: 'a' };\n  worldScene: Scene;\n  waterIndex = 0;\n  waterIncreasePerFrame = 0;\n  waterHeightOffset = 0;\n  waterTextures: Texture[] = [];\n  maxDeepColor = new Float32Array(4);\n  minDeepColor = new Float32Array(4);\n  maxShallowColor = new Float32Array(4);\n  minShallowColor = new Float32Array(4);\n  anyReady = false;\n  terrainReady = false;\n  cliffsReady = false;\n  doodads: Doodad[] = [];\n  terrainDoodads: TerrainDoodad[] = [];\n  doodadsReady = false;\n  units: Unit[] = [];\n  unitsReady = false;\n  tilesetTextures: Texture[] = [];\n  cliffTextures: Texture[] = [];\n  cliffModels: TerrainModel[] = [];\n  corners: Corner[][] = [];\n  centerOffset = new Float32Array(2);\n  mapSize = new Int32Array(2);\n  tilesets: MappedDataRow[] = [];\n  blightTextureIndex = -1;\n  cliffTilesets: MappedDataRow[] = [];\n  columns = 0;\n  rows = 0;\n  vertexBuffer: WebGLBuffer | null = null;\n  faceBuffer: WebGLBuffer | null = null;\n  instanceBuffer: WebGLBuffer | null = null;\n  textureBuffer: WebGLBuffer | null = null;\n  variationBuffer: WebGLBuffer | null = null;\n  waterBuffer: WebGLBuffer | null = null;\n  heightMap: WebGLTexture | null = null;\n  waterHeightMap: WebGLTexture | null = null;\n  cliffHeightMap: WebGLTexture | null = null;\n\n  constructor(viewer: War3MapViewer, buffer: ArrayBuffer | Uint8Array) {\n    this.viewer = viewer;\n    this.worldScene = viewer.addScene();\n\n    this.map = new War3Map();\n\n    // Readonly mode to optimize memory usage.\n    this.map.load(buffer, true);\n\n    this.loadMapInformation();\n\n    this.pathSolver = (src, params): unknown => {\n      // The type won't be a string for loads from memory, where the final source is the input source.\n      // The primitive constructor is one example of this.\n      if (typeof src === 'string') {\n        // MPQ paths have backwards slashes...always? Don't know.\n        const path = src.replace(/\\//g, '\\\\');\n\n        // If the file is in the map, return it.\n        const file = this.map.get(path);\n\n        if (file) {\n          return file.arrayBuffer();\n        }\n\n        // Try to get the file from the server.\n        return viewer.wc3PathSolver(src, params);\n      }\n\n      return src;\n    };\n\n    this.loadTerrainCliffsAndWater();\n\n    // Global tables like WC3. It's bad.\n    const modifications = this.map.readModifications();\n    this.applyModificationFile(viewer.doodadsData, viewer.doodadMetaData, modifications.w3d);\n    this.applyModificationFile(viewer.doodadsData, viewer.destructableMetaData, modifications.w3b);\n    this.applyModificationFile(viewer.unitsData, viewer.unitMetaData, modifications.w3u);\n    this.applyModificationFile(viewer.unitsData, viewer.unitMetaData, modifications.w3t);\n\n    this.loadDoodadsAndDestructibles();\n    this.loadUnitsAndItems();\n  }\n\n  die(): void {\n    this.worldScene.detach();\n  }\n\n  load(src: unknown): Promise<Resource | undefined> {\n    return this.viewer.load(src, this.pathSolver, this.solverParams);\n  }\n\n  loadMapInformation(): void {\n    const mpqFile = this.map.get('war3map.w3i');\n\n    if (!mpqFile) {\n      console.warn('Attempted to load war3map.w3i but it is not there. Using default tileset A.');\n      return;\n    }\n\n    const parser = new War3MapW3i();\n\n    try {\n      parser.load(mpqFile.bytes());\n    } catch (e) {\n      console.warn('Failed to correctly parse the map information file');\n    }\n\n    this.solverParams.tileset = parser.tileset.toLowerCase();\n\n    this.buildVersion = parser.getBuildVersion();\n\n    if (this.buildVersion > 131) {\n      this.solverParams.reforged = true;\n    }\n  }\n\n  async loadTerrainCliffsAndWater(): Promise<void> {\n    const mpqFile = this.map.get('war3map.w3e');\n\n    if (!mpqFile) {\n      console.warn('Attempted to load war3map.w3e, but it is not there.');\n      return;\n    }\n\n    const parser = new War3MapW3e();\n\n    try {\n      parser.load(mpqFile.bytes());\n    } catch (e) {\n      console.warn(`Failed to load war3map.w3e: ${e}`);\n      return;\n    }\n\n    const viewer = this.viewer;\n    const centerOffset = parser.centerOffset;\n    const mapSize = parser.mapSize;\n\n    this.corners = parser.corners;\n    this.centerOffset.set(centerOffset);\n    this.mapSize.set(mapSize);\n\n    // Override the grid based on the map.\n    this.worldScene.grid = new Grid(centerOffset[0], centerOffset[1], mapSize[0] * 128 - 128, mapSize[1] * 128 - 128, 16 * 128, 16 * 128);\n\n    const texturesExt = this.solverParams.reforged ? '.dds' : '.blp';\n    const tileset = parser.tileset;\n\n    const tilesetTextures = [];\n    const cliffTextures = [];\n    const waterTextures = [];\n\n    for (const groundTileset of parser.groundTilesets) {\n      const row = <MappedDataRow>viewer.terrainData.getRow(groundTileset);\n\n      this.tilesets.push(row);\n      \n      tilesetTextures.push(this.load(`${row.string('dir')}\\\\${row.string('file')}${texturesExt}`));\n    }\n\n    const blights = {\n      A: 'Ashen',\n      B: 'Barrens',\n      C: 'Felwood',\n      D: 'Cave',\n      F: 'Lordf',\n      G: 'Dungeon',\n      I: 'Ice',\n      J: 'DRuins',\n      K: 'Citadel',\n      L: 'Lords',\n      N: 'North',\n      O: 'Outland',\n      Q: 'VillageFall',\n      V: 'Village',\n      W: 'Lordw',\n      X: 'Village',\n      Y: 'Village',\n      Z: 'Ruins',\n    };\n\n    this.blightTextureIndex = this.tilesetTextures.length;\n    tilesetTextures.push(this.load(`TerrainArt\\\\Blight\\\\${blights[tileset]}_Blight${texturesExt}`));\n\n    for (const cliffTileset of parser.cliffTilesets) {\n      const row = <MappedDataRow>viewer.cliffTypesData.getRow(cliffTileset);\n\n      this.cliffTilesets.push(row);\n      cliffTextures.push(this.load(`${row.string('texDir')}\\\\${row.string('texFile')}${texturesExt}`));\n    }\n\n    const waterRow = <MappedDataRow>viewer.waterData.getRow(`${tileset}Sha`);\n\n    this.waterHeightOffset = waterRow.number('height');\n    this.waterIncreasePerFrame = waterRow.number('texRate') / 60;\n    this.waterTextures.length = 0;\n    this.maxDeepColor.set([waterRow.number('Dmax_R'), waterRow.number('Dmax_G'), waterRow.number('Dmax_B'), waterRow.number('Dmax_A')]);\n    this.minDeepColor.set([waterRow.number('Dmin_R'), waterRow.number('Dmin_G'), waterRow.number('Dmin_B'), waterRow.number('Dmin_A')]);\n    this.maxShallowColor.set([waterRow.number('Smax_R'), waterRow.number('Smax_G'), waterRow.number('Smax_B'), waterRow.number('Smax_A')]);\n    this.minShallowColor.set([waterRow.number('Smin_R'), waterRow.number('Smin_G'), waterRow.number('Smin_B'), waterRow.number('Smin_A')]);\n\n    for (let i = 0, l = waterRow.number('numTex'); i < l; i++) {\n      waterTextures.push(this.load(`${waterRow.string('texFile')}${i < 10 ? '0' : ''}${i}${texturesExt}`));\n    }\n\n    this.tilesetTextures = <Texture[]>await Promise.all(tilesetTextures);\n    this.cliffTextures = <Texture[]>await Promise.all(cliffTextures);\n    this.waterTextures = <Texture[]>await Promise.all(waterTextures);\n\n    const corners = parser.corners;\n    const [columns, rows] = this.mapSize;\n    const instanceCount = (columns - 1) * (rows - 1);\n    const cliffHeights = new Float32Array(columns * rows);\n    const cornerHeights = new Float32Array(columns * rows);\n    const waterHeights = new Float32Array(columns * rows);\n    const cornerTextures = new Uint8Array(instanceCount * 4);\n    const cornerVariations = new Uint8Array(instanceCount * 4);\n    const waterFlags = new Uint8Array(instanceCount);\n    let instance = 0;\n    const cliffs: {[key: string]: { locations: number[], textures: number[] }} = {};\n\n    this.columns = columns - 1;\n    this.rows = rows - 1;\n\n    for (let y = 0; y < rows; y++) {\n      for (let x = 0; x < columns; x++) {\n        const bottomLeft = corners[y][x];\n        const index = y * columns + x;\n\n        cliffHeights[index] = bottomLeft.groundHeight;\n        cornerHeights[index] = bottomLeft.groundHeight + bottomLeft.layerHeight - 2;\n        waterHeights[index] = bottomLeft.waterHeight;\n\n        if (y < rows - 1 && x < columns - 1) {\n          // Water can be used with cliffs and normal corners, so store water state regardless.\n          waterFlags[instance] = this.isWater(x, y);\n\n          // Is this a cliff, or a normal corner?\n          if (this.isCliff(x, y)) {\n            const bottomLeftLayer = bottomLeft.layerHeight;\n            const bottomRightLayer = corners[y][x + 1].layerHeight;\n            const topLeftLayer = corners[y + 1][x].layerHeight;\n            const topRightLayer = corners[y + 1][x + 1].layerHeight;\n            const base = Math.min(bottomLeftLayer, bottomRightLayer, topLeftLayer, topRightLayer);\n            const fileName = this.cliffFileName(bottomLeftLayer, bottomRightLayer, topLeftLayer, topRightLayer, base);\n\n            if (fileName !== 'AAAA') {\n              let cliffTexture = bottomLeft.cliffTexture;\n\n              /// ?\n              if (cliffTexture === 15) {\n                cliffTexture = 1;\n              }\n\n              const cliffRow = this.cliffTilesets[cliffTexture];\n              const dir = <string>cliffRow.string('cliffModelDir');\n              const path = `Doodads\\\\Terrain\\\\${dir}\\\\${dir}${fileName}${getCliffVariation(dir, fileName, bottomLeft.cliffVariation)}.mdx`;\n\n              if (!cliffs[path]) {\n                cliffs[path] = { locations: [], textures: []};\n              }\n\n              cliffs[path].locations.push((x + 1) * 128 + centerOffset[0], y * 128 + centerOffset[1], (base - 2) * 128);\n              cliffs[path].textures.push(cliffTexture);\n            }\n          } else {\n            const bottomLeftTexture = this.cornerTexture(x, y);\n            const bottomRightTexture = this.cornerTexture(x + 1, y);\n            const topLeftTexture = this.cornerTexture(x, y + 1);\n            const topRightTexture = this.cornerTexture(x + 1, y + 1);\n            const textures = unique([bottomLeftTexture, bottomRightTexture, topLeftTexture, topRightTexture]).sort();\n            let texture = textures[0];\n\n            cornerTextures[instance * 4] = texture + 1;\n            cornerVariations[instance * 4] = this.getVariation(texture, bottomLeft.groundVariation);\n\n            textures.shift();\n\n            for (let i = 0, l = textures.length; i < l; i++) {\n\n              let bitset = 0;\n\n              texture = textures[i];\n\n              if (bottomRightTexture === texture) {\n                bitset |= 0b0001;\n              }\n\n              if (bottomLeftTexture === texture) {\n                bitset |= 0b0010;\n              }\n\n              if (topRightTexture === texture) {\n                bitset |= 0b0100;\n              }\n\n              if (topLeftTexture === texture) {\n                bitset |= 0b1000;\n              }\n\n              cornerTextures[instance * 4 + 1 + i] = texture + 1;\n              cornerVariations[instance * 4 + 1 + i] = bitset;\n            }\n          }\n\n          instance += 1;\n        }\n      }\n    }\n\n    const gl = this.viewer.gl;\n    const webgl = this.viewer.webgl;\n\n    this.vertexBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]), gl.STATIC_DRAW);\n\n    this.faceBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.faceBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW);\n\n    this.cliffHeightMap = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, this.cliffHeightMap);\n    webgl.setTextureMode(gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.NEAREST, gl.NEAREST);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, columns, rows, 0, gl.ALPHA, gl.FLOAT, cliffHeights);\n\n    this.heightMap = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, this.heightMap);\n    webgl.setTextureMode(gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.NEAREST, gl.NEAREST);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, columns, rows, 0, gl.ALPHA, gl.FLOAT, cornerHeights);\n\n    this.waterHeightMap = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, this.waterHeightMap);\n    webgl.setTextureMode(gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.NEAREST, gl.NEAREST);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, columns, rows, 0, gl.ALPHA, gl.FLOAT, waterHeights);\n\n    this.instanceBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(instanceCount).map((currentValue, index) => index), gl.STATIC_DRAW);\n\n    this.textureBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, cornerTextures, gl.STATIC_DRAW);\n\n    this.variationBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.variationBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, cornerVariations, gl.STATIC_DRAW);\n\n    this.waterBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.waterBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, waterFlags, gl.STATIC_DRAW);\n\n    this.terrainReady = true;\n    this.anyReady = true;\n\n    const cliffShader = viewer.cliffShader;\n\n    const cliffPromises = Object.entries(cliffs).map(async (cliff) => {\n      const path = cliff[0];\n      const { locations, textures } = cliff[1];\n      const resource = await viewer.loadBaseFile(path, 'arrayBuffer');\n\n      if (resource) {\n        return new TerrainModel(this, <ArrayBuffer>resource.data, locations, textures, cliffShader);\n      }\n\n      return;\n    }).filter(x => x);\n\n    // Sometimes TS isn't the brightest.\n    const cliffPromisesForReal = <Promise<TerrainModel>[]>cliffPromises;\n\n    this.cliffModels = await Promise.all(cliffPromisesForReal);\n    this.cliffsReady = true;\n  }\n\n  loadDoodadsAndDestructibles(): void {\n    const mpqFile = this.map.get('war3map.doo');\n\n    if (!mpqFile) {\n      console.warn('Attempted to load war3map.doo but it is not there');\n      return;\n    }\n\n    const parser = new War3MapDoo();\n\n    try {\n      parser.load(mpqFile.bytes(), this.buildVersion);\n    } catch (e) {\n      console.warn(`Failed to load war3map.doo: ${e}`);\n      return;\n    }\n\n    // Doodads and destructibles.\n    for (const doodad of parser.doodads) {\n      try {\n        const row = this.viewer.doodadsData.getRow(doodad.id);\n\n        if (row) {\n          let file = row.string('file');\n\n          if (file) {\n            const numVar = row.number('numVar');\n\n            if (file.endsWith('.mdl')) {\n              file = file.slice(0, -4);\n            }\n\n            let fileVar = file;\n\n            file += '.mdx';\n\n            if (numVar > 1) {\n              fileVar += Math.min(doodad.variation, numVar - 1);\n            }\n\n            fileVar += '.mdx';\n\n            // First see if the model is local.\n            // Doodads refering to local models may have invalid variations, so if the variation doesn't exist, try without a variation.\n            const mpqFile = this.map.get(fileVar) || this.map.get(file);\n            let promise;\n\n            if (mpqFile) {\n              promise = this.load(mpqFile.name);\n            } else {\n              promise = this.load(fileVar);\n            }\n\n            promise.then((model) => {\n              if (model) {\n                this.doodads.push(new Doodad(this, <MdxModel>model, row, doodad));\n              }\n            });\n          } else {\n            console.log('Unknown doodad ID', doodad.id, doodad);\n          }\n        }\n      } catch (e) {\n        console.warn(`Failed to load doodad/destructible ID ${doodad.id}: ${e}`);\n      }\n    }\n\n    // Cliff/Terrain doodads.\n    for (const doodad of parser.terrainDoodads) {\n      try {\n        const row = <MappedDataRow>this.viewer.doodadsData.getRow(doodad.id);\n\n        this.load(`${row.string('file')}.mdx`)\n          .then((model) => {\n            if (model) {\n              this.terrainDoodads.push(new TerrainDoodad(this, <MdxModel>model, row, doodad));\n            }\n          });\n\n        // let pathTexture = <Texture>this.load(row.pathTex);\n\n        // pathTexture.whenLoaded(() => {\n        //   let startx = doodad.location[0];\n        //   let starty = doodad.location[1];\n        //   let endx = startx + pathTexture.width / 4;\n        //   let endy = starty + pathTexture.height / 4;\n\n        //   for (let x = startx; x < endx; x++) {\n        //     for (let y = starty; y < endy; y++) {\n\n        //     }\n        //   }\n        // });\n      } catch (e) {\n        console.warn(`Failed to load cliff/terrain doodad ID ${doodad.id}: ${e}`);\n      }\n    }\n\n    this.doodadsReady = true;\n    this.anyReady = true;\n  }\n\n  loadUnitsAndItems(): void {\n    const mpqFile = this.map.get('war3mapUnits.doo');\n\n    if (!mpqFile) {\n      console.warn('Attempted to load war3mapUnits.doo but it is not there');\n      return;\n    }\n\n    const parser = new War3MapUnitsDoo();\n\n    try {\n      parser.load(mpqFile.bytes(), this.buildVersion);\n    } catch (e) {\n      console.warn(`Failed to load war3mapUnits.doo: ${e}`);\n      return;\n    }\n\n    // Collect the units and items data.\n    for (const unit of parser.units) {\n      try {\n        let row: MappedDataRow | undefined;\n        let path;\n\n        // Hardcoded?\n        if (unit.id === 'sloc') {\n          path = 'Objects\\\\StartLocation\\\\StartLocation.mdx';\n        } else {\n          row = this.viewer.unitsData.getRow(unit.id);\n\n          if (row) {\n            path = row.string('file');\n\n            if (path) {\n              if (path.endsWith('.mdl')) {\n                path = path.slice(0, -4);\n              }\n\n              path += '.mdx';\n            }\n          }\n        }\n\n        if (path) {\n          this.load(path)\n            .then((model) => {\n              if (model) {\n                this.units.push(new Unit(this, <MdxModel>model, row, unit));\n              }\n            });\n        } else {\n          console.log('Unknown unit ID', unit.id, unit);\n        }\n      } catch (e) {\n        console.warn(`Failed to load unit/item ID ${unit.id}: ${e}`);\n      }\n    }\n\n    this.unitsReady = true;\n    this.anyReady = true;\n  }\n\n  /**\n   * Update the map.\n   */\n  update(): void {\n    if (this.anyReady) {\n      this.waterIndex += this.waterIncreasePerFrame;\n\n      if (this.waterIndex >= this.waterTextures.length) {\n        this.waterIndex = 0;\n      }\n\n      for (const doodad of this.doodads) {\n        doodad.update();\n      }\n\n      for (const unit of this.units) {\n        unit.update();\n      }\n    }\n  }\n\n  /**\n   * Render the map.\n   */\n  render(): void {\n    if (this.anyReady) {\n      const worldScene = this.worldScene;\n\n      worldScene.startFrame();\n      this.renderGround();\n      this.renderCliffs();\n      worldScene.renderOpaque();\n      this.renderWater();\n      worldScene.renderTranslucent();\n    }\n  }\n\n  renderGround(): void {\n    if (this.terrainReady) {\n      const gl = this.viewer.gl;\n      const webgl = this.viewer.webgl;\n      const instancedArrays = <ANGLE_instanced_arrays>webgl.extensions['ANGLE_instanced_arrays'];\n      const shader = this.viewer.groundShader;\n      const uniforms = shader.uniforms;\n      const attribs = shader.attribs;\n      const tilesetTextures = this.tilesetTextures;\n      const instanceAttrib = attribs['a_InstanceID'];\n      const positionAttrib = attribs['a_position'];\n      const texturesAttrib = attribs['a_textures'];\n      const variationsAttrib = attribs['a_variations'];\n      const tilesetCount = tilesetTextures.length; // This includes the blight texture.\n\n      gl.enable(gl.BLEND);\n      gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n      webgl.useShader(shader);\n\n      gl.uniformMatrix4fv(uniforms['u_VP'], false, this.worldScene.camera.viewProjectionMatrix);\n      gl.uniform2fv(uniforms['u_offset'], this.centerOffset);\n      gl.uniform2f(uniforms['u_size'], this.columns, this.rows);\n      gl.uniform1i(uniforms['u_heightMap'], 15);\n\n      gl.activeTexture(gl.TEXTURE15);\n      gl.bindTexture(gl.TEXTURE_2D, this.heightMap);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n      gl.vertexAttribPointer(positionAttrib, 2, gl.FLOAT, false, 0, 0);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer);\n      gl.vertexAttribPointer(instanceAttrib, 1, gl.FLOAT, false, 0, 0);\n      instancedArrays.vertexAttribDivisorANGLE(instanceAttrib, 1);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);\n      gl.vertexAttribPointer(texturesAttrib, 4, gl.UNSIGNED_BYTE, false, 0, 0);\n      instancedArrays.vertexAttribDivisorANGLE(texturesAttrib, 1);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.variationBuffer);\n      gl.vertexAttribPointer(variationsAttrib, 4, gl.UNSIGNED_BYTE, false, 0, 0);\n      instancedArrays.vertexAttribDivisorANGLE(variationsAttrib, 1);\n\n      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.faceBuffer);\n\n      gl.uniform1f(uniforms['u_baseTileset'], 0);\n\n      for (let i = 0, l = Math.min(tilesetCount, 15); i < l; i++) {\n        const isExtended = tilesetTextures[i].width > tilesetTextures[i].height ? 1 : 0;\n\n        gl.uniform1f(uniforms[`u_extended[${i}]`], isExtended);\n        gl.uniform1i(uniforms[`u_tilesets[${i}]`], i);\n\n        webgl.bindTexture(tilesetTextures[i], i);\n      }\n\n      instancedArrays.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, this.rows * this.columns);\n\n      if (tilesetCount > 15) {\n        gl.uniform1f(uniforms['u_baseTileset'], 15);\n\n        for (let i = 0, l = tilesetCount - 15; i < l; i++) {\n          const isExtended = tilesetTextures[i + 15].width > tilesetTextures[i + 15].height ? 1 : 0;\n\n          gl.uniform1f(uniforms[`u_extended[${i}]`], isExtended);\n\n          webgl.bindTexture(tilesetTextures[i + 15], i);\n        }\n\n        instancedArrays.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, this.rows * this.columns);\n      }\n\n      instancedArrays.vertexAttribDivisorANGLE(texturesAttrib, 0);\n      instancedArrays.vertexAttribDivisorANGLE(variationsAttrib, 0);\n      instancedArrays.vertexAttribDivisorANGLE(instanceAttrib, 0);\n    }\n  }\n\n  renderWater(): void {\n    if (this.terrainReady) {\n      const gl = this.viewer.gl;\n      const webgl = this.viewer.webgl;\n      const instancedArrays = <ANGLE_instanced_arrays>webgl.extensions['ANGLE_instanced_arrays'];\n      const shader = this.viewer.waterShader;\n      const uniforms = shader.uniforms;\n      const attribs = shader.attribs;\n      const instanceAttrib = attribs['a_InstanceID'];\n      const positionAttrib = attribs['a_position'];\n      const isWaterAttrib = attribs['a_isWater'];\n\n      gl.depthMask(false);\n\n      gl.enable(gl.BLEND);\n      gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n      webgl.useShader(shader);\n\n      gl.uniformMatrix4fv(uniforms['u_VP'], false, this.worldScene.camera.viewProjectionMatrix);\n      gl.uniform2fv(uniforms['u_offset'], this.centerOffset);\n      gl.uniform2f(uniforms['u_size'], this.columns, this.rows);\n      gl.uniform1i(uniforms['u_heightMap'], 0);\n      gl.uniform1i(uniforms['u_waterHeightMap'], 1);\n      gl.uniform1i(uniforms['u_waterTexture'], 2);\n      gl.uniform1f(uniforms['u_offsetHeight'], this.waterHeightOffset);\n      gl.uniform4fv(uniforms['u_maxDeepColor'], this.maxDeepColor);\n      gl.uniform4fv(uniforms['u_minDeepColor'], this.minDeepColor);\n      gl.uniform4fv(uniforms['u_maxShallowColor'], this.maxShallowColor);\n      gl.uniform4fv(uniforms['u_minShallowColor'], this.minShallowColor);\n\n      gl.activeTexture(gl.TEXTURE0);\n      gl.bindTexture(gl.TEXTURE_2D, this.heightMap);\n\n      gl.activeTexture(gl.TEXTURE1);\n      gl.bindTexture(gl.TEXTURE_2D, this.waterHeightMap);\n\n      webgl.bindTexture(this.waterTextures[this.waterIndex | 0], 2);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n      gl.vertexAttribPointer(positionAttrib, 2, gl.FLOAT, false, 8, 0);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer);\n      gl.vertexAttribPointer(instanceAttrib, 1, gl.FLOAT, false, 4, 0);\n      instancedArrays.vertexAttribDivisorANGLE(instanceAttrib, 1);\n\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.waterBuffer);\n      gl.vertexAttribPointer(isWaterAttrib, 1, gl.UNSIGNED_BYTE, false, 1, 0);\n      instancedArrays.vertexAttribDivisorANGLE(isWaterAttrib, 1);\n\n      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.faceBuffer);\n      instancedArrays.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, this.rows * this.columns);\n\n      instancedArrays.vertexAttribDivisorANGLE(isWaterAttrib, 0);\n      instancedArrays.vertexAttribDivisorANGLE(instanceAttrib, 0);\n    }\n  }\n\n  renderCliffs(): void {\n    if (this.cliffsReady) {\n      const gl = this.viewer.gl;\n      const webgl = this.viewer.webgl;\n      const instancedArrays = <ANGLE_instanced_arrays>webgl.extensions['ANGLE_instanced_arrays'];\n      const vertexArrayObject = <OES_vertex_array_object>webgl.extensions['OES_vertex_array_object'];\n      const shader = this.viewer.cliffShader;\n      const attribs = shader.attribs;\n      const uniforms = shader.uniforms;\n\n      gl.disable(gl.BLEND);\n\n      shader.use();\n\n      gl.uniformMatrix4fv(uniforms['u_VP'], false, this.worldScene.camera.viewProjectionMatrix);\n      gl.uniform1i(uniforms['u_heightMap'], 0);\n      gl.uniform2f(uniforms['u_pixel'], 1 / (this.columns + 1), 1 / (this.rows + 1));\n      gl.uniform2fv(uniforms['u_centerOffset'], this.centerOffset);\n      gl.uniform1i(uniforms['u_texture1'], 1);\n      gl.uniform1i(uniforms['u_texture2'], 2);\n\n      gl.activeTexture(gl.TEXTURE0);\n      gl.bindTexture(gl.TEXTURE_2D, this.cliffHeightMap);\n\n      gl.activeTexture(gl.TEXTURE1);\n      gl.bindTexture(gl.TEXTURE_2D, this.cliffTextures[0].webglResource);\n\n      if (this.cliffTextures.length > 1) {\n        gl.activeTexture(gl.TEXTURE2);\n        gl.bindTexture(gl.TEXTURE_2D, this.cliffTextures[1].webglResource);\n      }\n\n      // Set instanced attributes.\n      if (!vertexArrayObject) {\n        instancedArrays.vertexAttribDivisorANGLE(attribs['a_instancePosition'], 1);\n        instancedArrays.vertexAttribDivisorANGLE(attribs['a_instanceTexture'], 1);\n      }\n\n      // Render the cliffs.\n      for (const cliff of this.cliffModels) {\n        cliff.render(shader);\n      }\n\n      // Clear instanced attributes.\n      if (!vertexArrayObject) {\n        instancedArrays.vertexAttribDivisorANGLE(attribs['a_instancePosition'], 0);\n        instancedArrays.vertexAttribDivisorANGLE(attribs['a_instanceTexture'], 0);\n      }\n    }\n  }\n\n  cliffFileName(bottomLeftLayer: number, bottomRightLayer: number, topLeftLayer: number, topRightLayer: number, base: number): string {\n    return String.fromCharCode(65 + bottomLeftLayer - base) +\n      String.fromCharCode(65 + topLeftLayer - base) +\n      String.fromCharCode(65 + topRightLayer - base) +\n      String.fromCharCode(65 + bottomRightLayer - base);\n  }\n\n  getVariation(groundTexture: number, variation: number): number {\n    const texture = this.tilesetTextures[groundTexture];\n\n    // Extended?\n    if (texture.width > texture.height) {\n      if (variation < 16) {\n        return 16 + variation;\n      } else if (variation === 16) {\n        return 15;\n      } else {\n        return 0;\n      }\n    } else {\n      if (variation === 0) {\n        return 0;\n      } else {\n        return 15;\n      }\n    }\n  }\n\n  /**\n   * Is the corner at the given column and row a cliff?\n   */\n  isCliff(column: number, row: number): boolean {\n    if (column < 1 || column > this.columns - 1 || row < 1 || row > this.rows - 1) {\n      return false;\n    }\n\n    const corners = this.corners;\n    const bottomLeft = corners[row][column].layerHeight;\n    const bottomRight = corners[row][column + 1].layerHeight;\n    const topLeft = corners[row + 1][column].layerHeight;\n    const topRight = corners[row + 1][column + 1].layerHeight;\n\n    return bottomLeft !== bottomRight || bottomLeft !== topLeft || bottomLeft !== topRight;\n  }\n\n  /**\n   * Is the tile at the given column and row water?\n   */\n  isWater(column: number, row: number): number {\n    const corners = this.corners;\n\n    return corners[row][column].water || corners[row][column + 1].water || corners[row + 1][column].water || corners[row + 1][column + 1].water;\n  }\n\n  /**\n   * Given a cliff index, get its ground texture index.\n   * This is an index into the tilset textures.\n   */\n  cliffGroundIndex(whichCliff: number): number {\n    const whichTileset = this.cliffTilesets[whichCliff].string('groundTile');\n    const tilesets = this.tilesets;\n\n    for (let i = 0, l = tilesets.length; i < l; i++) {\n      if (tilesets[i].string('tileID') === whichTileset) {\n        return i;\n      }\n    }\n\n    return 0;\n  }\n\n  /**\n   * Get the ground texture of a corner, whether it's normal ground, a cliff, or a blighted corner.\n   */\n  cornerTexture(column: number, row: number): number {\n    const corners = this.corners;\n    const columns = this.columns;\n    const rows = this.rows;\n\n    for (let y = -1; y < 1; y++) {\n      for (let x = -1; x < 1; x++) {\n        if (column + x > 0 && column + x < columns - 1 && row + y > 0 && row + y < rows - 1) {\n          if (this.isCliff(column + x, row + y)) {\n            let texture = corners[row + y][column + x].cliffTexture;\n\n            if (texture === 15) {\n              texture = 1;\n            }\n\n            return this.cliffGroundIndex(texture);\n          }\n        }\n      }\n    }\n\n    const corner = corners[row][column];\n\n    // Is this corner blighted?\n    if (corner.blight) {\n      return this.blightTextureIndex;\n    }\n\n    return corner.groundTexture;\n  }\n\n  applyModificationFile(dataMap: MappedData, metadataMap: MappedData, modificationFile: War3MapW3u | War3MapW3d | undefined): void {\n    if (modificationFile) {\n      // Modifications to built-in objects\n      this.applyModificationTable(dataMap, metadataMap, modificationFile.originalTable);\n\n      // Declarations of user-defined objects\n      this.applyModificationTable(dataMap, metadataMap, modificationFile.customTable);\n    }\n  }\n\n  applyModificationTable(dataMap: MappedData, metadataMap: MappedData, modificationTable: ModificationTable): void {\n    for (const modificationObject of modificationTable.objects) {\n      let row;\n\n      if (modificationObject.newId !== '') {\n        row = dataMap.getRow(modificationObject.newId);\n\n        if (!row) {\n          row = new MappedDataRow();\n\n          row.map = Object.assign({}, (<MappedDataRow>dataMap.getRow(modificationObject.oldId)).map);\n\n          dataMap.setRow(modificationObject.newId, row);\n        }\n      } else {\n        row = <MappedDataRow>dataMap.getRow(modificationObject.oldId);\n      }\n\n      for (const modification of modificationObject.modifications) {\n        const metadata = metadataMap.getRow(modification.id);\n\n        if (metadata) {\n          row.set(<string>metadata.string('field'), modification.value);\n        } else {\n          console.warn('Unknown modification ID', modification);\n        }\n      }\n    }\n  }\n\n  groundNormal(out: vec3, x: number, y: number): vec3 {\n    const centerOffset = this.centerOffset;\n    const mapSize = this.mapSize;\n\n    x = (x - centerOffset[0]) / 128;\n    y = (y - centerOffset[1]) / 128;\n\n    const cellX = x | 0;\n    const cellY = y | 0;\n\n    // See if this coordinate is in the map\n    if (cellX >= 0 && cellX < mapSize[0] - 1 && cellY >= 0 && cellY < mapSize[1] - 1) {\n      // See http://gamedev.stackexchange.com/a/24574\n      const corners = this.corners;\n      const bottomLeft = corners[cellY][cellX].groundHeight;\n      const bottomRight = corners[cellY][cellX + 1].groundHeight;\n      const topLeft = corners[cellY + 1][cellX].groundHeight;\n      const topRight = corners[cellY + 1][cellX + 1].groundHeight;\n      const sqX = x - cellX;\n      const sqY = y - cellY;\n\n      if (sqX + sqY < 1) {\n        vec3.set(normalHeap1, 1, 0, bottomRight - bottomLeft);\n        vec3.set(normalHeap2, 0, 1, topLeft - bottomLeft);\n      } else {\n        vec3.set(normalHeap1, -1, 0, topRight - topLeft);\n        vec3.set(normalHeap2, 0, 1, topRight - bottomRight);\n      }\n\n      vec3.normalize(out, vec3.cross(out, normalHeap1, normalHeap2));\n    } else {\n      vec3.set(out, 0, 0, 1);\n    }\n\n    return out;\n  }\n}\n\n/*\n  heightAt(location) {\n    let heightMap = this.heightMap,\n      offset = this.offset,\n      x = (location[0] / 128) + offset[0],\n      y = (location[1] / 128) + offset[1];\n\n    let minY = Math.floor(y),\n      maxY = Math.ceil(y),\n      minX = Math.floor(x),\n      maxX = Math.ceil(x);\n\n    // See if this coordinate is in the map\n    if (maxY > 0 && minY < heightMap.length - 1 && maxX > 0 && minX < heightMap[0].length - 1) {\n      // See http://gamedev.stackexchange.com/a/24574\n      let triZ0 = heightMap[minY][minX],\n        triZ1 = heightMap[minY][maxX],\n        triZ2 = heightMap[maxY][minX],\n        triZ3 = heightMap[maxY][maxX],\n        sqX = x - minX,\n        sqZ = y - minY,\n        height;\n\n      if ((sqX + sqZ) < 1) {\n        height = triZ0 + (triZ1 - triZ0) * sqX + (triZ2 - triZ0) * sqZ;\n      } else {\n        height = triZ3 + (triZ1 - triZ3) * (1 - sqZ) + (triZ2 - triZ3) * (1 - sqX);\n      }\n\n      return height * 128;\n    }\n\n    return 0;\n  }\n  */\n"
  },
  {
    "path": "src/viewer/handlers/w3x/shaders/cliffs.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\n\nconst shader = `\n// #extension GL_OES_standard_derivatives : enable\n\n${precision}\n\nuniform sampler2D u_texture1;\nuniform sampler2D u_texture2;\n\nvarying vec3 v_normal;\nvarying vec2 v_uv;\nvarying float v_texture;\nvarying vec3 v_position;\n\n// const vec3 lightDirection = normalize(vec3(-0.3, -0.3, 0.25));\n\nvec4 sample(float texture, vec2 uv) {\n  // int(0.0) == 0 is not always true.\n  int i = int(texture + 0.1);\n\n  if (i == 0) {\n    return texture2D(u_texture1, uv);\n  } else {\n    return texture2D(u_texture2, uv);\n  }\n}\n\nvoid main() {\n  vec4 color = sample(v_texture, v_uv);\n\n  // vec3 faceNormal = cross(dFdx(v_position), dFdy(v_position));\n  // vec3 normal = normalize((faceNormal + v_normal) * 0.5);\n\n  // color *= clamp(dot(normal, lightDirection) + 0.45, 0.1, 1.0);\n\n  gl_FragColor = color;\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/w3x/shaders/cliffs.vert.ts",
    "content": "const shader = `\nuniform mat4 u_VP;\nuniform sampler2D u_heightMap;\nuniform vec2 u_pixel;\nuniform vec2 u_centerOffset;\n\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_uv;\nattribute vec3 a_instancePosition;\nattribute float a_instanceTexture;\n\nvarying vec3 v_normal;\nvarying vec2 v_uv;\nvarying float v_texture;\nvarying vec3 v_position;\n\nvoid main() {\n  // Half of a pixel in the cliff height map.\n  vec2 halfPixel = u_pixel * 0.5;\n\n  // The bottom left corner of the map tile this vertex is on.\n  vec2 corner = floor((a_instancePosition.xy - vec2(1.0, 0.0) - u_centerOffset.xy) / 128.0);\n\n  // Get the 4 closest heights in the height map.\n  float bottomLeft = texture2D(u_heightMap, corner * u_pixel + halfPixel).a;\n  float bottomRight = texture2D(u_heightMap, (corner + vec2(1.0, 0.0)) * u_pixel + halfPixel).a;\n  float topLeft = texture2D(u_heightMap, (corner + vec2(0.0, 1.0)) * u_pixel + halfPixel).a;\n  float topRight = texture2D(u_heightMap, (corner + vec2(1.0, 1.0)) * u_pixel + halfPixel).a;\n  \n  // Do a bilinear interpolation between the heights to get the final value.\n  float bottom = mix(bottomRight, bottomLeft, -a_position.x / 128.0);\n  float top = mix(topRight, topLeft, -a_position.x / 128.0);\n  float height = mix(bottom, top, a_position.y / 128.0);\n\n  v_normal = a_normal;\n  v_uv = a_uv;\n  v_texture = a_instanceTexture;\n  v_position = a_position + vec3(a_instancePosition.xy, a_instancePosition.z + height * 128.0);\n\n  gl_Position = u_VP * vec4(v_position, 1.0);\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/w3x/shaders/ground.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\n\nconst shader = `\n${precision}\n\nuniform sampler2D u_tilesets[15];\n\nvarying vec4 v_tilesets;\nvarying vec2 v_uv[4];\nvarying vec3 v_normal;\n\nconst vec3 lightDirection = normalize(vec3(-0.3, -0.3, 0.25));\n\nvec4 sample(float tileset, vec2 uv) {\n  // 1.0 - 1.0 == 0.0 is not always true.\n  int i = int(tileset - 0.6);\n\n  if (i == 0) {\n    return texture2D(u_tilesets[0], uv);\n  } else if (i == 1) {\n    return texture2D(u_tilesets[1], uv);\n  } else if (i == 2) {\n    return texture2D(u_tilesets[2], uv);\n  } else if (i == 3) {\n    return texture2D(u_tilesets[3], uv);\n  } else if (i == 4) {\n    return texture2D(u_tilesets[4], uv);\n  } else if (i == 5) {\n    return texture2D(u_tilesets[5], uv);\n  } else if (i == 6) {\n    return texture2D(u_tilesets[6], uv);\n  } else if (i == 7) {\n    return texture2D(u_tilesets[7], uv);\n  } else if (i == 8) {\n    return texture2D(u_tilesets[8], uv);\n  } else if (i == 9) {\n    return texture2D(u_tilesets[9], uv);\n  } else if (i == 10) {\n    return texture2D(u_tilesets[10], uv);\n  } else if (i == 11) {\n    return texture2D(u_tilesets[11], uv);\n  } else if (i == 12) {\n    return texture2D(u_tilesets[12], uv);\n  } else if (i == 13) {\n    return texture2D(u_tilesets[13], uv);\n  } else if (i == 14) {\n    return texture2D(u_tilesets[14], uv);\n  }\n}\n\nvec4 blend(vec4 color, float tileset, vec2 uv) {\n  vec4 texel = sample(tileset, uv);\n\n  return mix(color, texel, texel.a);\n}\n\nvoid main() {\n  vec4 color = sample(v_tilesets[0], v_uv[0]);\n\n  if (v_tilesets[1] > 0.5) {\n    color = blend(color, v_tilesets[1], v_uv[1]);\n  }\n\n  if (v_tilesets[2] > 0.5) {\n    color = blend(color, v_tilesets[2], v_uv[2]);\n  }\n\n  if (v_tilesets[3] > 0.5) {\n    color = blend(color, v_tilesets[3], v_uv[3]);\n  }\n\n  //color *= clamp(dot(v_normal, lightDirection) + 0.45, 0.0, 1.0);\n\n  gl_FragColor = vec4(color.rgb, 1.0);\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/w3x/shaders/ground.vert.ts",
    "content": "const shader = `\nuniform mat4 u_VP;\nuniform sampler2D u_heightMap;\nuniform vec2 u_size;\nuniform vec2 u_offset;\nuniform bool u_extended[14];\nuniform float u_baseTileset;\n\nattribute vec2 a_position;\nattribute float a_InstanceID;\nattribute vec4 a_textures;\nattribute vec4 a_variations;\n\nvarying vec4 v_tilesets;\nvarying vec2 v_uv[4];\nvarying vec3 v_normal;\n\nvec2 getCell(float variation) {\n  if (variation < 16.0) {\n    return vec2(mod(variation, 4.0), floor(variation / 4.0));\n  } else {\n    variation -= 16.0;\n\n    return vec2(4.0 + mod(variation, 4.0), floor(variation / 4.0));\n  }\n}\n\nvec2 getUV(vec2 position, bool extended, float variation) {\n  vec2 cell = getCell(variation);\n  vec2 cellSize = vec2(extended ? 0.125 : 0.25, 0.25);\n  vec2 uv = vec2(position.x, 1.0 - position.y);\n  vec2 pixelSize = vec2(1.0 / 512.0, 1.0 / 256.0); /// Note: hardcoded to 512x256 for now.\n\n  return clamp((cell + uv) * cellSize, cell * cellSize + pixelSize, (cell + 1.0) * cellSize - pixelSize); \n}\n\nvoid main() {\n  vec4 textures = a_textures - u_baseTileset;\n  \n  if (textures[0] > 0.0 || textures[1] > 0.0 || textures[2] > 0.0 || textures[3] > 0.0) {\n    v_tilesets = textures;\n\n    v_uv[0] = getUV(a_position, u_extended[int(textures[0]) - 1], a_variations[0]);\n    v_uv[1] = getUV(a_position, u_extended[int(textures[1]) - 1], a_variations[1]);\n    v_uv[2] = getUV(a_position, u_extended[int(textures[2]) - 1], a_variations[2]);\n    v_uv[3] = getUV(a_position, u_extended[int(textures[3]) - 1], a_variations[3]);\n\n    vec2 corner = vec2(mod(a_InstanceID, u_size.x), floor(a_InstanceID / u_size.x));\n    vec2 base = corner + a_position;\n    float height = texture2D(u_heightMap, base / u_size).a;\n\n    float hL = texture2D(u_heightMap, vec2(base - vec2(1.0, 0.0)) / (u_size)).a;\n    float hR = texture2D(u_heightMap, vec2(base + vec2(1.0, 0.0)) / (u_size)).a;\n    float hD = texture2D(u_heightMap, vec2(base - vec2(0.0, 1.0)) / (u_size)).a;\n    float hU = texture2D(u_heightMap, vec2(base + vec2(0.0, 1.0)) / (u_size)).a;\n\n    v_normal = normalize(vec3(hL - hR, hD - hU, 2.0));\n\n    gl_Position = u_VP * vec4(base * 128.0 + u_offset, height * 128.0, 1.0);\n  } else {\n    v_tilesets = vec4(0.0);\n\n    v_uv[0] = vec2(0.0);\n    v_uv[1] = vec2(0.0);\n    v_uv[2] = vec2(0.0);\n    v_uv[3] = vec2(0.0);\n\n    v_normal = vec3(0.0);\n\n    gl_Position = vec4(0.0);\n  }\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/w3x/shaders/water.frag.ts",
    "content": "import precision from '../../shaders/precision.glsl';\n\nconst shader = `\n${precision}\n\nuniform sampler2D u_waterTexture;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main() {\n  gl_FragColor = texture2D(u_waterTexture, v_uv) * v_color;\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/w3x/shaders/water.vert.ts",
    "content": "const shader = `\nuniform mat4 u_VP;\nuniform sampler2D u_heightMap;\nuniform sampler2D u_waterHeightMap;\nuniform vec2 u_size;\nuniform vec2 u_offset;\nuniform float u_offsetHeight;\nuniform vec4 u_minDeepColor;\nuniform vec4 u_maxDeepColor;\nuniform vec4 u_minShallowColor;\nuniform vec4 u_maxShallowColor;\n\nattribute vec2 a_position;\nattribute float a_InstanceID;\nattribute float a_isWater;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nconst float minDepth = 10.0 / 128.0;\nconst float deepLevel = 64.0 / 128.0;\nconst float maxDepth = 72.0 / 128.0;\n\nvoid main() {\n  if (a_isWater > 0.5) {\n    v_uv = a_position;\n\n    vec2 corner = vec2(mod(a_InstanceID, u_size.x), floor(a_InstanceID / u_size.x));\n    vec2 base = corner + a_position;\n    float height = texture2D(u_heightMap, base / u_size).a;\n    float waterHeight = texture2D(u_waterHeightMap, base / u_size).a + u_offsetHeight;\n    float value = clamp(waterHeight - height, 0.0, 1.0);\n\n    if (value <= deepLevel) {\n      value = max(0.0, value - minDepth) / (deepLevel - minDepth);\n      v_color = mix(u_minShallowColor, u_maxShallowColor, value) / 255.0;\n    } else {\n      value = clamp(value - deepLevel, 0.0, maxDepth - deepLevel) / (maxDepth - deepLevel);\n      v_color = mix(u_minDeepColor, u_maxDeepColor, value) / 255.0;\n    }\n\n    gl_Position = u_VP * vec4(base * 128.0 + u_offset, waterHeight * 128.0, 1.0);\n  } else {\n    v_uv = vec2(0.0);\n    v_color = vec4(0.0);\n\n    gl_Position = vec4(0.0);\n  }\n}\n`;\n\nexport default shader;\n"
  },
  {
    "path": "src/viewer/handlers/w3x/standsequence.ts",
    "content": "import Sequence from '../mdx/sequence';\nimport MdxModel from '../mdx/model';\nimport MdxModelInstance from '../mdx/modelinstance';\n\ninterface FilteredSequence {\n  sequence: Sequence;\n  index: number;\n}\n\nfunction sequenceSorter(a: FilteredSequence, b: FilteredSequence): number {\n  return a.sequence.rarity - b.sequence.rarity;\n}\n\nfunction filterSequences(type: string, sequences: Sequence[]): FilteredSequence[] {\n  const filtered = [];\n\n  for (let i = 0, l = sequences.length; i < l; i++) {\n    const sequence = sequences[i],\n      name = sequence.name.split('-')[0].replace(/\\d/g, '').trim().toLowerCase();\n\n    if (name === type) {\n      filtered.push({ sequence, index: i });\n    }\n  }\n\n  return filtered;\n}\n\nfunction selectSequence(type: string, sequences: Sequence[]): FilteredSequence {\n  const filtered = filterSequences(type, sequences);\n  let i, l;\n\n  filtered.sort(sequenceSorter);\n\n  for (i = 0, l = filtered.length; i < l; i++) {\n    const sequence = filtered[i].sequence;\n    const rarity = sequence.rarity;\n\n    if (rarity === 0) {\n      break;\n    }\n\n    if (Math.random() * 10 > rarity) {\n      return filtered[i];\n    }\n  }\n\n  const sequencesLeft = filtered.length - i;\n  const random = i + Math.floor(Math.random() * sequencesLeft);\n  const sequence = filtered[random];\n\n  return sequence;\n}\n\nexport default function randomStandSequence(target: MdxModelInstance): void {\n  const model = <MdxModel>target.model;\n  const sequences = model.sequences;\n  const sequence = selectSequence('stand', sequences);\n\n  if (sequence) {\n    target.setSequence(sequence.index);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/terraindoodad.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { VEC3_UNIT_Z } from '../../../common/gl-matrix-addon';\nimport { degToRad } from '../../../common/math';\nimport { MappedDataRow } from '../../../utils/mappeddata';\nimport DooTerrainDoodad from '../../../parsers/w3x/doo/terraindoodad';\nimport MdxModel from '../mdx/model';\nimport MdxModelInstance from '../mdx/modelinstance';\nimport War3MapViewerMap from './map';\n\n\nconst locationHeap = vec3.create();\n/**\n * A cliff/terrain doodad.\n */\nexport default class TerrainDoodad {\n  instance: MdxModelInstance;\n  row: MappedDataRow;\n\n  constructor(map: War3MapViewerMap, model: MdxModel, row: MappedDataRow, doodad: DooTerrainDoodad) {\n    const centeroffset = map.centerOffset;\n    const instance = model.addInstance();\n\n    locationHeap[0] = doodad.location[0] * 128 + centeroffset[0] + 128;\n    locationHeap[1] = doodad.location[1] * 128 + centeroffset[1] + 128;\n\n    instance.move(locationHeap);\n    instance.rotateLocal(quat.setAxisAngle(quat.create(), VEC3_UNIT_Z, degToRad(row.number('fixedRot'))));\n    instance.setScene(map.worldScene);\n\n    this.instance = instance;\n    this.row = row;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/terrainmodel.ts",
    "content": "import MdlxModel from '../../../parsers/mdlx/model';\nimport Shader from '../../gl/shader';\nimport War3MapViewerMap from './map';\n\n/**\n * A static terrain model.\n */\nexport default class TerrainModel {\n  map: War3MapViewerMap;\n  vertexBuffer: WebGLBuffer;\n  faceBuffer: WebGLBuffer;\n  normalsOffset: number;\n  uvsOffset: number;\n  elements: number;\n  locationAndTextureBuffer: WebGLBuffer;\n  texturesOffset: number;\n  instances: number;\n  vao: WebGLVertexArrayObjectOES | null;\n\n  constructor(map: War3MapViewerMap, arrayBuffer: ArrayBuffer, locations: number[], textures: number[], shader: Shader) {\n    const gl = map.viewer.gl;\n    const webgl = map.viewer.webgl;\n    const instancedArrays = <ANGLE_instanced_arrays>webgl.extensions['ANGLE_instanced_arrays'];\n    const vertexArrayObject = <OES_vertex_array_object>webgl.extensions['OES_vertex_array_object'];\n\n    const parser = new MdlxModel();\n    parser.load(arrayBuffer);\n\n    const geoset = parser.geosets[0];\n    const vertices = geoset.vertices;\n    const normals = geoset.normals;\n    const uvs = geoset.uvSets[0];\n    const faces = geoset.faces;\n    const normalsOffset = vertices.byteLength;\n    const uvsOffset = normalsOffset + normals.byteLength;\n    let vao = null;\n    const attribs = shader.attribs;\n\n    if (vertexArrayObject) {\n      vao = vertexArrayObject.createVertexArrayOES();\n      vertexArrayObject.bindVertexArrayOES(vao);\n    }\n\n    const vertexBuffer = <WebGLBuffer>gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, uvsOffset + uvs.byteLength, gl.STATIC_DRAW);\n    gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);\n    gl.bufferSubData(gl.ARRAY_BUFFER, normalsOffset, normals);\n    gl.bufferSubData(gl.ARRAY_BUFFER, uvsOffset, uvs);\n\n    if (vertexArrayObject) {\n      gl.vertexAttribPointer(attribs['a_position'], 3, gl.FLOAT, false, 0, 0);\n      gl.enableVertexAttribArray(attribs['a_position']);\n\n      gl.vertexAttribPointer(attribs['a_normal'], 3, gl.FLOAT, false, 0, normalsOffset);\n      gl.enableVertexAttribArray(attribs['a_normal']);\n\n      gl.vertexAttribPointer(attribs['a_uv'], 2, gl.FLOAT, false, 0, uvsOffset);\n      gl.enableVertexAttribArray(attribs['a_uv']);\n    }\n\n    const texturesOffset = locations.length * 4;\n    const locationAndTextureBuffer = <WebGLBuffer>gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, locationAndTextureBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, texturesOffset + textures.length, gl.STATIC_DRAW);\n    gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(locations));\n    gl.bufferSubData(gl.ARRAY_BUFFER, texturesOffset, new Uint8Array(textures));\n\n    if (vertexArrayObject) {\n      gl.vertexAttribPointer(attribs['a_instancePosition'], 3, gl.FLOAT, false, 0, 0);\n      gl.enableVertexAttribArray(attribs['a_instancePosition']);\n      instancedArrays.vertexAttribDivisorANGLE(attribs['a_instancePosition'], 1);\n\n      gl.vertexAttribPointer(attribs['a_instanceTexture'], 1, gl.UNSIGNED_BYTE, false, 0, texturesOffset);\n      gl.enableVertexAttribArray(attribs['a_instanceTexture']);\n      instancedArrays.vertexAttribDivisorANGLE(attribs['a_instanceTexture'], 1);\n\n    }\n\n    const faceBuffer = <WebGLBuffer>gl.createBuffer();\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, faceBuffer);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW);\n\n    if (vertexArrayObject) {\n      vertexArrayObject.bindVertexArrayOES(null);\n    }\n\n    this.map = map;\n    this.vertexBuffer = vertexBuffer;\n    this.faceBuffer = faceBuffer;\n    this.normalsOffset = normalsOffset;\n    this.uvsOffset = uvsOffset;\n    this.elements = faces.length;\n    this.locationAndTextureBuffer = locationAndTextureBuffer;\n    this.texturesOffset = texturesOffset;\n    this.instances = locations.length / 3;\n    this.vao = vao;\n  }\n\n  render(shader: Shader): void {\n    const viewer = this.map.viewer;\n    const gl = viewer.gl;\n    const webgl = viewer.webgl;\n    const instancedArrays = <ANGLE_instanced_arrays>webgl.extensions['ANGLE_instanced_arrays'];\n    const vertexArrayObject = <OES_vertex_array_object>webgl.extensions['OES_vertex_array_object'];\n    const attribs = shader.attribs;\n\n    if (vertexArrayObject) {\n      vertexArrayObject.bindVertexArrayOES(this.vao);\n    } else {\n      // Locations and textures.\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.locationAndTextureBuffer);\n      gl.vertexAttribPointer(attribs['a_instancePosition'], 3, gl.FLOAT, false, 0, 0);\n      gl.vertexAttribPointer(attribs['a_instanceTexture'], 1, gl.UNSIGNED_BYTE, false, 0, this.texturesOffset);\n\n      // Vertices.\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n      gl.vertexAttribPointer(attribs['a_position'], 3, gl.FLOAT, false, 0, 0);\n      gl.vertexAttribPointer(attribs['a_normal'], 3, gl.FLOAT, false, 0, this.normalsOffset);\n      gl.vertexAttribPointer(attribs['a_uv'], 2, gl.FLOAT, false, 0, this.uvsOffset);\n\n      // Faces.\n      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.faceBuffer);\n    }\n\n    // Draw.\n    instancedArrays.drawElementsInstancedANGLE(gl.TRIANGLES, this.elements, gl.UNSIGNED_SHORT, 0, this.instances);\n\n    if (vertexArrayObject) {\n      vertexArrayObject.bindVertexArrayOES(null);\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/unit.ts",
    "content": "import { vec3, quat } from 'gl-matrix';\nimport { VEC3_UNIT_Z } from '../../../common/gl-matrix-addon';\nimport { MappedDataRow } from '../../../utils/mappeddata';\nimport DooUnit from '../../../parsers/w3x/unitsdoo/unit';\nimport MdxModel from '../mdx/model';\nimport War3MapViewerMap from './map';\nimport { Widget } from './widget';\n\nconst heapZ = vec3.create();\n\n/**\n * A unit.\n */\nexport default class Unit extends Widget {\n  /**\n   * StartLocation.mdx (and others?) seems to be built-in, and has no row.\n   */\n  row: MappedDataRow | undefined;\n\n  constructor(map: War3MapViewerMap, model: MdxModel, row: MappedDataRow | undefined, unit: DooUnit) {\n    super(map, model);\n\n    const instance = this.instance;\n\n    instance.move(<vec3>unit.location);\n    instance.rotateLocal(quat.setAxisAngle(quat.create(), VEC3_UNIT_Z, unit.angle));\n    instance.scale(<vec3>unit.scale);\n    instance.setTeamColor(unit.player);\n    instance.setScene(map.worldScene);\n\n    if (row) {\n      heapZ[2] = row.number('moveHeight');\n\n      instance.move(heapZ);\n      instance.setVertexColor([row.number('red') / 255, row.number('green') / 255, row.number('blue') / 255, 1]);\n      instance.uniformScale(row.number('modelScale'));\n    }\n\n    this.instance = instance;\n    this.row = row;\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/variations.ts",
    "content": "const cliffVariations = {\n  AAAB: 1,\n  AAAC: 1,\n  AABA: 1,\n  AABB: 2,\n  AABC: 0,\n  AACA: 1,\n  AACB: 0,\n  AACC: 1,\n  ABAA: 1,\n  ABAB: 1,\n  ABAC: 0,\n  ABBA: 2,\n  ABBB: 1,\n  ABBC: 0,\n  ABCA: 0,\n  ABCB: 0,\n  ABCC: 0,\n  ACAA: 1,\n  ACAB: 0,\n  ACAC: 1,\n  ACBA: 0,\n  ACBB: 0,\n  ACBC: 0,\n  ACCA: 1,\n  ACCB: 0,\n  ACCC: 1,\n  BAAA: 1,\n  BAAB: 1,\n  BAAC: 0,\n  BABA: 1,\n  BABB: 1,\n  BABC: 0,\n  BACA: 0,\n  BACB: 0,\n  BACC: 0,\n  BBAA: 1,\n  BBAB: 1,\n  BBAC: 0,\n  BBBA: 1,\n  BBCA: 0,\n  BCAA: 0,\n  BCAB: 0,\n  BCAC: 0,\n  BCBA: 0,\n  BCCA: 0,\n  CAAA: 1,\n  CAAB: 0,\n  CAAC: 1,\n  CABA: 0,\n  CABB: 0,\n  CABC: 0,\n  CACA: 1,\n  CACB: 0,\n  CACC: 1,\n  CBAA: 0,\n  CBAB: 0,\n  CBAC: 0,\n  CBBA: 0,\n  CBCA: 0,\n  CCAA: 1,\n  CCAB: 0,\n  CCAC: 1,\n  CCBA: 0,\n  CCCA: 1,\n};\n\nconst cityCliffVariations = {\n  AAAB: 2,\n  AAAC: 1,\n  AABA: 1,\n  AABB: 3,\n  AABC: 0,\n  AACA: 1,\n  AACB: 0,\n  AACC: 3,\n  ABAA: 1,\n  ABAB: 2,\n  ABAC: 0,\n  ABBA: 3,\n  ABBB: 0,\n  ABBC: 0,\n  ABCA: 0,\n  ABCB: 0,\n  ABCC: 0,\n  ACAA: 1,\n  ACAB: 0,\n  ACAC: 2,\n  ACBA: 0,\n  ACBB: 0,\n  ACBC: 0,\n  ACCA: 3,\n  ACCB: 0,\n  ACCC: 1,\n  BAAA: 1,\n  BAAB: 3,\n  BAAC: 0,\n  BABA: 2,\n  BABB: 0,\n  BABC: 0,\n  BACA: 0,\n  BACB: 0,\n  BACC: 0,\n  BBAA: 3,\n  BBAB: 1,\n  BBAC: 0,\n  BBBA: 1,\n  BBCA: 0,\n  BCAA: 0,\n  BCAB: 0,\n  BCAC: 0,\n  BCBA: 0,\n  BCCA: 0,\n  CAAA: 1,\n  CAAB: 0,\n  CAAC: 3,\n  CABA: 0,\n  CABB: 0,\n  CABC: 0,\n  CACA: 2,\n  CACB: 0,\n  CACC: 1,\n  CBAA: 0,\n  CBAB: 0,\n  CBAC: 0,\n  CBBA: 0,\n  CBCA: 0,\n  CCAA: 3,\n  CCAB: 0,\n  CCAC: 1,\n  CCBA: 0,\n  CCCA: 1,\n};\n\nexport default function getCliffVariation(dir: string, tag: string, variation: number): number {\n  if (dir === 'Cliffs') {\n    return Math.min(variation, cliffVariations[tag]);\n  } else {\n    return Math.min(variation, cityCliffVariations[tag]);\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/viewer.ts",
    "content": "import { FetchDataTypeName } from '../../../common/fetchdatatype';\nimport { MappedData } from '../../../utils/mappeddata';\nimport ModelViewer from '../../viewer';\nimport Shader from '../../gl/shader';\nimport { PathSolver } from '../../handlerresource';\nimport mdxHandler from '../mdx/handler';\nimport blpHandler from '../blp/handler';\nimport tgaHandler from '../tga/handler';\nimport ddsHandler from '../dds/handler';\nimport groundVert from './shaders/ground.vert';\nimport groundFrag from './shaders/ground.frag';\nimport waterVert from './shaders/water.vert';\nimport waterFrag from './shaders/water.frag';\nimport cliffsVert from './shaders/cliffs.vert';\nimport cliffsFrag from './shaders/cliffs.frag';\nimport War3MapViewerMap from './map';\nimport GenericResource from '../../genericresource';\n\nexport default class War3MapViewer extends ModelViewer {\n  wc3PathSolver: PathSolver;\n  isReforged: boolean;\n  groundShader: Shader;\n  waterShader: Shader;\n  cliffShader: Shader;\n  terrainData = new MappedData();\n  cliffTypesData = new MappedData();\n  waterData = new MappedData();\n  doodadsData = new MappedData();\n  doodadMetaData = new MappedData();\n  destructableMetaData = new MappedData();\n  unitsData = new MappedData();\n  unitMetaData = new MappedData();\n  loadedBaseFiles = false;\n  map: War3MapViewerMap | null = null;\n\n  constructor(canvas: HTMLCanvasElement, wc3PathSolver: PathSolver, isReforged: boolean) {\n    super(canvas);\n\n    const webgl = this.webgl;\n\n    // Data textures.\n    if (!webgl.ensureExtension('OES_texture_float')) {\n      throw new Error('War3MapViewer: No float texture support!');\n    }\n\n    // Optionally used for cliff renering.\n    if (!webgl.ensureExtension('OES_vertex_array_object')) {\n      console.warn('War3MapViewer: No vertex array object support! This might reduce performance.');\n    }\n\n    this.on('error', (e) => console.log(e));\n\n    this.addHandler(mdxHandler, wc3PathSolver, isReforged);\n    this.addHandler(blpHandler);\n    this.addHandler(tgaHandler);\n    this.addHandler(ddsHandler);\n\n    this.wc3PathSolver = wc3PathSolver;\n    this.isReforged = isReforged;\n\n    this.groundShader = this.webgl.createShader(groundVert, groundFrag);\n    this.waterShader = this.webgl.createShader(waterVert, waterFrag);\n    this.cliffShader = this.webgl.createShader(cliffsVert, cliffsFrag);\n\n    this.loadBaseFiles();\n  }\n\n  async loadBaseFiles(): Promise<void> {\n    const promises = [\n      this.loadBaseFile('TerrainArt\\\\Terrain.slk', 'text'),\n      this.loadBaseFile('TerrainArt\\\\CliffTypes.slk', 'text'),\n      this.loadBaseFile('TerrainArt\\\\Water.slk', 'text'),\n      this.loadBaseFile('Doodads\\\\Doodads.slk', 'text'),\n      this.loadBaseFile('Doodads\\\\DoodadMetaData.slk', 'text'),\n      this.loadBaseFile('Units\\\\DestructableData.slk', 'text'),\n      this.loadBaseFile('Units\\\\DestructableMetaData.slk', 'text'),\n      this.loadBaseFile('Units\\\\UnitData.slk', 'text'),\n      this.loadBaseFile('Units\\\\unitUI.slk', 'text'),\n      this.loadBaseFile('Units\\\\ItemData.slk', 'text'),\n      this.loadBaseFile('Units\\\\UnitMetaData.slk', 'text'),\n    ];\n\n    let reforgedPromises;\n\n    if (this.isReforged) {\n      reforgedPromises = [\n        this.loadBaseFile('Doodads\\\\doodadSkins.txt', 'text'),\n        this.loadBaseFile('Units\\\\destructableSkin.txt', 'text'),\n        this.loadBaseFile('Units\\\\unitSkin.txt', 'text'),\n        this.loadBaseFile('Units\\\\itemSkin.txt', 'text'),\n      ];\n    }\n\n    const [terrain, cliffTypes, water, doodads, doodadMetaData, destructableData, destructableMetaData, unitData, unitUi, itemData, unitMetaData] = await Promise.all(promises);\n\n    if (!terrain || !cliffTypes || !water || !doodads || !doodadMetaData || !destructableData || !destructableMetaData || !unitData || !unitUi || !itemData || !unitMetaData) {\n      throw new Error('Failed to load the base files');\n    }\n\n    this.terrainData.load(<string>terrain.data);\n    this.cliffTypesData.load(<string>cliffTypes.data);\n    this.waterData.load(<string>water.data);\n    this.doodadsData.load(<string>doodads.data);\n    this.doodadMetaData.load(<string>doodadMetaData.data);\n    this.doodadsData.load(<string>destructableData.data);\n    this.destructableMetaData.load(<string>destructableMetaData.data);\n    this.unitsData.load(<string>unitData.data);\n    this.unitsData.load(<string>unitUi.data);\n    this.unitsData.load(<string>itemData.data);\n    this.unitMetaData.load(<string>unitMetaData.data);\n\n    if (reforgedPromises) {\n      const [doodadSkins, destructableSkin, unitSkin, itemSkin] = await Promise.all(reforgedPromises);\n\n      if (!doodadSkins || !destructableSkin || !unitSkin || !itemSkin) {\n        throw new Error('Failed to load the base Reforged files');\n      }\n\n      this.doodadsData.load(<string>doodadSkins.data);\n      this.doodadsData.load(<string>destructableSkin.data);\n      this.unitsData.load(<string>unitSkin.data);\n      this.unitsData.load(<string>itemSkin.data);\n    }\n\n    this.loadedBaseFiles = true;\n    this.emit('loadedbasefiles');\n  }\n\n  loadBaseFile(path: string, dataType: FetchDataTypeName): Promise<GenericResource | undefined> {\n    return super.loadGeneric(<string>this.wc3PathSolver(path), dataType);\n  }\n\n  /**\n   * Load a map from a buffer.\n   */\n  loadMap(buffer: ArrayBuffer | Uint8Array): void {\n    if (this.loadedBaseFiles) {\n      if (this.map) {\n        this.map.die();\n      }\n\n      this.map = new War3MapViewerMap(this, buffer);\n    }\n  }\n\n  /**\n   * Update the map.\n   */\n  override update(): void {\n    if (this.map) {\n      super.update();\n\n      this.map.update();\n    }\n  }\n\n  /**\n   * Render the map.\n   */\n  override render(): void {\n    if (this.map) {\n      this.map.render();\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/handlers/w3x/widget.ts",
    "content": "import MdxModel from '../mdx/model';\nimport MdxModelInstance from '../mdx/modelinstance';\nimport War3MapViewerMap from './map';\nimport randomStandSequence from './standsequence';\n\nexport enum WidgetState {\n  IDLE,\n  WALK,\n}\n\n/**\n * A widget.\n */\nexport class Widget {\n  instance: MdxModelInstance;\n  state = WidgetState.IDLE;\n\n  constructor(map: War3MapViewerMap, model: MdxModel) {\n    this.instance = model.addInstance();\n\n    this.instance.setScene(map.worldScene);\n  }\n\n  update(): void {\n    if (this.instance.sequenceEnded || this.instance.sequence === -1) {\n      if (this.state === WidgetState.IDLE) {\n        randomStandSequence(this.instance);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/imagetexture.ts",
    "content": "import { isPowerOfTwo } from '../common/math';\nimport { isGif, isJpeg, isPng, isWebP } from '../common/isformat';\nimport Texture from './texture';\nimport { HandlerResourceData } from './handlerresource';\n\n/**\n * Checks if the given source is a supported image texture source.\n */\nexport function isImageSource(src: unknown): boolean {\n  return src instanceof ImageData || src instanceof HTMLImageElement || src instanceof HTMLCanvasElement || src instanceof HTMLVideoElement;\n}\n\n/**\n * Detects whether the given buffer is a supported format, and if so returns the mime.\n * The supported formats are PNG, JPEG, GIF, and WebP.\n */\nexport function detectMime(buffer: Uint8Array): string {\n  if (isPng(buffer)) {\n    return 'image/png';\n  }\n\n  if (isJpeg(buffer)) {\n    return 'image/jpeg';\n  }\n\n  if (isGif(buffer)) {\n    return 'image/gif';\n  }\n\n  if (isWebP(buffer)) {\n    return 'image/webp';\n  }\n\n  return '';\n}\n\n/**\n * A texture handler for image sources.\n */\nexport class ImageTexture extends Texture {\n  constructor(src: TexImageSource, resourceData: HandlerResourceData) {\n    super(resourceData);\n\n    const gl = this.viewer.gl;\n\n    this.webglResource = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, this.webglResource);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n    if (isPowerOfTwo(src.width) && isPowerOfTwo(src.height)) {\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);\n      gl.generateMipmap(gl.TEXTURE_2D);\n    } else {\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n      // Required for NPOT textures.\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    }\n\n    this.width = src.width;\n    this.height = src.height;\n  }\n}\n"
  },
  {
    "path": "src/viewer/index.ts",
    "content": "import ModelViewer, { DebugRenderMode } from './viewer';\nimport Scene from './scene';\nimport Camera from './camera';\nimport { Node } from './node';\nimport Model from './model';\nimport ModelInstance from './modelinstance';\nimport Texture from './texture';\nimport GenericResource from './genericresource';\nimport gl from './gl';\nimport handlers from './handlers';\n\nexport default {\n  ModelViewer,\n  DebugRenderMode,\n  Scene,\n  Camera,\n  Node,\n  Model,\n  ModelInstance,\n  Texture,\n  GenericResource,\n  gl,\n  handlers,\n};\n"
  },
  {
    "path": "src/viewer/model.ts",
    "content": "import { HandlerResource } from './handlerresource';\nimport Bounds from './bounds';\nimport ModelInstance from './modelinstance';\n\n/**\n * A model.\n */\nexport default abstract class Model extends HandlerResource {\n  bounds = new Bounds();\n\n  /**\n   * Create a new instance and return it.\n   */\n  abstract addInstance(): ModelInstance;\n}\n"
  },
  {
    "path": "src/viewer/modelinstance.ts",
    "content": "import { testSphere, distanceToPlane3 } from '../common/gl-matrix-addon';\nimport { Node } from './node';\nimport Model from './model';\nimport Scene from './scene';\nimport Camera from './camera';\nimport Texture from './texture';\nimport Bounds from './bounds';\n\n/**\n * A model instance.\n */\nexport default abstract class ModelInstance extends Node {\n  scene: Scene | null = null;\n  left = -1;\n  right = -1;\n  bottom = -1;\n  top = -1;\n  plane = -1;\n  depth = 0;\n  updateFrame = 0;\n  model: Model;\n  /**\n   * Allows to slow down or speed up animations of this instance, and any children.\n   */\n  timeScale = 1;\n  /**\n   * If false, this instance won't be rendered.\n   * \n   * When working with Warcraft 3 instances, it is preferable to use hide() and show().\n   * These hide and show also internal instances of this instance.\n   */\n  rendered = true;\n  textureOverrides: Map<number, Texture> = new Map();\n\n  constructor(model: Model) {\n    super();\n\n    this.model = model;\n  }\n\n  /**\n   * This instance should be shown.\n   */\n  show(): void {\n    this.rendered = true;\n  }\n\n  /**\n   * This instance should be hidden.\n   */\n  hide(): void {\n    this.rendered = false;\n  }\n\n  /**\n   * Should the instance be shown?\n   */\n  shown(): boolean {\n    return this.rendered;\n  }\n\n  /**\n   * Should the instance be hidden?\n   */\n  hidden(): boolean {\n    return !this.rendered;\n  }\n\n  /**\n   * Detach this instance from the scene it's in.\n   * \n   * Equivalent to scene.removeInstance(instance).\n   */\n  detach(): boolean {\n    if (this.scene) {\n      return this.scene.removeInstance(this);\n    }\n\n    return false;\n  }\n\n  overrideTexture(index: number, texture?: Texture): void {\n    if (texture) {\n      this.textureOverrides.set(index, texture);\n    } else {\n      this.textureOverrides.delete(index);\n    }\n  }\n\n  /**\n   * Called for instance culling.\n   */\n  getBounds(): Bounds {\n    return this.model.bounds;\n  }\n\n  /**\n   * Clears any objects that were emitted by this instance.\n   */\n  clearEmittedObjects(): void {\n\n  }\n\n  /**\n   * Sets the scene of this instance.\n   * \n   * This is equivalent to scene.addInstance(instance).\n   */\n  setScene(scene: Scene): boolean {\n    return scene.addInstance(this);\n  }\n\n  override recalculateTransformation(): void {\n    super.recalculateTransformation();\n\n    if (this.scene) {\n      this.scene.grid.moved(this);\n    }\n  }\n\n  override update(dt: number): void {\n    const scene = this.scene;\n\n    if (scene && this.rendered && this.isVisible(scene.camera)) {\n      // Add this instance to the render list.\n      scene.renderInstance(this);\n\n      // Update this instance.\n      this.updateAnimations(dt * this.timeScale);\n\n      // Update child nodes if there are any, such as instances parented to instances.\n      super.update(dt);\n    }\n  }\n\n  updateAnimations(_dt: number): void {\n\n  }\n\n  renderOpaque(): void {\n\n  }\n\n  renderTranslucent(): void {\n\n  }\n\n  isVisible(camera: Camera): boolean {\n    const [x, y, z] = this.worldLocation;\n    const [sx, sy, sz] = this.worldScale;\n    const bounds = this.getBounds();\n    const planes = camera.planes;\n    let biggest = sx;\n\n    // Get the biggest scaling dimension.\n    if (sy > biggest) {\n      biggest = sy;\n    }\n\n    if (sz > biggest) {\n      biggest = sz;\n    }\n\n    this.plane = testSphere(planes, x + bounds.x, y + bounds.y, z + bounds.z, bounds.r * biggest, this.plane);\n\n    if (this.plane === -1) {\n      this.depth = distanceToPlane3(planes[4], x, y, z);\n\n      return true;\n    }\n\n    return false;\n  }\n}\n"
  },
  {
    "path": "src/viewer/node.ts",
    "content": "import { vec3, quat, mat4 } from 'gl-matrix';\nimport { VEC3_ZERO, VEC3_ONE, QUAT_DEFAULT, quatLookAt } from '../common/gl-matrix-addon';\nimport { SkeletalNode } from './skeletalnode';\n\nconst locationHeap = vec3.create();\nconst rotationHeap = quat.create();\nconst scalingHeap = vec3.create();\n\n/**\n * A node.\n */\nexport class Node {\n  pivot = vec3.create();\n  localLocation = vec3.create();\n  localRotation = quat.create();\n  localScale = vec3.fromValues(1, 1, 1);\n  worldLocation = vec3.create();\n  worldRotation = quat.create();\n  worldScale = vec3.fromValues(1, 1, 1);\n  inverseWorldLocation = vec3.create();\n  inverseWorldRotation = quat.create();\n  inverseWorldScale = vec3.fromValues(1, 1, 1);\n  localMatrix = mat4.create();\n  worldMatrix = mat4.create();\n  dontInheritTranslation = false;\n  dontInheritRotation = false;\n  dontInheritScaling = true;\n  parent: Node | SkeletalNode | null = null;\n  children: Node[] = [];\n\n  /**\n   * Sets the node's pivot.\n   */\n  setPivot(pivot: vec3): this {\n    vec3.copy(this.pivot, pivot);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Sets the node's local location.\n   */\n  setLocation(location: vec3): this {\n    vec3.copy(this.localLocation, location);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Sets the node's local rotation.\n   */\n  setRotation(rotation: quat): this {\n    quat.copy(this.localRotation, rotation);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Sets the node's local scale.\n   */\n  setScale(varying: vec3): this {\n    vec3.copy(this.localScale, varying);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Sets the node's local scale uniformly.\n   */\n  setUniformScale(uniform: number): this {\n    vec3.set(this.localScale, uniform, uniform, uniform);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Sets the node's local location, rotation, and scale.\n   */\n  setTransformation(location: vec3, rotation: quat, scale: vec3): this {\n    const localLocation = this.localLocation;\n    const localRotation = this.localRotation;\n    const localScale = this.localScale;\n\n    localLocation[0] = location[0];\n    localLocation[1] = location[1];\n    localLocation[2] = location[2];\n    // vec3.copy(this.localLocation, location);\n\n    localRotation[0] = rotation[0];\n    localRotation[1] = rotation[1];\n    localRotation[2] = rotation[2];\n    localRotation[3] = rotation[3];\n    // quat.copy(this.localRotation, rotation);\n\n    localScale[0] = scale[0];\n    localScale[1] = scale[1];\n    localScale[2] = scale[2];\n    // vec3.copy(this.localScale, scale);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Resets the node's local location, pivot, rotation, and scale, to the default values.\n   */\n  resetTransformation(): this {\n    vec3.copy(this.pivot, VEC3_ZERO);\n    vec3.copy(this.localLocation, VEC3_ZERO);\n    quat.copy(this.localRotation, QUAT_DEFAULT);\n    vec3.copy(this.localScale, VEC3_ONE);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Moves the node's pivot.\n   */\n  movePivot(offset: vec3): this {\n    vec3.add(this.pivot, this.pivot, offset);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Moves the node's local location.\n   */\n  move(offset: vec3): this {\n    vec3.add(this.localLocation, this.localLocation, offset);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Rotates the node's local rotation in world space.\n   */\n  rotate(rotation: quat): this {\n    quat.mul(this.localRotation, this.localRotation, rotation);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Rotates the node's local rotation in local space.\n   */\n  rotateLocal(rotation: quat): this {\n    quat.mul(this.localRotation, rotation, this.localRotation);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Scales the node.\n   */\n  scale(scale: vec3): this {\n    vec3.mul(this.localScale, this.localScale, scale);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Scales the node uniformly.\n   */\n  uniformScale(scale: number): this {\n    vec3.scale(this.localScale, this.localScale, scale);\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  face(to: vec3, worldUp: vec3): this {\n    quat.conjugate(this.localRotation, quatLookAt(this.localRotation, this.localLocation, to, worldUp));\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Sets the node's parent.\n   */\n  setParent(parent?: Node | SkeletalNode): this {\n    // If the node already had a parent, detach from it first.\n    if (this.parent) {\n      const children = this.parent.children;\n      const index = children.indexOf(this);\n\n      if (index !== -1) {\n        children.splice(index, 1);\n      }\n    }\n\n    this.parent = parent || null;\n\n    // If the new parent is an actual thing, add this node as a child.\n    if (parent) {\n      parent.children.push(this);\n    }\n\n    this.recalculateTransformation();\n\n    return this;\n  }\n\n  /**\n   * Recalculate this node's transformation data.\n   */\n  recalculateTransformation(): void {\n    const parent = this.parent;\n    const localMatrix = this.localMatrix;\n    const localLocation = this.localLocation;\n    const localRotation = this.localRotation;\n    const localScale = this.localScale;\n    const worldMatrix = this.worldMatrix;\n    const worldLocation = this.worldLocation;\n    const worldRotation = this.worldRotation;\n    const worldScale = this.worldScale;\n    const inverseWorldLocation = this.inverseWorldLocation;\n    const inverseWorldRotation = this.inverseWorldRotation;\n    const inverseWorldScale = this.inverseWorldScale;\n\n    if (parent) {\n      const computedLocation = locationHeap;\n      const parentPivot = parent.pivot;\n      let computedRotation;\n      let computedScaling;\n      \n      computedLocation[0] = localLocation[0] + parentPivot[0];\n      computedLocation[1] = localLocation[1] + parentPivot[1];\n      computedLocation[2] = localLocation[2] + parentPivot[2];\n      // vec3.add(computedLocation, localLocation, parentPivot);\n\n      // If this node shouldn't inherit the parent's rotation, rotate it by the inverse.\n      if (this.dontInheritRotation) {\n        computedRotation = rotationHeap;\n\n        quat.mul(computedRotation, localRotation, parent.inverseWorldRotation);\n      } else {\n        computedRotation = localRotation;\n      }\n\n      // If this node shouldn't inherit the parent's translation, translate it by the inverse.\n      // if (this.dontInheritTranslation) {\n      // mat4.translate(worldMatrix, worldMatrix, parent.inverseWorldLocation);\n      // }\n\n      if (this.dontInheritScaling) {\n        computedScaling = scalingHeap;\n\n        const parentInverseScale = parent.inverseWorldScale;\n        computedScaling[0] = parentInverseScale[0] * localScale[0];\n        computedScaling[1] = parentInverseScale[1] * localScale[1];\n        computedScaling[2] = parentInverseScale[2] * localScale[2];\n        // vec3.mul(computedScaling, parent.inverseWorldScale, localScale);\n\n        worldScale[0] = localScale[0];\n        worldScale[1] = localScale[1];\n        worldScale[2] = localScale[2];\n        // vec3.copy(worldScale, localScale);\n      } else {\n        computedScaling = localScale;\n\n        const parentScale = parent.worldScale;\n        worldScale[0] = parentScale[0] * localScale[0];\n        worldScale[1] = parentScale[1] * localScale[1];\n        worldScale[2] = parentScale[2] * localScale[2];\n        // vec3.mul(worldScale, parentScale, localScale);\n      }\n\n      mat4.fromRotationTranslationScale(localMatrix, computedRotation, computedLocation, computedScaling);\n\n      mat4.mul(worldMatrix, parent.worldMatrix, localMatrix);\n\n      quat.mul(worldRotation, parent.worldRotation, computedRotation);\n    } else {\n      // Local matrix\n      mat4.fromRotationTranslationScale(localMatrix, localRotation, localLocation, localScale);\n\n      // World matrix\n      worldMatrix[0] = localMatrix[0];\n      worldMatrix[1] = localMatrix[1];\n      worldMatrix[2] = localMatrix[2];\n      worldMatrix[3] = localMatrix[3];\n      worldMatrix[4] = localMatrix[4];\n      worldMatrix[5] = localMatrix[5];\n      worldMatrix[6] = localMatrix[6];\n      worldMatrix[7] = localMatrix[7];\n      worldMatrix[8] = localMatrix[8];\n      worldMatrix[9] = localMatrix[9];\n      worldMatrix[10] = localMatrix[10];\n      worldMatrix[11] = localMatrix[11];\n      worldMatrix[12] = localMatrix[12];\n      worldMatrix[13] = localMatrix[13];\n      worldMatrix[14] = localMatrix[14];\n      worldMatrix[15] = localMatrix[15];\n      // mat4.copy(worldMatrix, localMatrix);\n\n      // World rotation\n      worldRotation[0] = localRotation[0];\n      worldRotation[1] = localRotation[1];\n      worldRotation[2] = localRotation[2];\n      worldRotation[3] = localRotation[3];\n      // quat.copy(worldRotation, localRotation);\n\n      // World scale\n      worldScale[0] = localScale[0];\n      worldScale[1] = localScale[1];\n      worldScale[2] = localScale[2];\n      // vec3.copy(worldScale, localScale);\n    }\n\n    // Inverse world rotation\n    inverseWorldRotation[0] = -worldRotation[0];\n    inverseWorldRotation[1] = -worldRotation[1];\n    inverseWorldRotation[2] = -worldRotation[2];\n    inverseWorldRotation[3] = worldRotation[3];\n    // quat.conjugate(inverseWorldRotation, worldRotation);\n\n    // Inverse world scale\n    inverseWorldScale[0] = 1 / worldScale[0];\n    inverseWorldScale[1] = 1 / worldScale[1];\n    inverseWorldScale[2] = 1 / worldScale[2];\n    // vec3.inverse(this.inverseWorldScale, worldScale);\n\n    // World location\n    worldLocation[0] = worldMatrix[12];\n    worldLocation[1] = worldMatrix[13];\n    worldLocation[2] = worldMatrix[14];\n\n    // Inverse world location\n    inverseWorldLocation[0] = -worldLocation[0];\n    inverseWorldLocation[1] = -worldLocation[1];\n    inverseWorldLocation[2] = -worldLocation[2];\n    // vec3.negate(this.inverseWorldLocation, worldLocation);\n\n    for (const child of this.children) {\n      child.recalculateTransformation();\n    }\n  }\n\n  /**\n   * Update this node, and continue down the node hierarchy.\n   */\n  update(dt: number): void {\n    for (const child of this.children) {\n      child.update(dt);\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/resource.ts",
    "content": "import ModelViewer from './viewer';\n\n/**\n * The data sent to every resource as a part of the loading process.\n */\nexport type ResourceData = { viewer: ModelViewer, fetchUrl: string };\n\n/**\n * A viewer resource.\n * \n * Generally speaking resources are created via viewer.load(), or viewer.loadGeneric().\n */\nexport abstract class Resource {\n  viewer: ModelViewer;\n  fetchUrl: string;\n  blockers: Promise<Resource | undefined>[] = [];\n\n  constructor(resourceData: ResourceData) {\n    this.viewer = resourceData.viewer;\n    this.fetchUrl = resourceData.fetchUrl;\n  }\n\n  /**\n   * Remove this resource from its viewer's cache.\n   * \n   * Equivalent to viewer.unload(resource).\n   */\n  detach(): boolean {\n    return this.viewer.unload(this);\n  }\n}\n"
  },
  {
    "path": "src/viewer/scene.ts",
    "content": "import { vec3, vec4 } from 'gl-matrix';\nimport ModelViewer from './viewer';\nimport Camera from './camera';\nimport Grid from './grid';\nimport ModelInstance from './modelinstance';\nimport EmittedObjectUpdater from './emittedobjectupdater';\n\n/**\n * A scene.\n *\n * Every scene has its own list of model instances, and its own camera and viewport.\n *\n * In addition, every scene may have its own AudioContext if enableAudio() is called.\n * If audio is enabled, the AudioContext's listener's location will be updated automatically.\n * Note that due to browser policies, this may be done only after user interaction with the web page.\n */\nexport default class Scene {\n  viewer: ModelViewer;\n  camera = new Camera();\n  grid = new Grid(-100000, -100000, 200000, 200000, 200000, 200000);\n  visibleCells = 0;\n  visibleInstances = 0;\n  updatedParticles = 0;\n  audioEnabled = false;\n  audioContext: AudioContext | null = null;\n  instances: ModelInstance[] = [];\n  emittedObjectUpdater = new EmittedObjectUpdater();\n  /**\n   * Similar to WebGL's own `alpha` parameter.\n   * \n   * If false, the scene will be cleared before rendering, meaning that scenes behind it won't be visible through it.\n   * \n   * If true, alpha works as usual.\n   */\n  alpha = false;\n  /**\n   * The scene's background color.\n   * \n   * Only used if `alpha` is false.\n   */\n  color = vec3.create();\n  /**\n   * The area on the canvas in which this scene is rendered.\n   * \n   * Defaults to the entire canvas.\n   * \n   * The vector defines [x, y, width, height], sizes are in pixels, and everything is related to the bottom left corner of the canvas.\n   */\n  viewport = vec4.create();\n  /**\n   * The position of the light that is used when rendering.\n   * \n   * Affects HD MDX and M3 models.\n   */\n  lightPosition = vec3.fromValues(0, 0, 10000);\n\n  constructor(viewer: ModelViewer) {\n    this.viewer = viewer;\n\n    const canvas = viewer.canvas;\n    const width = canvas.width;\n    const height = canvas.height;\n\n    // Use the whole canvas by default.\n    this.viewport[2] = width;\n    this.viewport[3] = height;\n\n    // And standard perspective projection.\n    this.camera.perspective(Math.PI / 4, width / height, 8, 10000);\n  }\n\n  /**\n   * Creates an AudioContext if one wasn't created already, and resumes it if needed.\n   * \n   * The returned promise will resolve to whether it is actually running or not.\n   * \n   * It may stay in suspended state indefinitly until the user interacts with the page, due to browser policies.\n   */\n  async enableAudio(): Promise<boolean> {\n    if (typeof AudioContext === 'function') {\n      if (!this.audioContext) {\n        this.audioContext = new AudioContext();\n      }\n\n      if (this.audioContext.state !== 'suspended') {\n        await this.audioContext.resume();\n      }\n\n      this.audioEnabled = this.audioContext.state === 'running';\n\n      return this.audioEnabled;\n    }\n\n    return false;\n  }\n\n  /**\n   * Suspend the audio context.\n   */\n  disableAudio(): void {\n    if (this.audioContext) {\n      this.audioContext.suspend();\n    }\n\n    this.audioEnabled = false;\n  }\n\n  /**\n   * Sets the scene of the given instance.\n   * \n   * Equivalent to instance.setScene(scene).\n   */\n  addInstance(instance: ModelInstance): boolean {\n    if (instance.scene !== this) {\n      if (instance.scene) {\n        instance.scene.removeInstance(instance);\n      }\n\n      instance.scene = this;\n\n      this.grid.moved(instance);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Remove the given instance from this scene.\n   * \n   * Equivalent to ModelInstance.detach().\n   */\n  removeInstance(instance: ModelInstance): boolean {\n    if (instance.scene === this) {\n      this.grid.remove(instance);\n\n      instance.scene = null;\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Clear this scene.\n   */\n  clear(): void {\n    // First remove references to this scene stored in the instances.\n    for (const cell of this.grid.cells) {\n      for (const instance of cell.instances) {\n        instance.scene = null;\n      }\n    }\n\n    // Then remove references to the instances.\n    this.grid.clear();\n  }\n\n  /**\n   * Detach this scene from the viewer.\n   * \n   * Equivalent to viewer.removeScene(scene).\n   */\n  detach(): boolean {\n    if (this.viewer) {\n      return this.viewer.removeScene(this);\n    }\n\n    return false;\n  }\n\n  /**\n   * Update this scene.\n   */\n  update(dt: number): void {\n    const camera = this.camera;\n\n    // Update the audio context's position if it exists.\n    if (this.audioContext) {\n      const listener = this.audioContext.listener;\n      const position = camera.location;\n      const forward = camera.directionY;\n      const up = camera.directionZ;\n\n      listener.positionX.value = -position[0];\n      listener.positionY.value = -position[1];\n      listener.positionZ.value = -position[2];\n\n      listener.forwardX.value = forward[0];\n      listener.forwardY.value = forward[1];\n      listener.forwardZ.value = forward[2];\n\n      listener.upX.value = up[0];\n      listener.upY.value = up[1];\n      listener.upZ.value = up[2];\n    }\n\n    const frame = this.viewer.frame;\n    const instances = this.instances;\n\n    this.visibleCells = 0;\n    this.visibleInstances = 0;\n\n    // Update and collect all of the visible instances.\n    for (const cell of this.grid.cells) {\n      if (cell.isVisible(camera)) {\n        this.visibleCells += 1;\n\n        for (const instance of cell.instances) {\n          // If an instance is rendered, wasn't updated on this frame, and has no parent, update it.\n          // If the instance is visible, it will be updated, all of its children will be updated, and it will be added to the render list.\n          // Note that the update frame is needed because instances can exist in any number of cells at the same time.\n          if (instance.rendered && instance.updateFrame < frame && !instance.parent) {\n            instance.updateFrame = frame;\n            instance.update(dt);\n          }\n        }\n      }\n    }\n\n    // Sort the visible instances based on depth.\n    instances.length = this.visibleInstances;\n    instances.sort((a, b) => a.depth - b.depth);\n\n    this.emittedObjectUpdater.update(dt);\n    this.updatedParticles = this.emittedObjectUpdater.alive;\n  }\n\n  renderInstance(instance: ModelInstance): void {\n    this.instances[this.visibleInstances++] = instance;\n  }\n\n  /**\n   * Use the scene's viewport.\n   * \n   * Should be called before `renderOpaque()` and `renderTranslucent()`.\n   * \n   * Called automatically by `render()`.\n   */\n  startFrame(): void {\n    const gl = this.viewer.gl;\n    const viewport = this.viewport;\n\n    // Set the viewport.\n    gl.viewport(viewport[0], viewport[1], viewport[2], viewport[3]);\n\n    // Allow to render only in the viewport.\n    gl.scissor(viewport[0], viewport[1], viewport[2], viewport[3]);\n\n    // If this scene doesn't want alpha, clear it.\n    if (!this.alpha) {\n      const color = this.color;\n\n      gl.depthMask(true);\n      gl.clearColor(color[0], color[1], color[2], 1);\n      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n    }\n  }\n\n  /**\n   * Render opaque things in this scene.\n   * \n   * They are rendered front to back.\n   */\n  renderOpaque(): void {\n    const instances = this.instances;\n\n    for (let i = 0, l = instances.length; i < l; i++) {\n      instances[i].renderOpaque();\n    }\n  }\n\n  /**\n   * Renders translucent things in this scene.\n   * \n   * They are rendered back to front.\n   */\n  renderTranslucent(): void {\n    const instances = this.instances;\n\n    for (let i = instances.length - 1; i >= 0; i--) {\n      instances[i].renderTranslucent();\n    }\n  }\n\n  /**\n   * Render this scene.\n   */\n  render(): void {\n    this.startFrame();\n    this.renderOpaque();\n    this.renderTranslucent();\n  }\n\n  /**\n   * Clear all of the emitted objects in this scene.\n   */\n  clearEmittedObjects(): void {\n    for (const object of this.emittedObjectUpdater.objects) {\n      object.health = 0;\n    }\n  }\n}\n"
  },
  {
    "path": "src/viewer/skeletalnode.ts",
    "content": "import { vec3, quat, mat4 } from 'gl-matrix';\nimport { VEC3_UNIT_X, VEC3_UNIT_Y, VEC3_UNIT_Z } from '../common/gl-matrix-addon';\nimport Scene from './scene';\nimport { Node } from './node';\nimport ModelInstance from './modelinstance';\n\nconst locationHeap = vec3.create();\nconst rotationHeap = quat.create();\nconst scalingHeap = vec3.create();\nconst cameraRayHeap = vec3.create();\nconst rotationHeap2 = quat.create();\n\n/**\n * A skeletal node used for skeletons.\n * \n * Expected to be created with createSkeletalNodes() below.\n */\nexport class SkeletalNode {\n  pivot: vec3;\n  localLocation: vec3;\n  localRotation: quat;\n  localScale: vec3;\n  worldLocation: vec3;\n  worldRotation: quat;\n  worldScale: vec3;\n  inverseWorldLocation: vec3;\n  inverseWorldRotation: quat;\n  inverseWorldScale: vec3;\n  localMatrix: mat4;\n  worldMatrix: mat4;\n  dontInheritTranslation = false;\n  dontInheritRotation = false;\n  dontInheritScaling = false;\n  billboarded = false;\n  billboardedX = false;\n  billboardedY = false;\n  billboardedZ = false;\n  dirty = true;\n  wasDirty = false;\n  parent: SkeletalNode | Node | null = null;\n  children: Node[] = [];\n  /**\n   * The object associated with this node, if there is any.\n   */\n  object: unknown = null;\n\n  constructor(pivot: vec3,\n    localLocation: vec3, localRotation: quat, localScale: vec3,\n    worldLocation: vec3, worldRotation: quat, worldScale: vec3,\n    inverseWorldLocation: vec3, inverseWorldRotation: quat, inverseWorldScale: vec3,\n    localMatrix: mat4, worldMatrix: mat4) {\n    this.pivot = pivot;\n    this.localLocation = localLocation;\n    this.localRotation = localRotation;\n    this.localScale = localScale;\n    this.worldLocation = worldLocation;\n    this.worldRotation = worldRotation;\n    this.worldScale = worldScale;\n    this.inverseWorldLocation = inverseWorldLocation;\n    this.inverseWorldRotation = inverseWorldRotation;\n    this.inverseWorldScale = inverseWorldScale;\n    this.localMatrix = localMatrix;\n    this.worldMatrix = worldMatrix;\n\n    this.localRotation[3] = 1;\n\n    this.localScale.fill(1);\n\n    this.localMatrix[0] = 1;\n    this.localMatrix[5] = 1;\n    this.localMatrix[10] = 1;\n    this.localMatrix[15] = 1;\n  }\n\n  /**\n   * Recalculate this skeletal node.\n   */\n  recalculateTransformation(instance: ModelInstance): void {\n    const scene = <Scene>instance.scene;\n    const localMatrix = this.localMatrix;\n    const localLocation = this.localLocation;\n    const localRotation = this.localRotation;\n    const localScale = this.localScale;\n    const worldMatrix = this.worldMatrix;\n    const worldLocation = this.worldLocation;\n    const worldRotation = this.worldRotation;\n    const worldScale = this.worldScale;\n    const pivot = this.pivot;\n    const inverseWorldLocation = this.inverseWorldLocation;\n    const inverseWorldRotation = this.inverseWorldRotation;\n    const inverseWorldScale = this.inverseWorldScale;\n    const parent = <SkeletalNode | Node>this.parent;\n    let computedLocation;\n    let computedRotation;\n    let computedScaling;\n\n    if (this.dontInheritTranslation) {\n      vec3.add(locationHeap, parent.inverseWorldLocation, worldLocation);\n\n      computedLocation = vec3.add(locationHeap, locationHeap, localLocation);\n    } else {\n      computedLocation = localLocation;\n    }\n\n    if (this.dontInheritScaling) {\n      vec3.mul(locationHeap, parent.inverseWorldScale, instance.worldScale);\n\n      computedScaling = vec3.mul(locationHeap, locationHeap, localScale);\n    } else {\n      computedScaling = localScale;\n    }\n\n    if (this.billboarded) {\n      computedRotation = rotationHeap;\n\n      quat.copy(computedRotation, parent.inverseWorldRotation);\n      quat.mul(computedRotation, computedRotation, scene.camera.inverseRotation);\n\n      this.convertBasis(computedRotation);\n\n      quat.mul(computedRotation, computedRotation, localRotation);\n    } else {\n      const { billboardedX, billboardedY, billboardedZ } = this;\n\n      if (billboardedX || billboardedY || billboardedZ) {\n        if (billboardedX) {\n          if (computedScaling === localScale) {\n            computedScaling = scalingHeap;\n            vec3.copy(computedScaling, localScale);\n          }\n\n          // (Original comment from Retera's Warsmash)\n          // It took me many hours to deduce from playing around that this negative one\n          // multiplier should be here. I suggest a lot of testing before you remove it.\n          computedScaling[2] *= -1;\n        }\n\n        // Inverse that local rotation\n        rotationHeap2[0] = -localRotation[0];\n        rotationHeap2[1] = -localRotation[1];\n        rotationHeap2[2] = -localRotation[2];\n\n        quat.mul(rotationHeap2, rotationHeap2, parent.inverseWorldRotation);\n\n        vec3.transformQuat(cameraRayHeap, scene.camera.billboardedVectors[6], rotationHeap2);\n\n        if (billboardedX) {\n          quat.setAxisAngle(rotationHeap2, VEC3_UNIT_X, Math.atan2(cameraRayHeap[2], cameraRayHeap[1]));\n        } else if (billboardedY) {\n          quat.setAxisAngle(rotationHeap2, VEC3_UNIT_Y, Math.atan2(-cameraRayHeap[2], cameraRayHeap[0]));\n        } else {\n          quat.setAxisAngle(rotationHeap2, VEC3_UNIT_Z, Math.atan2(cameraRayHeap[1], cameraRayHeap[0]));\n        }\n\n        computedRotation = rotationHeap;\n\n        quat.mul(computedRotation, localRotation, rotationHeap2);\n      } else {\n        computedRotation = localRotation;\n      }\n    }\n\n    if (this.dontInheritRotation) {\n      quat.mul(rotationHeap2, parent.inverseWorldRotation, instance.worldRotation);\n      computedRotation = quat.mul(rotationHeap, rotationHeap2, computedRotation);\n    }\n\n    // Local matrix\n    mat4.fromRotationTranslationScaleOrigin(localMatrix, computedRotation, computedLocation, computedScaling, pivot);\n\n    // World matrix\n    mat4.mul(worldMatrix, parent.worldMatrix, localMatrix);\n\n    // World location\n    // vec3.transformMat4(worldLocation, pivot, worldMatrix);\n    const x = pivot[0];\n    const y = pivot[1];\n    const z = pivot[2];\n    worldLocation[0] = worldMatrix[0] * x + worldMatrix[4] * y + worldMatrix[8] * z + worldMatrix[12];\n    worldLocation[1] = worldMatrix[1] * x + worldMatrix[5] * y + worldMatrix[9] * z + worldMatrix[13];\n    worldLocation[2] = worldMatrix[2] * x + worldMatrix[6] * y + worldMatrix[10] * z + worldMatrix[14];\n\n    // Inverse world location\n    inverseWorldLocation[0] = -worldLocation[0];\n    inverseWorldLocation[1] = -worldLocation[1];\n    inverseWorldLocation[2] = -worldLocation[2];\n\n    // World rotation\n    quat.mul(worldRotation, parent.worldRotation, computedRotation);\n\n    // Inverse world rotation\n    inverseWorldRotation[0] = -worldRotation[0];\n    inverseWorldRotation[1] = -worldRotation[1];\n    inverseWorldRotation[2] = -worldRotation[2];\n    inverseWorldRotation[3] = worldRotation[3];\n\n    // World scale\n    const parentScale = parent.worldScale;\n    worldScale[0] = parentScale[0] * computedScaling[0];\n    worldScale[1] = parentScale[1] * computedScaling[1];\n    worldScale[2] = parentScale[2] * computedScaling[2];\n      \n    // Inverse world scale\n    inverseWorldScale[0] = 1 / worldScale[0];\n    inverseWorldScale[1] = 1 / worldScale[1];\n    inverseWorldScale[2] = 1 / worldScale[2];\n  }\n\n  /**\n   * Allows inherited node classes to run extra transformations when billboarding.\n   * \n   * This is needed because the different model formats are in different vector spaces.\n   */\n  convertBasis(_rotation: quat): void {\n\n  }\n}\n\ninterface SkeletalNodesData {\n  data: Float32Array;\n  nodes: SkeletalNode[];\n  pivots: Float32Array;\n  localLocations: Float32Array;\n  localRotations: Float32Array;\n  localScales: Float32Array;\n  worldLocations: Float32Array;\n  worldRotations: Float32Array;\n  worldScales: Float32Array;\n  inverseWorldLocations: Float32Array;\n  invereseWorldRotations: Float32Array;\n  inverseWorldScales: Float32Array;\n  localMatrices: Float32Array;\n  worldMatrices: Float32Array;\n}\n\nconst NODE_SHARED_SIZE = 65;\n\n/**\n * Creates an array of skeletal nodes with shared memory.\n * \n * The returned object contains the node array itself, the backing buffer, and all of the different shared arrays.\n */\nexport function createSkeletalNodes(count: number, Node = SkeletalNode): SkeletalNodesData {\n  const data = new Float32Array(count * NODE_SHARED_SIZE);\n  const nodes = [];\n  let offset = 0;\n  const count3 = count * 3;\n  const count4 = count * 4;\n  const count16 = count * 16;\n\n  const pivots = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const localLocations = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const localRotations = data.subarray(offset, offset + count4);\n  offset += count4;\n\n  const localScales = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const worldLocations = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const worldRotations = data.subarray(offset, offset + count4);\n  offset += count4;\n\n  const worldScales = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const inverseWorldLocations = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const invereseWorldRotations = data.subarray(offset, offset + count4);\n  offset += count4;\n\n  const inverseWorldScales = data.subarray(offset, offset + count3);\n  offset += count3;\n\n  const localMatrices = data.subarray(offset, offset + count16);\n  offset += count16;\n\n  const worldMatrices = data.subarray(offset, offset + count16);\n\n  for (let i = 0; i < count; i++) {\n    const i3 = i * 3;\n    const i33 = i3 + 3;\n    const i4 = i * 4;\n    const i44 = i4 + 4;\n    const i16 = i * 16;\n    const i1616 = i16 + 16;\n\n    nodes[i] = new Node(\n      pivots.subarray(i3, i33),\n      localLocations.subarray(i3, i33),\n      localRotations.subarray(i4, i44),\n      localScales.subarray(i3, i33),\n      worldLocations.subarray(i3, i33),\n      worldRotations.subarray(i4, i44),\n      worldScales.subarray(i3, i33),\n      inverseWorldLocations.subarray(i3, i33),\n      invereseWorldRotations.subarray(i4, i44),\n      inverseWorldScales.subarray(i3, i33),\n      localMatrices.subarray(i16, i1616),\n      worldMatrices.subarray(i16, i1616),\n    );\n  }\n\n  return {\n    data,\n    nodes,\n    pivots,\n    localLocations,\n    localRotations,\n    localScales,\n    worldLocations,\n    worldRotations,\n    worldScales,\n    inverseWorldLocations,\n    invereseWorldRotations,\n    inverseWorldScales,\n    localMatrices,\n    worldMatrices,\n  };\n}\n"
  },
  {
    "path": "src/viewer/texture.ts",
    "content": "import { HandlerResource } from './handlerresource';\n\n/**\n * A texture.\n */\nexport default abstract class Texture extends HandlerResource {\n  webglResource: WebGLTexture | null = null;\n  width = 0;\n  height = 0;\n}\n"
  },
  {
    "path": "src/viewer/viewer.ts",
    "content": "import { EventEmitter } from 'events';\nimport { FetchDataTypeName, FetchDataType, FetchResult, fetchDataType } from '../common/fetchdatatype';\nimport WebGL from './gl/gl';\nimport Scene from './scene';\nimport { Resource } from './resource';\nimport { PathSolver, HandlerResourceData, HandlerResource, SolverParams } from './handlerresource';\nimport GenericResource from './genericresource';\nimport ClientBuffer from './gl/clientbuffer';\nimport { isImageSource, ImageTexture, detectMime } from './imagetexture';\nimport { blobToImage } from '../common/canvas';\n\nexport enum DebugRenderMode {\n  None,\n  Diffuse,\n  NormalMap,\n  Occlusion,\n  Roughness,\n  Metallic,\n  TCFactor,\n  Emissive,\n  TexCoords,\n  Normals,\n  Tangents,\n}\n\n/**\n * A viewer handler.\n */\nexport interface Handler {\n  load?: (viewer: ModelViewer, ...args: any[]) => void;\n  isValidSource: (src: unknown) => boolean;\n  resource: new (src: any, resourceData: HandlerResourceData) => HandlerResource\n}\n\n/**\n * A model viewer.\n */\nexport default class ModelViewer extends EventEmitter {\n  /**\n   * The viewer's canvas.\n   */\n  canvas: HTMLCanvasElement;\n  /**\n   * The viewer's WebGL context.\n   */\n  gl: WebGLRenderingContext;\n  /**\n   * A wrapper around the viewer's WebGL context with utility functions.\n   */\n  webgl: WebGL;\n  /**\n   * All of the loaded resources.\n   */\n  resources: Resource[] = [];\n  /**\n   * A map from urls to their resources.\n   * \n   * Only used by fetched resources.\n   */\n  resourceMap: Map<string, Resource> = new Map();\n  /**\n   * A map from urls to the promises that load them.\n   * \n   * Only used by fetched resources.\n   */\n  promiseMap: Map<string, Promise<Resource | undefined>> = new Map();\n  /**\n   * The viewer's handlers, added with `addHandler()`.\n   */\n  handlers: Set<Handler> = new Set();\n  /**\n   * The viewer's scenes, added with `addScene()`.\n   */\n  scenes: Scene[] = [];\n  /**\n   * The current frame.\n   */\n  frame = 0;\n  /**\n   * The number of visible cells on the current frame.\n   */\n  visibleCells = 0;\n  /**\n   * The number of visible instances on the current frame.\n   */\n  visibleInstances = 0;\n  /**\n   * The number of particles being updated on the current frame.\n   */\n  updatedParticles = 0;\n  /**\n   * A viewer-wide flag.\n   * \n   * If it is false, not only will audio not run, but in fact audio files won't even be fetched in the first place.\n   * \n   * If audio is desired, this should be set to true before loading models that use audio.\n   * \n   * Note that it is preferable to call enableAudio(), which checks for the existence of AudioContext.\n   */\n  audioEnabled = false;\n  /**\n   * A resizeable buffer that can be used by any part of the library.\n   * \n   * The data it contains is temporary, and can be overwritten at any time.\n   */\n  buffer: ClientBuffer;\n  /**\n   * A cache of arbitrary data, shared between all of the handlers.\n   */\n  sharedCache: Map<unknown, unknown> = new Map();\n  /**\n   * Debug rendering mode.\n   * \n   * How it affects the rendering ultimately depends on the handlers.\n   */\n  debugRenderMode = DebugRenderMode.None;\n\n  directLoadId = 0;\n\n  constructor(canvas: HTMLCanvasElement, options?: WebGLContextAttributes) {\n    super();\n\n    const webgl = new WebGL(canvas, options);\n    const gl = webgl.gl;\n\n    this.canvas = canvas;\n    this.gl = gl;\n    this.webgl = webgl;\n    this.buffer = webgl.createClientBuffer();\n\n    // The only initial setup, the rest should be handled by the handlers.\n    gl.depthFunc(gl.LEQUAL);\n    gl.enable(gl.DEPTH_TEST);\n    gl.enable(gl.SCISSOR_TEST);\n  }\n\n  /**\n   * Enable audio if AudioContext is available.\n   */\n  enableAudio(): boolean {\n    if (typeof AudioContext === 'function') {\n      this.audioEnabled = true;\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Add an handler.\n   */\n  addHandler(handler: Handler, ...args: unknown[]): boolean {\n    if (handler) {\n      const handlers = this.handlers;\n\n      // Check to see if this handler was added already.\n      if (!handlers.has(handler)) {\n        if (!handler.isValidSource) {\n          this.emit('error', { viewer: this, error: 'Handler missing the isValidSource function', handler });\n          return false;\n        }\n\n        // Check if the handler has a loader, and if so load it.\n        if (handler.load) {\n          try {\n            handler.load(this, ...args);\n          } catch (e) {\n            this.emit('error', { viewer: this, error: `Handler failed to load`, handler, reason: e });\n\n            return false;\n          }\n        }\n\n        handlers.add(handler);\n\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Add a scene.\n   */\n  addScene(): Scene {\n    const scene = new Scene(this);\n\n    this.scenes.push(scene);\n\n    return scene;\n  }\n\n  /**\n   * Remove a scene.\n   */\n  removeScene(scene: Scene): boolean {\n    const scenes = this.scenes;\n    const index = scenes.indexOf(scene);\n\n    if (index !== -1) {\n      scenes.splice(index, 1);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Removes all of the scenes in the viewer.\n   */\n  clear(): void {\n    this.scenes.length = 0;\n  }\n\n  /**\n   * Given a source and an optional path solver, loads a resource and returns a promise to it.\n   */\n  async load(src: unknown, pathSolver?: PathSolver, solverParams?: SolverParams): Promise<Resource | undefined> {\n    let finalSrc: unknown;\n    let fetchUrl = '';\n    let promise;\n\n    // Run the path solver if there is one.\n    if (pathSolver) {\n      try {\n        finalSrc = pathSolver(src, solverParams);\n      } catch (e) {\n        this.emit('error', { viewer: this, error: `Path solver failed`, src, reason: e, pathSolver, solverParams });\n\n        return;\n      }\n    } else {\n      finalSrc = src;\n    }\n\n    if (!finalSrc) {\n      return;\n    }\n\n    // Allow path solvers to return promises.\n    if (finalSrc instanceof Promise) {\n      finalSrc = await finalSrc;\n    }\n\n    // Give path solvers the option to inject resources.\n    if (finalSrc instanceof Resource) {\n      return finalSrc;\n    }\n\n    // If the final source is a string, and doesn't match any handler, it is assumed to be an URL to fetch.\n    if (typeof finalSrc === 'string' && !this.detectFormat(finalSrc)) {\n      fetchUrl = finalSrc;\n\n      // Check the promise cache and return a promise if one exists.\n      promise = this.promiseMap.get(fetchUrl);\n      if (promise) {\n        return promise;\n      }\n\n      // Check the fetch cache and return a resource if one exists.\n      const resource = this.resourceMap.get(fetchUrl);\n      if (resource) {\n        return resource;\n      }\n\n      // Otherwise promise to fetch the data and construct a resource.\n      promise = fetchDataType(fetchUrl, 'arrayBuffer')\n        .then((value) => {\n          if (value.ok) {\n            return value.data;\n          } else {\n            this.emit('error', { viewer: this, error: `Failed to fetch a resource: ${value.error}`, fetchUrl, reason: value.data });\n            return;\n          }\n        });\n    } else {\n      fetchUrl = `__DIRECT_LOAD_${this.directLoadId++}`;\n      promise = Promise.resolve(finalSrc);\n    }\n\n    promise = promise\n      .then(async (actualSrc) => {\n        // finalSrc will be undefined if this is a fetch and the fetch failed.\n        if (actualSrc) {\n          if (actualSrc instanceof ArrayBuffer) {\n            actualSrc = new Uint8Array(actualSrc);\n          }\n\n          // If the source is an image source, load it directly.\n          if (isImageSource(actualSrc)) {\n            return new ImageTexture(<TexImageSource>actualSrc, { viewer: this, fetchUrl, pathSolver });\n          }\n\n          // If the source is a buffer of an image, convert it to an image, and load it directly.\n          if (actualSrc instanceof Uint8Array) {\n            const type = detectMime(actualSrc);\n\n            if (type.length) {\n              return new ImageTexture(await blobToImage(new Blob([actualSrc.buffer], { type })), { viewer: this, fetchUrl, pathSolver });\n            }\n          }\n\n          // Attempt to match the source to a handler.\n          const handler = this.detectFormat(actualSrc);\n\n          if (handler) {\n            try {\n              const resource = new handler.resource(actualSrc, { viewer: this, fetchUrl, pathSolver });\n\n              // If the resource is blocked by internal resources being loaded, wait for them and then clear them.\n              await Promise.all(resource.blockers);\n              resource.blockers.length = 0;\n\n              return resource;\n            } catch (e) {\n              this.emit('error', { viewer: this, error: 'Failed to create a resource', fetchUrl, src, reason: e });\n            }\n          } else {\n            this.emit('error', { viewer: this, error: 'Source has no matching handler', fetchUrl, src });\n          }\n        }\n\n        return;\n      })\n      .then((resource) => {\n        this.promiseMap.delete(fetchUrl);\n\n        if (resource) {\n          this.resourceMap.set(fetchUrl, resource);\n          this.resources.push(resource);\n\n          this.emit('load', { viewer: this, fetchUrl, resource });\n        }\n\n        this.emit('loadend', { viewer: this, fetchUrl, resource });\n        this.checkLoadingStatus();\n\n        return resource;\n      });\n\n    this.promiseMap.set(fetchUrl, promise);\n    this.emit('loadstart', { viewer: this, fetchUrl, promise });\n\n    return promise;\n  }\n\n  detectFormat(src: unknown): Handler | undefined {\n    for (const handler of this.handlers) {\n      if (handler.isValidSource(src)) {\n        return handler;\n      }\n    }\n\n    return;\n  }\n\n  /**\n   * Check whether the given string maps to a resource in the cache.\n   */\n  has(key: string): boolean {\n    return this.resourceMap.has(key);\n  }\n\n  /**\n   * Get a resource from the cache.\n   */\n  get(key: string): Resource | undefined {\n    return this.resourceMap.get(key);\n  }\n\n  /**\n   * Load something generic.\n   * \n   * Unlike load(), this does not use handlers or construct any internal objects.\n   * \n   * `dataType` can be one of: `\"image\"`, `\"string\"`, `\"arrayBuffer\"`, `\"bytes\"`, `\"blob\"`.\n   * \n   * If `callback` isn't given, the resource's `data` is the fetch data, according to `dataType`.\n   * \n   * If `callback` is given, the resource's `data` is the value returned by it when called with the fetch data.\n   * \n   * If `callback` returns a promise, the resource's `data` will be whatever the promise resolved to.\n   */\n  async loadGeneric(fetchUrl: string, dataType: FetchDataTypeName, callback?: (data: FetchDataType) => unknown): Promise<GenericResource | undefined> {\n    // Check the promise cache and return a promise if one exists.\n    const promise = this.promiseMap.get(fetchUrl);\n    if (promise) {\n      return <Promise<GenericResource>>promise;\n    }\n\n    // Check the fetch cache and return a resource if one exists.\n    const resource = this.resourceMap.get(fetchUrl);\n    if (resource) {\n      return <GenericResource>resource;\n    }\n\n    const fetchPromise = fetchDataType(fetchUrl, dataType)\n      .then(async (value: FetchResult) => {\n        // Once the resource finished loading (successfully or not), the promise can be removed from the promise cache.\n        this.promiseMap.delete(fetchUrl);\n\n        let resource;\n\n        if (value.ok) {\n          let data: unknown = value.data;\n\n          if (callback) {\n            data = await callback(<FetchDataType>data);\n          }\n\n          resource = new GenericResource(data, { viewer: this, fetchUrl });\n\n          this.resourceMap.set(fetchUrl, resource);\n          this.resources.push(resource);\n\n          this.emit('load', { viewer: this, fetchUrl, resource });\n        } else {\n          this.emit('error', { viewer: this, error: 'Failed to fetch a generic resource', fetchUrl });\n        }\n\n        this.emit('loadend', { viewer: this, fetchUrl, resource });\n        this.checkLoadingStatus();\n\n        return resource;\n      });\n\n    this.promiseMap.set(fetchUrl, fetchPromise);\n    this.emit('loadstart', { viewer: this, fetchUrl });\n\n    return fetchPromise;\n  }\n\n  /**\n   * Unload a resource.\n   * Note that this only removes the resource from the viewer's cache.\n   * If it's being referenced and used e.g. by a scene, it will not be garbage collected.\n   */\n  unload(resource: Resource): boolean {\n    const fetchUrl = resource.fetchUrl;\n\n    if (fetchUrl !== '') {\n      this.resourceMap.delete(fetchUrl);\n    }\n\n    const resources = this.resources;\n    const index = resources.indexOf(resource);\n\n    if (index !== -1) {\n      resources.splice(index, 1);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Starts loading a new empty resource, and returns it.\n   * This empty resource will block the \"idle\" event (and thus whenAllLoaded) until it's resolved.\n   * This is used when a resource might get loaded in the future, but it is not known what it is yet.\n   */\n  promise(): () => void {\n    const promise = Promise.resolve(undefined);\n    const key = `${performance.now()}`;\n\n    this.promiseMap.set(key, promise);\n\n    return (): void => {\n      this.promiseMap.delete(key);\n      this.checkLoadingStatus();\n    };\n  }\n\n  checkLoadingStatus(): void {\n    if (this.promiseMap.size === 0) {\n      // A timeout is used so that this event will arrive after the current frame to let everything settle.\n      setTimeout(() => this.emit('idle'), 0);\n    }\n  }\n\n  /**\n   * Wait for all of the resources to load.\n   * \n   * If a callback is given, it will be called, otherwise, a promise is returned.\n   */\n  whenAllLoaded(): Promise<ModelViewer>;\n  whenAllLoaded(callback: (viewer: ModelViewer) => void): void;\n  whenAllLoaded(callback?: (viewer: ModelViewer) => void): Promise<ModelViewer> | void {\n    const promise = new Promise((resolve: (viewer: ModelViewer) => void) => {\n      if (this.promiseMap.size === 0) {\n        resolve(this);\n      } else {\n        this.once('idle', () => resolve(this));\n      }\n    });\n\n    if (callback) {\n      promise.then(() => callback(this));\n    } else {\n      return promise;\n    }\n  }\n\n  /**\n   * Get a blob representing the contents of the viewer's canvas.\n   * \n   * If a callback is given, it will be called, otherwise, a promise is returned.\n   */\n  toBlob(): Promise<Blob>; \n  toBlob(callback: BlobCallback): void;\n  toBlob(callback?: BlobCallback): Promise<Blob | null> | void {\n    const promise = new Promise((resolve: BlobCallback) => this.canvas.toBlob((blob) => resolve(blob)));\n\n    if (callback) {\n      promise.then((blob) => callback(blob));\n    } else {\n      return promise;\n    }\n  }\n\n  /**\n   * Update and render a frame.\n   */\n  updateAndRender(dt = 1000 / 60): void {\n    this.update(dt);\n    this.startFrame();\n    this.render();\n  }\n\n  /**\n   * Update all of the scenes, which includes updating their cameras, audio context if one exists, and all of the instances they hold.\n   */\n  update(dt = 1000 / 60): void {\n    // Animations are in milliseconds, while particle movement and such is in seconds.\n    // It's easier to pass the time in seconds here, and turn it back to milliseconds for each instance, than it is to do the opposite for each particle.\n    dt *= 0.001;\n\n    this.frame += 1;\n\n    this.visibleCells = 0;\n    this.visibleInstances = 0;\n    this.updatedParticles = 0;\n\n    for (const scene of this.scenes) {\n      scene.update(dt);\n\n      this.visibleCells += scene.visibleCells;\n      this.visibleInstances += scene.visibleInstances;\n      this.updatedParticles += scene.updatedParticles;\n    }\n  }\n\n  /**\n   * Clears the WebGL buffer.\n   * \n   * Called automatically by updateAndRender().\n   * \n   * Call this at some point before render() if you need more control.\n   */\n  startFrame(): void {\n    const gl = this.gl;\n\n    // See https://www.opengl.org/wiki/FAQ#Masking\n    gl.depthMask(true);\n    gl.clearColor(0, 0, 0, 1);\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n  }\n\n  /**\n   * Render.\n   */\n  render(): void {\n    for (const scene of this.scenes) {\n      scene.render();\n    }\n  }\n\n  /**\n   * Clear all of the emitted objects in this viewer.\n   */\n  clearEmittedObjects(): void {\n    for (const scene of this.scenes) {\n      scene.clearEmittedObjects();\n    }\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"target\": \"es2017\",\n    \"lib\": [\"es2020\", \"dom\"],\n    \"outDir\": \"./dist/cjs\",\n    \"moduleResolution\": \"node\",\n    \"typeRoots\": [\"./types\", \"./node_modules/@types\"],\n    \"types\": [\"node\"],\n    \"sourceMap\": true,\n    \"declaration\": true,\n    \"strict\": true,\n    \"allowJs\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitOverride\": true,\n    \"noImplicitAny\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitReturns\": true,\n    \"noPropertyAccessFromIndexSignature\": true,\n    \"suppressImplicitAnyIndexErrors\": true\n  },\n  \"exclude\": [\"clients\", \"clean.js\", \"webpack.config.js\", \"dist\"]\n}"
  },
  {
    "path": "types/fengari.d.ts",
    "content": "declare module 'fengari/src/lstate' {\n  export class lua_State {}\n  // module.exports.CallInfo        = CallInfo;\n  // module.exports.CIST_OAH        = (1<<0);  /* original value of 'allowhook' */\n  // module.exports.CIST_LUA        = (1<<1);  /* call is running a Lua function */\n  // module.exports.CIST_HOOKED     = (1<<2);  /* call is running a debug hook */\n  // module.exports.CIST_FRESH      = (1<<3);  /* call is running on a fresh invocation of luaV_execute */\n  // module.exports.CIST_YPCALL     = (1<<4);  /* call is a yieldable protected call */\n  // module.exports.CIST_TAIL       = (1<<5);  /* call was tail called */\n  // module.exports.CIST_HOOKYIELD  = (1<<6);  /* last hook called yielded */\n  // module.exports.CIST_LEQ        = (1<<7);  /* using __lt for __le */\n  // module.exports.CIST_FIN        = (1<<8);   /* call is running a finalizer */\n  // module.exports.EXTRA_STACK     = EXTRA_STACK;\n  // module.exports.lua_close       = lua_close;\n  // module.exports.lua_newstate    = lua_newstate;\n  const lua_newthread: (L: lua_State) => lua_State;\n  // module.exports.luaE_extendCI   = luaE_extendCI;\n  // module.exports.luaE_freeCI     = luaE_freeCI;\n  // module.exports.luaE_freethread = luaE_freethread;\n}\n\ndeclare module 'fengari/src/lauxlib' {\n  import { lua_State } from 'fengari/src/lstate';\n\n  // module.exports.LUA_ERRFILE = LUA_ERRFILE;\n  // module.exports.LUA_FILEHANDLE = LUA_FILEHANDLE;\n  // module.exports.LUA_LOADED_TABLE = LUA_LOADED_TABLE;\n  // module.exports.LUA_NOREF = LUA_NOREF;\n  // module.exports.LUA_PRELOAD_TABLE = LUA_PRELOAD_TABLE;\n  // module.exports.LUA_REFNIL = LUA_REFNIL;\n  // module.exports.luaL_Buffer = luaL_Buffer;\n  // module.exports.luaL_addchar = luaL_addchar;\n  // module.exports.luaL_addlstring = luaL_addlstring;\n  // module.exports.luaL_addsize = luaL_addsize;\n  // module.exports.luaL_addstring = luaL_addstring;\n  // module.exports.luaL_addvalue = luaL_addvalue;\n  // module.exports.luaL_argcheck = luaL_argcheck;\n  // module.exports.luaL_argerror = luaL_argerror;\n  // module.exports.luaL_buffinit = luaL_buffinit;\n  // module.exports.luaL_buffinitsize = luaL_buffinitsize;\n  // module.exports.luaL_callmeta = luaL_callmeta;\n  // module.exports.luaL_checkany = luaL_checkany;\n  const luaL_checkinteger: (L: lua_State, arg: number) => number;\n  const luaL_checklstring: (L: lua_State, arg: number) => string;\n  const luaL_checknumber: (L: lua_State, arg: number) => number;\n  // module.exports.luaL_checkoption = luaL_checkoption;\n  // module.exports.luaL_checkstack = luaL_checkstack;\n  const luaL_checkstring: (L: lua_State, arg: number) => string;\n  // module.exports.luaL_checktype = luaL_checktype;\n  // module.exports.luaL_checkudata = luaL_checkudata;\n  // module.exports.luaL_checkversion = luaL_checkversion;\n  // module.exports.luaL_checkversion_ = luaL_checkversion_;\n  // module.exports.luaL_dofile = luaL_dofile;\n  // module.exports.luaL_dostring = luaL_dostring;\n  // module.exports.luaL_error = luaL_error;\n  // module.exports.luaL_execresult = luaL_execresult;\n  // module.exports.luaL_fileresult = luaL_fileresult;\n  // module.exports.luaL_getmetafield = luaL_getmetafield;\n  // module.exports.luaL_getmetatable = luaL_getmetatable;\n  // module.exports.luaL_getsubtable = luaL_getsubtable;\n  // module.exports.luaL_gsub = luaL_gsub;\n  // module.exports.luaL_len = luaL_len;\n  // module.exports.luaL_loadbuffer = luaL_loadbuffer;\n  // module.exports.luaL_loadbufferx = luaL_loadbufferx;\n  // module.exports.luaL_loadfile = luaL_loadfile;\n  // module.exports.luaL_loadfilex = luaL_loadfilex;\n  const luaL_loadstring: (L: lua_State, s: Uint8Array) => string;\n  // module.exports.luaL_newlib = luaL_newlib;\n  // module.exports.luaL_newlibtable = luaL_newlibtable;\n  // module.exports.luaL_newmetatable = luaL_newmetatable;\n  const luaL_newstate: () => lua_State;\n  // module.exports.luaL_opt = luaL_opt;\n  // module.exports.luaL_optinteger = luaL_optinteger;\n  // module.exports.luaL_optlstring = luaL_optlstring;\n  // module.exports.luaL_optnumber = luaL_optnumber;\n  // module.exports.luaL_optstring = luaL_optstring;\n  // module.exports.luaL_prepbuffer = luaL_prepbuffer;\n  // module.exports.luaL_prepbuffsize = luaL_prepbuffsize;\n  // module.exports.luaL_pushresult = luaL_pushresult;\n  // module.exports.luaL_pushresultsize = luaL_pushresultsize;\n  const luaL_ref: (L: lua_State, t: number) => number;\n  // module.exports.luaL_requiref = luaL_requiref;\n  // module.exports.luaL_setfuncs = luaL_setfuncs;\n  // module.exports.luaL_setmetatable = luaL_setmetatable;\n  // module.exports.luaL_testudata = luaL_testudata;\n  const luaL_tolstring: (L: lua_State, idx: number) => Uint8Array;\n  // module.exports.luaL_traceback = luaL_traceback;\n  // module.exports.luaL_typename = luaL_typename;\n  const luaL_unref: (L: lua_State, t: number, ref: number) => void;\n  // module.exports.luaL_where = luaL_where;\n  // module.exports.lua_writestringerror = lua_writestringerror;\n}\n\ndeclare module 'fengari/src/lapi' {\n  import { lua_State } from 'fengari/src/lstate';\n\n  // module.exports.api_incr_top          = api_incr_top;\n  // module.exports.api_checknelems       = api_checknelems;\n  // module.exports.lua_absindex          = lua_absindex;\n  // module.exports.lua_arith             = lua_arith;\n  // module.exports.lua_atpanic           = lua_atpanic;\n  const lua_atnativeerror: (L: lua_State, errorf: (L: lua_State) => number) => void;\n  // module.exports.lua_call              = lua_call;\n  // module.exports.lua_callk             = lua_callk;\n  // module.exports.lua_checkstack        = lua_checkstack;\n  // module.exports.lua_compare           = lua_compare;\n  // module.exports.lua_concat            = lua_concat;\n  // module.exports.lua_copy              = lua_copy;\n  // module.exports.lua_createtable       = lua_createtable;\n  // module.exports.lua_dump              = lua_dump;\n  // module.exports.lua_error             = lua_error;\n  // module.exports.lua_gc                = lua_gc;\n  // module.exports.lua_getallocf         = lua_getallocf;\n  // module.exports.lua_getextraspace     = lua_getextraspace;\n  // module.exports.lua_getfield          = lua_getfield;\n  const lua_getglobal: (L: lua_State, name: string) => unknown;\n  // module.exports.lua_geti              = lua_geti;\n  // module.exports.lua_getmetatable      = lua_getmetatable;\n  // module.exports.lua_gettable          = lua_gettable;\n  // module.exports.lua_gettop            = lua_gettop;\n  // module.exports.lua_getupvalue        = lua_getupvalue;\n  // module.exports.lua_getuservalue      = lua_getuservalue;\n  // module.exports.lua_insert            = lua_insert;\n  // module.exports.lua_isboolean         = lua_isboolean;\n  // module.exports.lua_iscfunction       = lua_iscfunction;\n  // module.exports.lua_isfunction        = lua_isfunction;\n  // module.exports.lua_isinteger         = lua_isinteger;\n  // module.exports.lua_islightuserdata   = lua_islightuserdata;\n  // module.exports.lua_isnil             = lua_isnil;\n  // module.exports.lua_isnone            = lua_isnone;\n  // module.exports.lua_isnoneornil       = lua_isnoneornil;\n  // module.exports.lua_isnumber          = lua_isnumber;\n  // module.exports.lua_isproxy           = lua_isproxy;\n  // module.exports.lua_isstring          = lua_isstring;\n  // module.exports.lua_istable           = lua_istable;\n  // module.exports.lua_isthread          = lua_isthread;\n  // module.exports.lua_isuserdata        = lua_isuserdata;\n  // module.exports.lua_len               = lua_len;\n  // module.exports.lua_load              = lua_load;\n  // module.exports.lua_newtable          = lua_newtable;\n  // module.exports.lua_newuserdata       = lua_newuserdata;\n  // module.exports.lua_next              = lua_next;\n  const lua_pcall: (L: lua_State, n: number, r: number, f: number) => number;\n  // module.exports.lua_pcallk            = lua_pcallk;\n  const lua_pop: (L: lua_State, n: number) => void;\n  const lua_pushboolean: (L: lua_State, b: boolean) => void;\n  // module.exports.lua_pushcclosure      = lua_pushcclosure;\n  // module.exports.lua_pushcfunction     = lua_pushcfunction;\n  // module.exports.lua_pushfstring       = lua_pushfstring;\n  // module.exports.lua_pushglobaltable   = lua_pushglobaltable;\n  const lua_pushinteger: (L: lua_State, n: number) => void;\n  // module.exports.lua_pushjsclosure     = lua_pushjsclosure;\n  // module.exports.lua_pushjsfunction    = lua_pushjsfunction;\n  const lua_pushlightuserdata: (L: lua_State, p: unknown) => void;\n  // module.exports.lua_pushliteral       = lua_pushliteral;\n  // module.exports.lua_pushlstring       = lua_pushlstring;\n  const lua_pushnil: (L: lua_State) => void;\n  const lua_pushnumber: (L: lua_State, n: number) => void;\n  const lua_pushstring: (L: lua_State, s: string) => string;\n  // module.exports.lua_pushthread        = lua_pushthread;\n  // module.exports.lua_pushvalue         = lua_pushvalue;\n  // module.exports.lua_pushvfstring      = lua_pushvfstring;\n  // module.exports.lua_rawequal          = lua_rawequal;\n  // module.exports.lua_rawget            = lua_rawget;\n  const lua_rawgeti: (L: lua_State, idx: number, n: number) => unknown;\n  // module.exports.lua_rawgetp           = lua_rawgetp;\n  // module.exports.lua_rawlen            = lua_rawlen;\n  // module.exports.lua_rawset            = lua_rawset;\n  // module.exports.lua_rawseti           = lua_rawseti;\n  // module.exports.lua_rawsetp           = lua_rawsetp;\n  const lua_register: (L: lua_State, n: string, f: (L: lua_State) => number) => void;\n  // module.exports.lua_remove            = lua_remove;\n  // module.exports.lua_replace           = lua_replace;\n  // module.exports.lua_rotate            = lua_rotate;\n  // module.exports.lua_setallocf         = lua_setallocf;\n  // module.exports.lua_setfield          = lua_setfield;\n  // module.exports.lua_setglobal         = lua_setglobal;\n  // module.exports.lua_seti              = lua_seti;\n  // module.exports.lua_setmetatable      = lua_setmetatable;\n  // module.exports.lua_settable          = lua_settable;\n  // module.exports.lua_settop            = lua_settop;\n  // module.exports.lua_setupvalue        = lua_setupvalue;\n  // module.exports.lua_setuservalue      = lua_setuservalue;\n  // module.exports.lua_status            = lua_status;\n  // module.exports.lua_stringtonumber    = lua_stringtonumber;\n  const lua_toboolean: (L: lua_State, idx: number) => boolean;\n  // module.exports.lua_tocfunction       = lua_tocfunction;\n  // module.exports.lua_todataview        = lua_todataview;\n  // module.exports.lua_tointeger         = lua_tointeger;\n  // module.exports.lua_tointegerx        = lua_tointegerx;\n  // module.exports.lua_tojsstring        = lua_tojsstring;\n  // module.exports.lua_tolstring         = lua_tolstring;\n  // module.exports.lua_tonumber          = lua_tonumber;\n  // module.exports.lua_tonumberx         = lua_tonumberx;\n  // module.exports.lua_topointer         = lua_topointer;\n  // module.exports.lua_toproxy           = lua_toproxy;\n  // module.exports.lua_tostring          = lua_tostring;\n  // module.exports.lua_tothread          = lua_tothread;\n  const lua_touserdata: (L: lua_State, idx: number) => unknown;\n  // module.exports.lua_type              = lua_type;\n  // module.exports.lua_typename          = lua_typename;\n  // module.exports.lua_upvalueid         = lua_upvalueid;\n  // module.exports.lua_upvaluejoin       = lua_upvaluejoin;\n  // module.exports.lua_version           = lua_version;\n  // module.exports.lua_xmove             = lua_xmove;\n}\n\ndeclare module 'fengari/src/ldo' {\n  import { lua_State } from 'fengari/src/lstate';\n\n  // module.exports.adjust_top           = adjust_top;\n  // module.exports.luaD_call            = luaD_call;\n  // module.exports.luaD_callnoyield     = luaD_callnoyield;\n  // module.exports.luaD_checkstack      = luaD_checkstack;\n  // module.exports.luaD_growstack       = luaD_growstack;\n  // module.exports.luaD_hook            = luaD_hook;\n  // module.exports.luaD_inctop          = luaD_inctop;\n  // module.exports.luaD_pcall           = luaD_pcall;\n  // module.exports.luaD_poscall         = luaD_poscall;\n  // module.exports.luaD_precall         = luaD_precall;\n  // module.exports.luaD_protectedparser = luaD_protectedparser;\n  // module.exports.luaD_rawrunprotected = luaD_rawrunprotected;\n  // module.exports.luaD_reallocstack    = luaD_reallocstack;\n  // module.exports.luaD_throw           = luaD_throw;\n  // module.exports.lua_isyieldable      = lua_isyieldable;\n  const lua_resume: (L: lua_State, from: lua_State, nargs: number) => number;\n  const lua_yield: (L: lua_State, n: number) => void;\n  // module.exports.lua_yieldk           = lua_yieldk;\n}\n\ndeclare module 'fengari/src/defs' {\n  // module.exports.luastring_from    = luastring_from;\n  // module.exports.luastring_indexOf = luastring_indexOf;\n  // module.exports.luastring_of      = luastring_of;\n  // module.exports.is_luastring      = is_luastring;\n  // module.exports.luastring_eq      = luastring_eq;\n  const to_jsstring: (value: Uint8Array, from?: number, to?: number, replacement_char?: boolean) => string;\n  // module.exports.to_uristring      = to_uristring;\n  const to_luastring: (str: string, cache?: boolean) => Uint8Array;\n  // module.exports.from_userstring   = from_userstring;\n\n  // module.exports.LUA_SIGNATURE       = LUA_SIGNATURE;\n  // module.exports.LUA_VERSION_MAJOR   = LUA_VERSION_MAJOR;\n  // module.exports.LUA_VERSION_MINOR   = LUA_VERSION_MINOR;\n  // module.exports.LUA_VERSION_NUM     = LUA_VERSION_NUM;\n  // module.exports.LUA_VERSION_RELEASE = LUA_VERSION_RELEASE;\n  // module.exports.LUA_VERSION         = LUA_VERSION;\n  // module.exports.LUA_RELEASE         = LUA_RELEASE;\n  // module.exports.LUA_COPYRIGHT       = LUA_COPYRIGHT;\n  // module.exports.LUA_AUTHORS         = LUA_AUTHORS;\n\n  // module.exports.LUA_HOOKCALL            = LUA_HOOKCALL;\n  // module.exports.LUA_HOOKCOUNT           = LUA_HOOKCOUNT;\n  // module.exports.LUA_HOOKLINE            = LUA_HOOKLINE;\n  // module.exports.LUA_HOOKRET             = LUA_HOOKRET;\n  // module.exports.LUA_HOOKTAILCALL        = LUA_HOOKTAILCALL;\n  // module.exports.LUA_MASKCALL            = LUA_MASKCALL;\n  // module.exports.LUA_MASKCOUNT           = LUA_MASKCOUNT;\n  // module.exports.LUA_MASKLINE            = LUA_MASKLINE;\n  // module.exports.LUA_MASKRET             = LUA_MASKRET;\n  // module.exports.LUA_MINSTACK            = LUA_MINSTACK;\n  // module.exports.LUA_MULTRET             = -1;\n  // module.exports.LUA_OPADD               = LUA_OPADD;\n  // module.exports.LUA_OPBAND              = LUA_OPBAND;\n  // module.exports.LUA_OPBNOT              = LUA_OPBNOT;\n  // module.exports.LUA_OPBOR               = LUA_OPBOR;\n  // module.exports.LUA_OPBXOR              = LUA_OPBXOR;\n  // module.exports.LUA_OPDIV               = LUA_OPDIV;\n  // module.exports.LUA_OPEQ                = LUA_OPEQ;\n  // module.exports.LUA_OPIDIV              = LUA_OPIDIV;\n  // module.exports.LUA_OPLE                = LUA_OPLE;\n  // module.exports.LUA_OPLT                = LUA_OPLT;\n  // module.exports.LUA_OPMOD               = LUA_OPMOD;\n  // module.exports.LUA_OPMUL               = LUA_OPMUL;\n  // module.exports.LUA_OPPOW               = LUA_OPPOW;\n  // module.exports.LUA_OPSHL               = LUA_OPSHL;\n  // module.exports.LUA_OPSHR               = LUA_OPSHR;\n  // module.exports.LUA_OPSUB               = LUA_OPSUB;\n  // module.exports.LUA_OPUNM               = LUA_OPUNM;\n  const LUA_REGISTRYINDEX: number;\n  // module.exports.LUA_RIDX_GLOBALS        = LUA_RIDX_GLOBALS;\n  // module.exports.LUA_RIDX_LAST           = LUA_RIDX_LAST;\n  // module.exports.LUA_RIDX_MAINTHREAD     = LUA_RIDX_MAINTHREAD;\n  // module.exports.constant_types          = constant_types;\n  // module.exports.lua_Debug               = lua_Debug;\n  // module.exports.lua_upvalueindex        = lua_upvalueindex;\n  const thread_status: {\n    LUA_OK:        0,\n    LUA_YIELD:     1,\n    LUA_ERRRUN:    2,\n    LUA_ERRSYNTAX: 3,\n    LUA_ERRMEM:    4,\n    LUA_ERRGCMM:   5,\n    LUA_ERRERR:    6\n  };\n}\n"
  },
  {
    "path": "types/tga-js.d.ts",
    "content": "declare module 'tga-js' {\n  export default class TgaLoader {\n    header: {\n      idLength: number;\n      colorMapType: number;\n      imageType: number;\n      colorMapIndex: number;\n      colorMapLength: number;\n      colorMapDepth: number;\n      offsetX: number;\n      offsetY: number;\n      width: number;\n      height: number;\n      pixelDepth: number;\n      flags: number;\n    };\n\n    open(path: string, callback: () => void): void;\n    load(data: Uint8Array): void;\n    getImageData(imageData: ImageData): ImageData;\n    getCanvas(): HTMLCanvasElement;\n    getDataUrl(type: string): string;\n  }\n}\n"
  },
  {
    "path": "webpack.config.js",
    "content": "const fs = require('fs');\nconst webpack = require('webpack');\nconst TerserPlugin = require('terser-webpack-plugin');\n\nmodule.exports = (env, argv) => {\n  let entry;\n\n  if (env.umd) {\n    // The repo as a library.\n    entry = {\n      'viewer': { import: './src/index.ts', filename: 'umd/viewer.min.js', library: { name: 'ModelViewer', type: 'var' } },\n    };\n  } else {\n    // Built-in clients.\n    entry = {\n      'example': { import: './clients/example/index.js', filename: 'clients/example.min.js' },\n      'downgrader': { import: './clients/downgrader/index.js', filename: 'clients/downgrader.min.js' },\n      'map': { import: './clients/map/index.js', filename: 'clients/map.min.js' },\n      'mdlx': { import: './clients/mdlx/index.js', filename: 'clients/mdlx.min.js' },\n      'rebuild': { import: './clients/rebuild/index.js', filename: 'clients/rebuild.min.js' },\n      'sanitytest': { import: './clients/sanitytest/index.js', filename: 'clients/sanitytest.min.js' },\n      'tests': { import: './clients/tests/index.js', filename: 'clients/tests.min.js' },\n      'weu': { import: './clients/weu/index.js', filename: 'clients/weu.min.js' },\n      'mdlxoptimizer': { import: './clients/mdlxoptimizer/index.ts', filename: 'clients/mdlxoptimizer.min.js' },\n    };\n  }\n\n  return {\n    entry,\n    plugins: [\n      new webpack.BannerPlugin(fs.readFileSync('LICENSE', 'utf8')),\n      // Note: this is needed to compile fengari for the web.\n      new webpack.DefinePlugin({\n        'process.env.FENGARICONF': 'void 0',\n        'typeof process': JSON.stringify('undefined'),\n      }),\n    ],\n    performance: {\n      hints: false,\n    },\n    module: {\n      rules: [\n        {\n          test: /\\.ts$/,\n          exclude: /node_modules/,\n          loader: 'ts-loader',\n          options: { compilerOptions: { module: 'esnext', declaration: false } }\n        },\n      ],\n    },\n    resolve: {\n      extensions: ['.js', '.ts'],\n    },\n    devtool: argv.mode === 'development' ? 'eval-cheap-module-source-map' : 'source-map',\n    optimization: {\n      minimizer: [new TerserPlugin({\n        extractComments: false,\n      })],\n    },\n  };\n};\n"
  }
]