[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: hediet\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "on:\n  push:\n    branches:\n      - master\n  pull_request:\n\njobs:\n  build:\n    strategy:\n      matrix:\n        os: [macos-latest, ubuntu-latest, windows-latest]\n    runs-on: ${{ matrix.os }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v2\n        with:\n          submodules: true\n      - name: Install Node.js\n        uses: actions/setup-node@v1\n        with:\n          node-version: 20.x\n      - run: yarn install\n      - run: yarn build\n"
  },
  {
    "path": ".github/workflows/opened-issues-triage.yml",
    "content": "name: Move new issues into Triage\n\non:\n  issues:\n    types: [opened]\n\njobs:\n  automate-project-columns:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: alex-page/github-project-automation-plus@v0.2.3\n        with:\n          project: Backlog\n          column: Triage\n          repo-token: ${{ secrets.GH_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\ndist/\nout/\n\n# Python byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n*.vsix"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n\t\"trailingComma\": \"es5\",\n\t\"tabWidth\": 4,\n\t\"semi\": true,\n\t\"useTabs\": true,\n\t\"printWidth\": 120\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"type\": \"chrome\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"name\": \"Launch Chrome\",\n\t\t\t\"url\": \"http://localhost:8090\",\n\t\t\t\"webRoot\": \"${workspaceFolder}/visualization-playground\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Run Extension (Hot Reload)\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"runtimeExecutable\": \"${execPath}\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}/extension\",\n\t\t\t\t\"${workspaceFolder}/demos/php\"\n\t\t\t],\n\t\t\t\"env\": {\n\t\t\t\t\"HOT_RELOAD\": \"true\",\n\t\t\t\t\"USE_DEV_UI\": \"\"\n\t\t\t},\n\t\t\t\"outFiles\": [\"${workspaceFolder}/extension/dist/**/*.js\"],\n\t\t\t\"preLaunchTask\": \"npm: dev - extension\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Run Extension (Hot Reload + Dev UI)\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"runtimeExecutable\": \"${execPath}\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}/extension\",\n\t\t\t\t\"${workspaceFolder}/demos/php\"\n\t\t\t],\n\t\t\t\"env\": {\n\t\t\t\t\"HOT_RELOAD\": \"true\",\n\t\t\t\t\"USE_DEV_UI\": \"true\"\n\t\t\t},\n\t\t\t\"outFiles\": [\"${workspaceFolder}/extension/dist/**/*.js\"],\n\t\t\t\"preLaunchTask\": \"npm: dev - extension\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Run Extension\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"runtimeExecutable\": \"${execPath}\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}/extension\",\n\t\t\t\t\"${workspaceFolder}/demos/js\"\n\t\t\t],\n\t\t\t\"env\": {\n\t\t\t\t\"HOT_RELOAD\": \"\",\n\t\t\t\t\"USE_DEV_UI\": \"\"\n\t\t\t},\n\t\t\t\"outFiles\": [\"${workspaceFolder}/extension/dist/**/*.js\"]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Run Extension (Dev UI)\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"runtimeExecutable\": \"${execPath}\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}/extension\",\n\t\t\t\t\"${workspaceFolder}/demos/js\"\n\t\t\t],\n\t\t\t\"env\": {\n\t\t\t\t\"HOT_RELOAD\": \"\",\n\t\t\t\t\"USE_DEV_UI\": \"true\"\n\t\t\t},\n\t\t\t\"outFiles\": [\"${workspaceFolder}/extension/dist/**/*.js\"],\n\t\t\t\"preLaunchTask\": \"npm: dev - extension\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"dart\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"name\": \"Run Dart samples\",\n\t\t\t\"program\": \"demos/dart/demo.dart\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n\t\"search.exclude\": {\n\t\t\"extension/out\": true\n\t},\n\t\"plantuml.diagramsRoot\": \"docs\",\n\t\"plantuml.exportFormat\": \"png\",\n\t\"plantuml.exportOutDir\": \"docs/exported\",\n\t\"typescript.updateImportsOnFileMove.enabled\": \"prompt\",\n\t\"mochaExplorer.files\": \"./data-extraction/test/**/*.test.ts\",\n\t\"mochaExplorer.require\": [\"ts-node/register\", \"source-map-support/register\"],\n\t\"tasksStatusbar.taskLabelFilter\": \"dev\",\n\t\"editor.formatOnSave\": true,\n\t\"typescript.tsdk\": \"node_modules\\\\typescript\\\\lib\",\n\n\t\"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n\t\"prettier.prettierPath\": \"node_modules/prettier\",\n\t\"prettier.printWidth\": 120,\n\t\"[javascript]\": {\n\t\t\"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n\t}\n}\n"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t{\n\t\t\t\"type\": \"npm\",\n\t\t\t\"label\": \"npm: dev - extension\",\n\t\t\t\"script\": \"dev\",\n\t\t\t\"problemMatcher\": \"$tsc-watch\",\n\t\t\t\"isBackground\": true,\n\t\t\t\"presentation\": {\n\t\t\t\t\"reveal\": \"never\"\n\t\t\t},\n\t\t\t\"path\": \"extension/\",\n\t\t\t\"group\": {\n\t\t\t\t\"kind\": \"build\",\n\t\t\t\t\"isDefault\": true\n\t\t\t}\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nThis document extends the [readme](./extension/README.md) of the extension with implementation details.\n\n## Build Instructions\n\n-   Clone the repository\n-   Run `yarn` in the repository root\n-   Run `yarn build`\n\n## Dev Instructions\n\nThis project uses yarn workspaces and consists of the sub-projects _data-extraction_, _extension_ and _webview_.\nTo setup a dev environment, follow these steps:\n\n-   Clone the repository\n-   Run `yarn` in the repository root\n-   Run `yarn build` initially (or `yarn dev` for every sub-project)\n-   Run `yarn dev` for the sub-project (i.e. in its folder) you are working on.\n\nFor the _webview_ project, `yarn dev` will serve the react application on port 8080.\nCertain query parameters need to be set, so that the UI can connect to the debug visualizer extension.\n\nYou can use VS Code to launch and debug the extension.\nChoose the preconfigured `Run Extension (Dev UI)` as debug configuration\nso that the extension loads the UI from the webpack server.\nOtherwise, the extension will start a webserver on its own, hosting the `dist` folder of the _webview_ project.\n\n## Publish Instructions\n\n-   Follow the Build Instructions\n-   `cd extension`\n-   `yarn pub`\n\n## Architecture\n\n![](./docs/exported/main/Main.png)\n\n### webview\n\nImplements the UI and is hosted inside a webview in VS Code.\nCan be opened in a browser window.\nUses websockets and JSON RPC to communicate with the extension.\n\n### hediet/visualization\n\nContains all the visualizers and visualization infrastructure.\nThis external project can be found [here](https://github.com/hediet/visualization).\n\n### extension\n\nCreates the webview in VS Code, hosts a webserver and a websocket server.\nThe webserver serves the _webview_ project that is loaded by the webview.\nIf started with the `Run Extension (Dev UI)` debug configuration, it will load\nthe page from `http://localhost:8080` rather than from its own http server.\n\nThe webview is served from an http server rather than the file system to work around some security mechanisms,\nwhich would prevent lazy chunk loading or websockets.\n\nAfter the webview is loaded, it connects to the websocket server.\nThe websocket server is used to evaluate expressions and is secured by a random token.\n\n### data-extraction\n\nProvides types and a JS runtime for data extraction.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\nCopyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\n                            Preamble\n\nThe GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\nThe licenses for most software and other practical works are designed\nto take away your freedom to share and change the works. By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users. We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors. You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not\nprice. Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\nTo protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights. Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\nFor example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received. You must make sure that they, too, receive\nor can get the source code. And you must show them these terms so they\nknow their rights.\n\nDevelopers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\nFor the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software. For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\nSome devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so. This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software. The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable. Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts. If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\nFinally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary. To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\nThe precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n0. Definitions.\n\n\"This License\" refers to version 3 of the GNU General Public License.\n\n\"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n\"The Program\" refers to any copyrightable work licensed under this\nLicense. Each licensee is addressed as \"you\". \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\nTo \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy. The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\nA \"covered work\" means either the unmodified Program or a work based\non the Program.\n\nTo \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy. Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\nTo \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies. Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\nAn interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License. If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n1. Source Code.\n\nThe \"source code\" for a work means the preferred form of the work\nfor making modifications to it. \"Object code\" means any non-source\nform of a work.\n\nA \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\nThe \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form. A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\nThe \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities. However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work. For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\nThe Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\nThe Corresponding Source for a work in source code form is that\nsame work.\n\n2. Basic Permissions.\n\nAll rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met. This License explicitly affirms your unlimited\npermission to run the unmodified Program. The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work. This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\nYou may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force. You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright. Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\nConveying under any other circumstances is permitted solely under\nthe conditions stated below. Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\nNo covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\nWhen you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n4. Conveying Verbatim Copies.\n\nYou may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\nYou may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n5. Conveying Modified Source Versions.\n\nYou may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\nA compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit. Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n6. Conveying Non-Source Forms.\n\nYou may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\nA separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\nA \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling. In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage. For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product. A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n\"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source. The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\nIf you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information. But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\nThe requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed. Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\nCorresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n7. Additional Terms.\n\n\"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law. If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\nWhen you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit. (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.) You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\nNotwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\nAll other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10. If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term. If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\nIf you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\nAdditional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n8. Termination.\n\nYou may not propagate or modify a covered work except as expressly\nprovided under this License. Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\nHowever, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\nMoreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\nTermination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License. If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n9. Acceptance Not Required for Having Copies.\n\nYou are not required to accept this License in order to receive or\nrun a copy of the Program. Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance. However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work. These actions infringe copyright if you do\nnot accept this License. Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n10. Automatic Licensing of Downstream Recipients.\n\nEach time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License. You are not responsible\nfor enforcing compliance by third parties with this License.\n\nAn \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations. If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\nYou may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License. For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n11. Patents.\n\nA \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based. The\nwork thus licensed is called the contributor's \"contributor version\".\n\nA contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version. For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\nEach contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\nIn the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement). To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\nIf you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients. \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\nIf, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\nA patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License. You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\nNothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n12. No Surrender of Others' Freedom.\n\nIf conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License. If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all. For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n13. Use with the GNU Affero General Public License.\n\nNotwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work. The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n14. Revised Versions of this License.\n\nThe Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time. Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number. If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation. If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\nIf the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\nLater license versions may give you additional or different\npermissions. However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n15. Disclaimer of Warranty.\n\nTHERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n16. Limitation of Liability.\n\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n17. Interpretation of Sections 15 and 16.\n\nIf the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and`show c' should show the appropriate\nparts of the General Public License. Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\nYou should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\nThe GNU General Public License does not permit incorporating your program\ninto proprietary programs. If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library. If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License. But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.md",
    "content": "# VS Code Debug Visualizer\n\n[![](https://img.shields.io/static/v1?style=social&label=Sponsor&message=%E2%9D%A4&logo=GitHub&color&link=%3Curl%3E)](https://github.com/sponsors/hediet)\n[![](https://img.shields.io/static/v1?style=social&label=Donate&message=%E2%9D%A4&logo=Paypal&color&link=%3Curl%3E)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZP5F38L4C88UY&source=url)\n[![](https://img.shields.io/twitter/follow/hediet_dev.svg?style=social)](https://twitter.com/intent/follow?screen_name=hediet_dev)\n\nSee [README.md](./extension/README.md) for the readme of the extension.\n\nYou can get the extension in the [marketplace](https://marketplace.visualstudio.com/items?itemName=hediet.debug-visualizer).\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for build instructions and implementation details.\n\n![](./docs/doubly-linked-list-reverse-demo.gif)\n"
  },
  {
    "path": "data-extraction/CHANGELOG.md",
    "content": "# Change Log\n\n## 0.11.0\n\n-   Object Graph Data Extractor\n-   Plotly Data Extractor\n-   Some Bugfixes\n"
  },
  {
    "path": "data-extraction/LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 Henning Dieterichs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject 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,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "data-extraction/README.md",
    "content": "# @hediet/debug-visualizer-data-extraction\n\n[![](https://img.shields.io/twitter/follow/hediet_dev.svg?style=social)](https://twitter.com/intent/follow?screen_name=hediet_dev)\n\nA library that helps implementing data extractors for the Debug Visualizer VS Code extension.\nIt will automatically be injected by the extension when the debugger attaches.\nCompatible with NodeJS and browsers.\n\n# Installation\n\nUse the following command to install the library using yarn:\n\n```\nyarn add @hediet/debug-visualizer-data-extraction\n```\n\n# Usage\n\n## `createGraphFromPointers` Helper\n\n```ts\nimport { createGraphFromPointers } from \"@hediet/debug-visualizer-data-extraction\";\n\nsetTimeout(() => {\n\tnew Main().run();\n}, 0);\n\nclass Main {\n\trun() {\n\t\tconst list = new DoublyLinkedList(\"1\");\n\t\tlist.setNext(new DoublyLinkedList(\"2\"));\n\t\tlist.next!.setNext(new DoublyLinkedList(\"3\"));\n\t\tlist.next!.next!.setNext(new DoublyLinkedList(\"4\"));\n\n\t\t// Watch `visualize()` with the Debug Visualizer Extension for VS Code!\n\t\tconst visualize = () =>\n\t\t\t// Returns `CommonDataTypes.Graph` data which can be visualized by\n\t\t\t// either the vis.js or the graphviz visualizer.\n\t\t\tcreateGraphFromPointers({ list, last, cur }, i => ({\n\t\t\t\tid: i.id,\n\t\t\t\tlabel: i.name,\n\t\t\t\tcolor: finished.has(i) ? \"lime\" : undefined,\n\t\t\t\tedges: [\n\t\t\t\t\t{ to: i.next!, label: \"next\" },\n\t\t\t\t\t{ to: i.prev!, label: \"prev\", color: \"lightgray\" },\n\t\t\t\t].filter(r => !!r.to),\n\t\t\t}));\n\n\t\tconst finished = new Set();\n\t\tvar cur: DoublyLinkedList | undefined = list;\n\t\t// Reverses `list`. Finished nodes have correct pointers,\n\t\t// their next node is also finished.\n\t\tvar last: DoublyLinkedList | undefined = undefined;\n\t\twhile (cur) {\n\t\t\tcur.prev = cur.next;\n\t\t\tcur.next = last;\n\t\t\tfinished.add(cur);\n\t\t\tlast = cur;\n\t\t\tcur = cur.prev;\n\t\t}\n\t\tconsole.log(\"finished\");\n\t}\n}\n\nlet id = 0;\nclass DoublyLinkedList {\n\tpublic readonly id = (id++).toString();\n\tconstructor(public name: string) {}\n\n\tnext: DoublyLinkedList | undefined;\n\tprev: DoublyLinkedList | undefined;\n\n\tpublic setNext(val: DoublyLinkedList): void {\n\t\tval.prev = this;\n\t\tthis.next = val;\n\t}\n}\n```\n\n![](../docs/doubly-linked-list-reverse-demo.gif)\n\n## Registering Custom Data Extractors\n\n```ts\nimport { getDataExtractorApi } from \"@hediet/debug-visualizer-data-extraction\";\n\ngetDataExtractorApi().registerExtractor({\n\tid: \"my-foo-extractor\",\n\tgetExtractions: (data, collector) => {\n\t\tif (data instanceof Foo) {\n\t\t\tcollector.addExtraction({\n\t\t\t\tid: \"my-foo-extraction\",\n\t\t\t\tname: \"My Foo Extraction\",\n\t\t\t\tpriority: 2000,\n\t\t\t\textractData: () => ({ kind: { text: true }, text: \"Foo\" }),\n\t\t\t});\n\t\t}\n\t},\n});\n\nsetTimeout(() => {\n\tnew Main().run();\n}, 0);\n\nclass Foo {}\n\nclass Main {\n\trun() {\n\t\tconst f = new Foo();\n\t\t// if `f` is watched by the Debug Visualizer,\n\t\t// `my-foo-extractor` will provide the data for the visualizers.\n\t\t// See `CommonDataTypes` for data types that have built in visualizers.\n\t\tdebugger;\n\t}\n}\n```\n"
  },
  {
    "path": "data-extraction/package.json",
    "content": "{\n\t\"name\": \"@hediet/debug-visualizer-data-extraction\",\n\t\"description\": \"A library that helps implementing data extractors for the Debug Visualizer VS Code extension.\",\n\t\"version\": \"0.14.0\",\n\t\"main\": \"dist/index.js\",\n\t\"types\": \"dist/index.d.ts\",\n\t\"author\": {\n\t\t\"name\": \"Henning Dieterichs\",\n\t\t\"email\": \"henning.dieterichs@live.de\"\n\t},\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/hediet/vscode-debug-visualizer.git\"\n\t},\n\t\"license\": \"MIT\",\n\t\"files\": [\n\t\t\"dist\",\n\t\t\"src\"\n\t],\n\t\"publishConfig\": {\n\t\t\"access\": \"public\",\n\t\t\"registry\": \"https://registry.npmjs.org/\"\n\t},\n\t\"scripts\": {\n\t\t\"dev\": \"webpack --watch --mode development\",\n\t\t\"build\": \"webpack --mode production\",\n\t\t\"test\": \"mocha --require source-map-support/register --require ts-node/register ./test/**/*.test.ts\"\n\t},\n\t\"dependencies\": {},\n\t\"devDependencies\": {\n\t\t\"copy-webpack-plugin\": \"^11.0.0\",\n\t\t\"@types/copy-webpack-plugin\": \"^10.1.0\",\n\t\t\"@types/mocha\": \"^7.0.2\",\n\t\t\"@types/node\": \"^13.7.4\",\n\t\t\"@types/plotly.js\": \"1.44.28\",\n\t\t\"coveralls\": \"^3.0.11\",\n\t\t\"mocha\": \"^7.1.1\",\n\t\t\"mocha-lcov-reporter\": \"^1.3.0\",\n\t\t\"nyc\": \"^15.0.0\",\n\t\t\"source-map-support\": \"^0.5.16\",\n\t\t\"tslint\": \"^6.1.3\",\n\t\t\"typescript\": \"^5.1.6\",\n\t\t\"webpack\": \"^5.88.1\",\n\t\t\"webpack-cli\": \"^5.1.4\",\n\t\t\"ts-loader\": \"^9.4.4\",\n\t\t\"ts-node\": \"^10.9.1\"\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/CommonDataTypes.ts",
    "content": "// This file was created automatically. Do not edit it manually!\n\nexport type KnownVisualizationData =\n\t| TreeVisualizationData\n\t| AstTreeVisualizationData\n\t| GraphvizDotVisualizationData\n\t| GraphVisualizationData\n\t| GraphVisualizationData\n\t| GridVisualizationData\n\t| ImageVisualizationData\n\t| MonacoTextVisualizationData\n\t| MonacoTextDiffVisualizationData\n\t| TableVisualizationData\n\t| PlotlyVisualizationData\n\t| SimpleTextVisualizationData\n\t| SvgVisualizationData;\n\nexport type TreeVisualizationData = {\n\tkind: {\n\t\ttree: true;\n\t};\n\troot: TreeNode;\n};\n\nexport type TreeNode = {\n\t/**\n\t * The children of this tree-node\n\t */\n\tchildren: TreeNode[];\n\t/**\n\t * The parts that make up the text of this item\n\t */\n\titems: TreeNodeItem[];\n\t/**\n\t * If a node is selected, the concatenation of all segment values from root to the selected node is shown to the user.\n\t */\n\tsegment?: string;\n\t/**\n\t * Marked nodes are highlighted and scrolled into view on every visualization update.\n\t */\n\tisMarked?: boolean;\n};\n\nexport type TreeNodeItem = {\n\t/**\n\t * The text to show\n\t */\n\ttext: string;\n\t/**\n\t * The style of the text\n\t */\n\temphasis?: \"style1\" | \"style2\" | \"style3\" | string;\n};\n\nexport type AstTreeVisualizationData = {\n\tkind: {\n\t\tast: true;\n\t\ttree: true;\n\t\ttext: true;\n\t};\n\troot: AstTreeNode;\n\ttext: string;\n\tfileName?: string;\n};\n\nexport type AstTreeNode = {\n\tchildren: AstTreeNode[];\n\titems: AstTreeNodeItem[];\n\tsegment?: string;\n\tisMarked?: boolean;\n\tspan: {\n\t\tstart: number;\n\t\tlength: number;\n\t};\n};\n\nexport type AstTreeNodeItem = {\n\ttext: string;\n\temphasis?: \"style1\" | \"style2\" | \"style3\" | string;\n};\n\nexport type GraphvizDotVisualizationData = {\n\tkind: {\n\t\tdotGraph: true;\n\t};\n\ttext: string;\n};\n\nexport type GraphVisualizationData = {\n\tkind: {\n\t\tgraph: true;\n\t};\n\tnodes: GraphNode[];\n\tedges: GraphEdge[];\n};\n\nexport type GraphNode = {\n\tid: string;\n\tlabel?: string;\n\tcolor?: string;\n\tshape?: \"ellipse\" | \"box\";\n};\n\nexport type GraphEdge = {\n\tfrom: string;\n\tto: string;\n\tlabel?: string;\n\tid?: string;\n\tcolor?: string;\n\tstyle?: \"solid\" | \"dashed\" | \"dotted\";\n};\n\nexport type GridVisualizationData = {\n\tkind: {\n\t\tgrid: true;\n\t};\n\tcolumnLabels?: {\n\t\tlabel?: string;\n\t}[];\n\trows: {\n\t\tlabel?: string;\n\t\tcolumns: {\n\t\t\tcontent?: string;\n\t\t\t/**\n\t\t\t * A value to identify this cell. Should be unique.\n\t\t\t */\n\t\t\ttag?: string;\n\t\t\tcolor?: string;\n\t\t}[];\n\t}[];\n\tmarkers?: {\n\t\tid: string;\n\t\trow: number;\n\t\tcolumn: number;\n\t\trows?: number;\n\t\tcolumns?: number;\n\t\tlabel?: string;\n\t\tcolor?: string;\n\t}[];\n};\n\nexport type ImageVisualizationData = {\n\tkind: {\n\t\timagePng: true;\n\t};\n\t/**\n\t * The base 64 encoded PNG representation of the image\n\t */\n\tbase64Data: string;\n};\n\nexport type MonacoTextVisualizationData = {\n\tkind: {\n\t\ttext: true;\n\t};\n\t/**\n\t * The text to show\n\t */\n\ttext: string;\n\tdecorations?: {\n\t\trange: LineColumnRange;\n\t\tlabel?: string;\n\t}[];\n\t/**\n\t * An optional filename that might be used for chosing a syntax highlighter\n\t */\n\tfileName?: string;\n};\n\nexport type LineColumnRange = {\n\t/**\n\t * The start position\n\t */\n\tstart: LineColumnPosition;\n\t/**\n\t * The end position\n\t */\n\tend: LineColumnPosition;\n};\n\nexport type LineColumnPosition = {\n\t/**\n\t * The 0-based line number\n\t */\n\tline: number;\n\t/**\n\t * The 0-based column number\n\t */\n\tcolumn: number;\n};\n\nexport type MonacoTextDiffVisualizationData = {\n\tkind: {\n\t\ttext: true;\n\t};\n\t/**\n\t * The text to show\n\t */\n\ttext: string;\n\t/**\n\t * The text to compare against\n\t */\n\totherText: string;\n\t/**\n\t * An optional filename that might be used for chosing a syntax highlighter\n\t */\n\tfileName?: string;\n};\n\nexport type TableVisualizationData = {\n\tkind: {\n\t\ttable: true;\n\t};\n\t/**\n\t * An array of objects. The properties of the objects are used as columns.\n\t */\n\trows: {}[];\n};\n\nexport type PlotlyVisualizationData = {\n\tkind: {\n\t\tplotly: true;\n\t};\n\t/**\n\t * Expecting Plotly.Data[] (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/795ce172038dbafcb9cba030d637d733a7eea19c/types/plotly.js/index.d.ts#L1036)\n\t */\n\tdata: {\n\t\ttext?: string | string[];\n\t\txaxis?: string;\n\t\tyaxis?: string;\n\t\tcells?: {\n\t\t\tvalues?: string[][];\n\t\t};\n\t\theader?: {\n\t\t\tvalues?: string[];\n\t\t};\n\t\tdomain?: {\n\t\t\tx?: number[],\n\t\t\ty?: number[],\n\t\t};\n\t\tx?: (string | number | null)[] | (string | number | null)[][];\n\t\ty?: (string | number | null)[] | (string | number | null)[][];\n\t\tz?: (string | number | null)[] | (string | number | null)[][];\n\t\ttype?:\n\t\t\t| \"bar\"\n\t\t\t| \"box\"\n\t\t\t| \"candlestick\"\n\t\t\t| \"choropleth\"\n\t\t\t| \"contour\"\n\t\t\t| \"heatmap\"\n\t\t\t| \"histogram\"\n\t\t\t| \"indicator\"\n\t\t\t| \"mesh3d\"\n\t\t\t| \"ohlc\"\n\t\t\t| \"parcoords\"\n\t\t\t| \"pie\"\n\t\t\t| \"pointcloud\"\n\t\t\t| \"scatter\"\n\t\t\t| \"scatter3d\"\n\t\t\t| \"scattergeo\"\n\t\t\t| \"scattergl\"\n\t\t\t| \"scatterpolar\"\n\t\t\t| \"scatterternary\"\n\t\t\t| \"sunburst\"\n\t\t\t| \"surface\"\n\t\t\t| \"treemap\"\n\t\t\t| \"waterfall\"\n\t\t\t| \"funnel\"\n\t\t\t| \"funnelarea\"\n\t\t\t| \"scattermapbox\"\n\t\t\t| \"table\";\n\t\tmode?:\n\t\t\t| \"lines\"\n\t\t\t| \"markers\"\n\t\t\t| \"text\"\n\t\t\t| \"lines+markers\"\n\t\t\t| \"text+markers\"\n\t\t\t| \"text+lines\"\n\t\t\t| \"text+lines+markers\"\n\t\t\t| \"none\"\n\t\t\t| \"gauge\"\n\t\t\t| \"number\"\n\t\t\t| \"delta\"\n\t\t\t| \"number+delta\"\n\t\t\t| \"gauge+number\"\n\t\t\t| \"gauge+number+delta\"\n\t\t\t| \"gauge+delta\";\n\t}[];\n\t/**\n\t * Expecting Partial<Plotly.Layout> (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/795ce172038dbafcb9cba030d637d733a7eea19c/types/plotly.js/index.d.ts#L329)\n\t */\n\tlayout?: {\n\t\ttitle?: string;\n\t};\n};\n\nexport type SimpleTextVisualizationData = {\n\tkind: {\n\t\ttext: true;\n\t};\n\ttext: string;\n};\n\nexport type SvgVisualizationData = {\n\tkind: {\n\t\tsvg: true;\n\t};\n\t/**\n\t * The svg content\n\t */\n\ttext: string;\n};\n"
  },
  {
    "path": "data-extraction/src/DataExtractionResult.ts",
    "content": "export interface DataExtractionResult {\n\tdata: VisualizationData;\n\tusedExtractor: DataExtractorInfo;\n\tavailableExtractors: DataExtractorInfo[];\n}\n\n/**\n * Instances must be valid json values.\n */\nexport interface VisualizationData {\n\tkind: Record<string, true>;\n}\n\nexport interface DataExtractorInfo {\n\tid: DataExtractorId;\n\tname: string;\n\tpriority: number;\n}\n\nexport type DataExtractorId = {\n\t__brand: \"DataExtractorId\";\n} & string;\n\nexport function isVisualizationData(val: unknown): val is VisualizationData {\n\tif (typeof val !== \"object\" || !val || !(\"kind\" in val)) {\n\t\treturn false;\n\t}\n\n\tconst obj = val as any;\n\tif (typeof obj.kind !== \"object\" || !obj.kind) {\n\t\treturn false;\n\t}\n\n\treturn Object.values(obj.kind).every(val => val === true);\n}\n"
  },
  {
    "path": "data-extraction/src/getGlobal.ts",
    "content": "export function getGlobal(): any {\n\tif (typeof globalThis === \"object\") {\n\t\treturn globalThis;\n\t} else if (typeof global === \"object\") {\n\t\treturn global;\n\t} else if (typeof window === \"object\") {\n\t\treturn window;\n\t}\n\tthrow new Error(\"No global available\");\n}\n"
  },
  {
    "path": "data-extraction/src/index.ts",
    "content": "export * from \"./js\";\nexport * from \"./CommonDataTypes\";\nexport * from \"./DataExtractionResult\";\n"
  },
  {
    "path": "data-extraction/src/js/api/DataExtractorApi.ts",
    "content": "import { DataExtractionResult, VisualizationData } from \"../../DataExtractionResult\";\r\nimport { LoadDataExtractorsFn } from \"./LoadDataExtractorsFn\";\r\n\r\nexport interface DataExtractorApi {\r\n\t/**\r\n\t * Registers a single extractor.\r\n\t */\r\n\tregisterExtractor(extractor: DataExtractor): void;\r\n\r\n\t/**\r\n\t * Registers multiple extractors.\r\n\t */\r\n\tregisterExtractors(extractors: DataExtractor[]): void;\r\n\r\n\t/**\r\n\t * Extracts data from the result of `valueFn`.\r\n\t * @valueFn a function returning the value to extract the data from.\r\n\t * Is a function so that it's evaluation can depend on `evalFn`.\r\n\t */\r\n\tgetData(\r\n\t\tvalueFn: () => unknown,\r\n\t\tevalFn: <T>(expression: string) => T,\r\n\t\tpreferredDataExtractorId: string | undefined,\r\n\t\tvariablesInScope: Record<string, unknown>,\r\n\t\tcallFramesSnapshot: CallFramesSnapshot | null\r\n\t): JSONString<DataResult>;\r\n\r\n\t/**\r\n\t * Registers all default (built-in) extractors.\r\n\t * @preferExisting if `true`, existing extractors with the same id are not overwritten.\r\n\t */\r\n\tregisterDefaultExtractors(preferExisting?: boolean): void;\r\n\r\n\tsetDataExtractorFn(id: string, fn: LoadDataExtractorsFn | undefined): void;\r\n}\r\n\r\nexport type DataResult =\r\n\t| {\r\n\t\t\tkind: \"Data\";\r\n\t\t\textractionResult: DataExtractionResult;\r\n\t  }\r\n\t| { kind: \"NoExtractors\" }\r\n\t| { kind: \"Error\"; message: string }\r\n\t| {\r\n\t\t\tkind: \"OutdatedCallFrameSnapshot\";\r\n\t\t\tcallFramesRequest: CallFramesRequest;\r\n\t  };\r\n\r\nexport interface JSONString<T> extends String {\r\n\t__brand: { json: T };\r\n}\r\n\r\nexport interface CallFramesRequest {\r\n\trequestId: string;\r\n\trequestedCallFrames: CallFrameRequest[];\r\n}\r\n\r\nexport interface CallFrameRequest {\r\n\tmethodName: string;\r\n\tpathRegExp: string | undefined;\r\n}\r\n\r\nexport interface CallFramesSnapshot {\r\n\trequestId: string;\r\n\tframes: (CallFrameInfo | SkippedCallFrames)[];\r\n}\r\n\r\nexport interface SkippedCallFrames {\r\n\tskippedFrames: number;\r\n}\r\n\r\nexport interface CallFrameInfo {\r\n\tmethodName: string;\r\n\tsource: { name: string; path: string };\r\n\tvars: Record<string, any>;\r\n}\r\n\r\nexport interface DataExtractor {\r\n\t/**\r\n\t * Must be unique among all data extractors.\r\n\t */\r\n\tid: string;\r\n\r\n\t/**\r\n\t * Filters the data to be extracted.\r\n\t */\r\n\tdataCtor?: string;\r\n\tgetExtractions(data: unknown, extractionCollector: ExtractionCollector, context: DataExtractorContext): void;\r\n}\r\n\r\nexport interface ExtractionCollector {\r\n\t/**\r\n\t * Suggests a possible extraction.\r\n\t */\r\n\taddExtraction(extraction: DataExtraction): void;\r\n}\r\n\r\nexport interface DataExtractorContext {\r\n\t/**\r\n\t * Evaluates an expression in the context of the active stack frame.\r\n\t */\r\n\tevalFn: <TEval>(expression: string) => TEval;\r\n\r\n\treadonly expression: string | undefined;\r\n\r\n\treadonly variablesInScope: Record<string, () => unknown>;\r\n\r\n\textract(value: unknown): VisualizationData | undefined;\r\n\r\n\treadonly callFrameInfos: readonly (CallFrameInfo | SkippedCallFrames)[];\r\n\r\n\taddCallFrameRequest(request: CallFrameRequest): void;\r\n}\r\n\r\nexport interface DataExtraction {\r\n\t/**\r\n\t * Higher priorities are preferred.\r\n\t */\r\n\tpriority: number;\r\n\r\n\t/**\r\n\t * A unique id identifying this extraction among all extractions.\r\n\t * Required to express extraction preferences.\r\n\t */\r\n\tid?: string;\r\n\r\n\t/**\r\n\t * A user friendly name of this extraction.\r\n\t */\r\n\tname?: string;\r\n\r\n\textractData(): VisualizationData;\r\n}\r\n"
  },
  {
    "path": "data-extraction/src/js/api/DataExtractorApiImpl.ts",
    "content": "import {\r\n\tDataExtractorInfo,\r\n\tVisualizationData,\r\n} from \"../../DataExtractionResult\";\r\nimport * as helpers from \"../helpers\";\r\nimport {\r\n\tCallFrameInfo,\r\n\tCallFrameRequest,\r\n\tCallFramesSnapshot,\r\n\tDataExtraction,\r\n\tDataExtractor,\r\n\tDataExtractorApi,\r\n\tDataExtractorContext,\r\n\tDataResult,\r\n\tJSONString,\r\n\tSkippedCallFrames,\r\n} from \"./DataExtractorApi\";\r\nimport { LoadDataExtractorsFn } from \"./LoadDataExtractorsFn\";\r\nimport { registerDefaultExtractors } from \"./default-extractors\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class DataExtractorApiImpl implements DataExtractorApi {\r\n\tpublic static lastContext: DataExtractorContext | undefined = undefined;\r\n\r\n\tprivate readonly extractors = new Map<string, DataExtractor>();\r\n\tprivate readonly extractorSources = new Map<string, LoadDataExtractorsFn>();\r\n\r\n\tprivate toJson<TData>(data: TData): JSONString<TData> {\r\n\t\treturn JSON.stringify(data) as any;\r\n\t}\r\n\r\n\tpublic registerExtractor(extractor: DataExtractor): void {\r\n\t\tthis.extractors.set(extractor.id, extractor);\r\n\t}\r\n\r\n\tpublic registerExtractors(extractors: DataExtractor[]): void {\r\n\t\tfor (const e of extractors) {\r\n\t\t\tthis.registerExtractor(e);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic getData(\r\n\t\tvalueFn: () => unknown,\r\n\t\tevalFn: <T>(expression: string) => T,\r\n\t\tpreferredDataExtractorId: string | undefined,\r\n\t\tvariablesInScope: Record<string, () => unknown>,\r\n\t\tcallFramesSnapshot: CallFramesSnapshot | null\r\n\t): JSONString<DataResult> {\r\n\t\tconst callFrameRequests: CallFrameRequest[] = [];\r\n\t\tconst rootContext = new ContextImpl(\r\n\t\t\tvariablesInScope,\r\n\t\t\tremoveEnd(removeStart(valueFn.toString(), \"() => (\"), \")\").trim(),\r\n\t\t\tevalFn,\r\n\t\t\tthis,\r\n\t\t\tundefined,\r\n\t\t\tcallFramesSnapshot?.frames ?? [],\r\n\t\t\tcallFrameRequests\r\n\t\t);\r\n\r\n\t\tDataExtractorApiImpl.lastContext = rootContext;\r\n\t\tconst value = valueFn();\r\n\t\tconst extractions = this.getExtractions(value, rootContext);\r\n\t\tDataExtractorApiImpl.lastContext = undefined;\r\n\r\n\t\tconst requestId =\r\n\t\t\tcallFrameRequests.length === 0\r\n\t\t\t\t? \"\"\r\n\t\t\t\t: \"\" + cyrb53(JSON.stringify(callFrameRequests));\r\n\t\tif ((callFramesSnapshot?.requestId ?? \"\") !== requestId) {\r\n\t\t\treturn this.toJson({\r\n\t\t\t\tkind: \"OutdatedCallFrameSnapshot\",\r\n\t\t\t\tcallFramesRequest: {\r\n\t\t\t\t\trequestId,\r\n\t\t\t\t\trequestedCallFrames: callFrameRequests,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tlet usedExtraction = extractions[0];\r\n\t\tif (!usedExtraction) {\r\n\t\t\treturn this.toJson({ kind: \"NoExtractors\" } as DataResult);\r\n\t\t}\r\n\r\n\t\tif (preferredDataExtractorId) {\r\n\t\t\tconst preferred = extractions.find(\r\n\t\t\t\t(e) => e.id === preferredDataExtractorId\r\n\t\t\t);\r\n\t\t\tif (preferred) {\r\n\t\t\t\tusedExtraction = preferred;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tconst data = usedExtraction.extractData();\r\n\r\n\t\t\treturn this.toJson({\r\n\t\t\t\tkind: \"Data\",\r\n\t\t\t\textractionResult: {\r\n\t\t\t\t\tdata,\r\n\t\t\t\t\tusedExtractor: mapExtractor(usedExtraction),\r\n\t\t\t\t\tavailableExtractors: extractions.map(mapExtractor),\r\n\t\t\t\t},\r\n\t\t\t} as DataResult);\r\n\r\n\t\t} catch (e) {\r\n\t\t\treturn this.toJson({\r\n\t\t\t\tkind: \"Data\",\r\n\t\t\t\textractionResult: {\r\n\t\t\t\t\tdata: visualizeError(e),\r\n\t\t\t\t\tusedExtractor: mapExtractor(usedExtraction),\r\n\t\t\t\t\tavailableExtractors: extractions.map(mapExtractor),\r\n\t\t\t\t},\r\n\t\t\t} as DataResult);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic getExtractions(\r\n\t\tvalue: unknown,\r\n\t\tcontext: DataExtractorContext\r\n\t): DataExtraction[] {\r\n\t\tconst extractions = new Array<DataExtraction>();\r\n\t\tconst extractors = new Array<DataExtractor>();\r\n\r\n\t\tfor (const fn of this.extractorSources.values()) {\r\n\t\t\ttry {\r\n\t\t\t\tfn((extractor) => {\r\n\t\t\t\t\textractors.push(extractor);\r\n\t\t\t\t}, helpers);\r\n\t\t\t} catch (e) {\r\n\t\t\t\tconsole.error('Error in data extractor source', fn, e);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (const extractor of [...this.extractors.values(), ...extractors]) {\r\n\t\t\tif (extractor.dataCtor !== undefined) {\r\n\t\t\t\tif (\r\n\t\t\t\t\ttypeof value !== \"object\" ||\r\n\t\t\t\t\tvalue === null ||\r\n\t\t\t\t\tvalue.constructor.name !== extractor.dataCtor\r\n\t\t\t\t) {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\ttry {\r\n\t\t\t\textractor.getExtractions(\r\n\t\t\t\t\tvalue,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\taddExtraction(extraction) {\r\n\t\t\t\t\t\t\tif (extraction.id === undefined) {\r\n\t\t\t\t\t\t\t\textraction.id = extractor.id;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (extraction.name === undefined) {\r\n\t\t\t\t\t\t\t\textraction.name = extractor.id;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\textractions.push(extraction);\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t},\r\n\t\t\t\t\tcontext\r\n\t\t\t\t);\r\n\t\t\t} catch (e) {\r\n\t\t\t\textractions.push({\r\n\t\t\t\t\tid: extractor.id,\r\n\t\t\t\t\tname: extractor.id,\r\n\t\t\t\t\tpriority: 0,\r\n\t\t\t\t\textractData() {\r\n\t\t\t\t\t\treturn visualizeError(e);\r\n\t\t\t\t\t},\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t\textractions.sort((a, b) => b.priority - a.priority);\r\n\r\n\t\treturn extractions;\r\n\t}\r\n\r\n\tpublic registerDefaultExtractors(preferExisting: boolean = false): void {\r\n\t\t// TODO consider preferExisting\r\n\t\tregisterDefaultExtractors(this);\r\n\t}\r\n\r\n\tpublic setDataExtractorFn(\r\n\t\tid: string,\r\n\t\tfn: LoadDataExtractorsFn | undefined\r\n\t): void {\r\n\t\tif (fn) {\r\n\t\t\tthis.extractorSources.set(id, fn);\r\n\t\t} else {\r\n\t\t\tthis.extractorSources.delete(id);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction visualizeError(e: unknown | Error): VisualizationData {\r\n\treturn helpers.asData({\r\n\t\tkind: { text: true },\r\n\t\tfileName: 'error.md',\r\n\t\ttext: `# Error while running data extractor\\n\\n${formatErrorStr(e)}`,\r\n\t});\r\n}\r\n\r\nfunction formatErrorStr(e: unknown | Error): string {\r\n\tif (e instanceof Error) {\r\n\t\treturn `${e.message}\\n\\nStack:\\n${e.stack}`;\r\n\t}\r\n\treturn \"\" + e;\r\n}\r\n\r\nfunction mapExtractor(e: DataExtraction): DataExtractorInfo {\r\n\treturn {\r\n\t\tid: e.id! as any,\r\n\t\tname: e.name!,\r\n\t\tpriority: e.priority,\r\n\t};\r\n}\r\n\r\nclass ContextImpl implements DataExtractorContext {\r\n\tconstructor(\r\n\t\tpublic readonly variablesInScope: Record<string, () => unknown>,\r\n\t\tpublic readonly expression: string | undefined,\r\n\t\tpublic readonly evalFn: <T>(expression: string) => T,\r\n\t\tprivate readonly _api: DataExtractorApiImpl,\r\n\t\tprivate readonly _parent: ContextImpl | undefined,\r\n\t\tpublic readonly callFrameInfos: readonly (\r\n\t\t\t| CallFrameInfo\r\n\t\t\t| SkippedCallFrames\r\n\t\t)[],\r\n\t\tprivate readonly _callFrameRequests: CallFrameRequest[]\r\n\t) { }\r\n\r\n\taddCallFrameRequest(request: CallFrameRequest): void {\r\n\t\tthis._callFrameRequests.push(request);\r\n\t}\r\n\r\n\tget _level(): number {\r\n\t\treturn this._parent ? this._parent._level + 1 : 0;\r\n\t}\r\n\r\n\textract(value: any): VisualizationData | undefined {\r\n\t\tif (this._level > 10) {\r\n\t\t\tthrow new Error(\"extract() called too many times recursively\");\r\n\t\t}\r\n\r\n\t\tconst extractions = this._api.getExtractions(\r\n\t\t\tvalue,\r\n\t\t\tnew ContextImpl(\r\n\t\t\t\tthis.variablesInScope,\r\n\t\t\t\tundefined,\r\n\t\t\t\tthis.evalFn,\r\n\t\t\t\tthis._api,\r\n\t\t\t\tthis,\r\n\t\t\t\tthis.callFrameInfos,\r\n\t\t\t\tthis._callFrameRequests\r\n\t\t\t)\r\n\t\t);\r\n\t\tif (extractions.length === 0) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\treturn extractions[0].extractData();\r\n\t}\r\n}\r\n\r\nfunction removeStart(str: string, start: string): string {\r\n\tif (str.startsWith(start)) {\r\n\t\treturn str.substr(start.length);\r\n\t}\r\n\treturn str;\r\n}\r\n\r\nfunction removeEnd(str: string, end: string): string {\r\n\tif (str.endsWith(end)) {\r\n\t\treturn str.substr(0, str.length - end.length);\r\n\t}\r\n\treturn str;\r\n}\r\n\r\n// From https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript\r\nfunction cyrb53(str: string, seed = 0) {\r\n\tlet h1 = 0xdeadbeef ^ seed,\r\n\t\th2 = 0x41c6ce57 ^ seed;\r\n\tfor (let i = 0, ch; i < str.length; i++) {\r\n\t\tch = str.charCodeAt(i);\r\n\t\th1 = Math.imul(h1 ^ ch, 2654435761);\r\n\t\th2 = Math.imul(h2 ^ ch, 1597334677);\r\n\t}\r\n\th1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);\r\n\th1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);\r\n\th2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);\r\n\th2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);\r\n\r\n\treturn 4294967296 * (2097151 & h2) + (h1 >>> 0);\r\n}\r\n"
  },
  {
    "path": "data-extraction/src/js/api/LoadDataExtractorsFn.ts",
    "content": "import { DataExtractor } from \"./DataExtractorApi\";\nimport type * as helpersTypes from \"../helpers\"\n\nexport type LoadDataExtractorsFn = (\n\tregister: (extractor: DataExtractor) => void,\n    helpers: typeof helpersTypes\n) => void;\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/AsIsDataExtractor.ts",
    "content": "import { isVisualizationData } from \"../../../DataExtractionResult\";\nimport {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../..\";\n\nexport class AsIsDataExtractor implements DataExtractor {\n\treadonly id = \"as-is\";\n\tgetExtractions(\n\t\tdata: unknown,\n\t\textractionCollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tif (!isVisualizationData(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\textractionCollector.addExtraction({\n\t\t\tid: this.id,\n\t\t\tname: \"As Is\",\n\t\t\tpriority: 500,\n\t\t\textractData() {\n\t\t\t\treturn data;\n\t\t\t},\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/GetDebugVisualizationDataExtractor.ts",
    "content": "import { VisualizationData } from \"../../../DataExtractionResult\";\nimport {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../DataExtractorApi\";\n\nexport class GetVisualizationDataExtractor implements DataExtractor {\n\treadonly id = \"get-visualization-data\";\n\tgetExtractions(\n\t\tdata: unknown,\n\t\tcollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tif (typeof data !== \"object\" || !data) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst getVisualizationData = (data as any)\n\t\t\t.getVisualizationData as Function;\n\t\tif (typeof getVisualizationData !== \"function\") {\n\t\t\treturn;\n\t\t}\n\n\t\tcollector.addExtraction({\n\t\t\tid: this.id,\n\t\t\tname: \"Use Method 'getVisualizationData'\",\n\t\t\tpriority: 600,\n\t\t\textractData() {\n\t\t\t\treturn getVisualizationData.apply(data);\n\t\t\t},\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/GridExtractor.ts",
    "content": "import {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../..\";\nimport { GridVisualizationData } from \"../../../CommonDataTypes\";\nimport { expect } from \"../../../util\";\n\nexport class GridExtractor implements DataExtractor {\n\treadonly id = \"grid\";\n\tgetExtractions(\n\t\tdata: unknown,\n\t\textractionCollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tif (!Array.isArray(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\textractionCollector.addExtraction({\n\t\t\tid: this.id,\n\t\t\tname: \"Array As Grid\",\n\t\t\tpriority: 500,\n\t\t\textractData: () =>\n\t\t\t\texpect<GridVisualizationData>({\n\t\t\t\t\tkind: { grid: true },\n\t\t\t\t\trows: [{ columns: data.map(d => ({ tag: \"\" + d })) }],\n\t\t\t\t}),\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/MarkedGridExtractor.ts",
    "content": "import { DataExtractor, ExtractionCollector, DataExtractorContext } from \"..\";\r\nimport { LineColumnRange } from \"../../../CommonDataTypes\";\r\nimport { asData, markedGrid, tryEval } from \"../../helpers\";\r\n\r\nexport class MarkedGridFromArrayExtractor implements DataExtractor {\r\n\treadonly id = \"markedGridFromArray\";\r\n\tgetExtractions(\r\n\t\tdata: unknown,\r\n\t\tcollector: ExtractionCollector,\r\n\t\tcontext: DataExtractorContext\r\n\t): void {\r\n\t\tif (!Array.isArray(data)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!Array.isArray(data[0])) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet markers: any;\r\n\t\tif (data.length === 2 && typeof data[1] === \"object\") {\r\n\t\t\tmarkers = data[1];\r\n\t\t} else {\r\n\t\t\tfor (let i = 1; i < data.length; i++) {\r\n\t\t\t\tif (typeof data[i] !== \"string\") {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tmarkers = tryEval(data.slice(1));\r\n\t\t}\r\n\r\n\t\tcollector.addExtraction({\r\n\t\t\tid: \"markedGridFromArray\",\r\n\t\t\tname: \"Marked Grid from Array\",\r\n\t\t\tpriority: 1000,\r\n\t\t\textractData() {\r\n\t\t\t\treturn markedGrid(data[0], markers as any);\r\n\t\t\t},\r\n\t\t});\r\n\t}\r\n}\r\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/ObjectGraphExtractor.ts",
    "content": "import { VisualizationData } from \"../../../DataExtractionResult\";\nimport {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../DataExtractorApi\";\nimport {\n\tcreateGraph,\n\tCreateGraphEdge,\n\tcreateGraphFromPointers,\n} from \"../../helpers\";\nimport { GraphNode } from \"../../..\";\n\nexport class ObjectGraphExtractor implements DataExtractor {\n\treadonly id = \"object-graph\";\n\n\tgetExtractions(\n\t\tdata: unknown,\n\t\tcollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tfunction isObject(val: unknown): val is object {\n\t\t\tif (typeof val !== \"object\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!val) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tif (!isObject(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst infoSelector: (item: object) => {\n\t\t\tid?: string | number;\n\t\t\tedges: CreateGraphEdge<object>[];\n\t\t} & Omit<GraphNode, \"id\"> = (item) => {\n\t\t\tlet label = \"\";\n\t\t\tconst edges = new Array<CreateGraphEdge<any>>();\n\t\t\tif (item instanceof Set) {\n\t\t\t\tlabel = \"Set\";\n\t\t\t\tfor (const value of item.values()) {\n\t\t\t\t\tif (isObject(value)) {\n\t\t\t\t\t\tedges.push({ label: \"item\", to: value });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (item instanceof Map) {\n\t\t\t\tlabel = \"Map\";\n\t\t\t\tfor (const [key, value] of item.entries()) {\n\t\t\t\t\tif (isObject(value)) {\n\t\t\t\t\t\tedges.push({ label: key, to: value });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const [key, val] of Object.entries(item)) {\n\t\t\t\t\tif (isObject(val)) {\n\t\t\t\t\t\tedges.push({ label: key, to: val });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst className = item.constructor\n\t\t\t\t\t? item.constructor.name\n\t\t\t\t\t: \"?\";\n\t\t\t\tlabel = className;\n\t\t\t\tif (!Array.isArray(item)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlet toStrVal = item.toString();\n\t\t\t\t\t\tif (toStrVal !== \"[object Object]\") {\n\t\t\t\t\t\t\tif (toStrVal.length > 15) {\n\t\t\t\t\t\t\t\ttoStrVal += ` \"${toStrVal.substr(0, 15)}...\"`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlabel += `${className}: ${toStrVal}`;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tshape: \"box\",\n\t\t\t\tedges,\n\t\t\t\tcolor: item === data ? \"lightblue\" : undefined,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t};\n\n\t\tcollector.addExtraction({\n\t\t\tid: \"object-graph\",\n\t\t\tname: \"Object Graph\",\n\t\t\tpriority: 98,\n\t\t\textractData() {\n\t\t\t\treturn createGraph([data], infoSelector, { maxSize: 50 });\n\t\t\t},\n\t\t});\n\n\t\tif (\n\t\t\tdata.constructor === Object &&\n\t\t\tObject.values(data).every(\n\t\t\t\t(v) => v === undefined || v === null || typeof v === \"object\"\n\t\t\t)\n\t\t) {\n\t\t\tcollector.addExtraction({\n\t\t\t\tid: \"object-graph-pointers\",\n\t\t\t\tname: \"Object Graph With Pointers\",\n\t\t\t\tpriority: 99,\n\t\t\t\textractData() {\n\t\t\t\t\treturn createGraphFromPointers(data as any, infoSelector, {\n\t\t\t\t\t\tmaxSize: 50,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/PlotlyDataExtractor.ts",
    "content": "import { PlotlyVisualizationData } from \"../../../CommonDataTypes\";\nimport { expect } from \"../../../util\";\nimport {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../DataExtractorApi\";\n\nexport class PlotlyDataExtractor implements DataExtractor {\n\treadonly id = \"plot\";\n\n\tgetExtractions(\n\t\tdata: unknown,\n\t\tcollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tif (!Array.isArray(data)) {\n\t\t\treturn;\n\t\t}\n\t\tif (data.some(x => typeof x !== \"number\")) {\n\t\t\treturn;\n\t\t}\n\n\t\tcollector.addExtraction({\n\t\t\tid: \"plot-y\",\n\t\t\tname: \"Plot as y-Values\",\n\t\t\tpriority: 1001,\n\t\t\textractData: () =>\n\t\t\t\texpect<PlotlyVisualizationData>({\n\t\t\t\t\tkind: {\n\t\t\t\t\t\tplotly: true,\n\t\t\t\t\t},\n\t\t\t\t\tdata: [{ y: data }],\n\t\t\t\t}),\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/StringDiffExtractor.ts",
    "content": "import {\r\n\tDataExtractor,\r\n\tDataExtractorContext,\r\n\tExtractionCollector,\r\n} from \"../..\";\r\n\r\nexport class StringDiffExtractor implements DataExtractor {\r\n\tpublic readonly id = \"string-diff\";\r\n\r\n\tpublic getExtractions(\r\n\t\tdata: unknown,\r\n\t\tcollector: ExtractionCollector,\r\n\t\tcontext: DataExtractorContext\r\n\t) {\r\n\t\tif (\r\n\t\t\tArray.isArray(data) &&\r\n\t\t\tdata.length === 2 &&\r\n\t\t\ttypeof data[0] === \"string\" &&\r\n\t\t\ttypeof data[1] === \"string\"\r\n\t\t) {\r\n\t\t\tcollector.addExtraction({\r\n\t\t\t\tid: \"string-diff\",\r\n\t\t\t\tname: \"String Diff\",\r\n\t\t\t\tpriority: 1300,\r\n\t\t\t\textractData: () => ({\r\n\t\t\t\t\tkind: { text: true },\r\n\t\t\t\t\ttext: data[0],\r\n\t\t\t\t\totherText: data[1],\r\n\t\t\t\t}),\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/StringRangeExtractor.ts",
    "content": "import { DataExtractor, ExtractionCollector, DataExtractorContext } from \"..\";\r\nimport { LineColumnRange } from \"../../../CommonDataTypes\";\r\nimport { asData } from \"../../helpers\";\r\n\r\nexport class StringRangeExtractor implements DataExtractor {\r\n\treadonly id = \"stringRange\";\r\n\tgetExtractions(\r\n\t\tdata: unknown,\r\n\t\tcollector: ExtractionCollector,\r\n\t\tcontext: DataExtractorContext\r\n\t): void {\r\n\t\tif (!Array.isArray(data)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (typeof data[0] !== \"string\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst text = data[0];\r\n\r\n\t\tconst decorations1: { range: LineColumnRange; label?: string }[] = [];\r\n\t\tconst decorations2: { range: LineColumnRange; label?: string }[] = [];\r\n\r\n\t\tfunction offsetToLineColumn(offset: number) {\r\n\t\t\tlet line = 0;\r\n\t\t\tlet column = 0;\r\n\t\t\tfor (let idx = 0; idx < text.length; idx++) {\r\n\t\t\t\tif (idx === offset) {\r\n\t\t\t\t\treturn { line, column };\r\n\t\t\t\t}\r\n\t\t\t\tif (text[idx] === \"\\n\") {\r\n\t\t\t\t\tline++;\r\n\t\t\t\t\tcolumn = 0;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tcolumn++;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn { line, column }; // TODO\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\tdata.length === 2 &&\r\n\t\t\ttypeof data[1] === \"object\" &&\r\n\t\t\t!Array.isArray(data[1])\r\n\t\t) {\r\n\t\t\tdata = [data[0], ...Object.values(data[1])] as [\r\n\t\t\t\tnumber | [number, number]\r\n\t\t\t][];\r\n\t\t}\r\n\r\n\t\tfor (let item of (data as (number | [number, number])[]).slice(1)) {\r\n\t\t\tif (typeof item === \"string\") {\r\n\t\t\t\ttry {\r\n\t\t\t\t\titem = context.evalFn(item);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tif (item === undefined) {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (typeof item === \"number\") {\r\n\t\t\t\tconst pos = offsetToLineColumn(item);\r\n\t\t\t\tdecorations1.push({ range: { start: pos, end: pos } });\r\n\t\t\t\tdecorations2.push({\r\n\t\t\t\t\trange: {\r\n\t\t\t\t\t\tstart: pos,\r\n\t\t\t\t\t\tend: { line: pos.line, column: pos.column + 1 },\r\n\t\t\t\t\t},\r\n\t\t\t\t});\r\n\t\t\t} else if (\r\n\t\t\t\tArray.isArray(item) &&\r\n\t\t\t\titem.length === 2 &&\r\n\t\t\t\ttypeof item[0] === \"number\" &&\r\n\t\t\t\ttypeof item[1] === \"number\"\r\n\t\t\t) {\r\n\t\t\t\tdecorations1.push({\r\n\t\t\t\t\trange: {\r\n\t\t\t\t\t\tstart: offsetToLineColumn(item[0]),\r\n\t\t\t\t\t\tend: offsetToLineColumn(item[1]),\r\n\t\t\t\t\t},\r\n\t\t\t\t});\r\n\t\t\t\tdecorations2.push(decorations1[decorations1.length - 1]);\r\n\t\t\t} else {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcollector.addExtraction({\r\n\t\t\tpriority: 1200,\r\n\t\t\tid: \"stringRange\",\r\n\t\t\tname: \"String Range\",\r\n\t\t\textractData() {\r\n\t\t\t\treturn asData({\r\n\t\t\t\t\tkind: { text: true },\r\n\t\t\t\t\ttext,\r\n\t\t\t\t\tdecorations: decorations1,\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t});\r\n\r\n\t\tcollector.addExtraction({\r\n\t\t\tpriority: 1000,\r\n\t\t\tid: \"stringRangeFullCharacters\",\r\n\t\t\tname: \"String Range (Full Character)\",\r\n\t\t\textractData() {\r\n\t\t\t\treturn asData({\r\n\t\t\t\t\tkind: { text: true },\r\n\t\t\t\t\ttext,\r\n\t\t\t\t\tdecorations: decorations2,\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t});\r\n\t}\r\n}\r\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/TableExtractor.ts",
    "content": "import { isAssertionExpression } from \"typescript\";\nimport { DataExtractor, ExtractionCollector, DataExtractorContext } from \"..\";\nimport { TableVisualizationData } from \"../../../CommonDataTypes\";\nimport { expect } from \"../../../util\";\n\nfunction assert<T>(value: unknown): asserts value {}\n\nexport class TableDataExtractor implements DataExtractor {\n\treadonly id = \"table\";\n\n\tgetExtractions(\n\t\tdata: unknown,\n\t\tcollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tif (!Array.isArray(data)) {\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\t!data.every((d) => typeof d === \"object\" && d && !Array.isArray(d))\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tassert<object[]>(data);\n\n\t\tcollector.addExtraction({\n\t\t\tid: \"table\",\n\t\t\tname: \"Table\",\n\t\t\tpriority: 1000,\n\t\t\textractData() {\n\t\t\t\treturn expect<TableVisualizationData>({\n\t\t\t\t\tkind: {\n\t\t\t\t\t\ttable: true,\n\t\t\t\t\t},\n\t\t\t\t\trows: data,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tcollector.addExtraction({\n\t\t\tid: \"table-with-type-name\",\n\t\t\tname: \"Table (With Type Name)\",\n\t\t\tpriority: 950,\n\t\t\textractData() {\n\t\t\t\treturn expect<TableVisualizationData>({\n\t\t\t\t\tkind: {\n\t\t\t\t\t\ttable: true,\n\t\t\t\t\t},\n\t\t\t\t\trows: data.map((d) => ({ type: d.constructor.name, ...d })),\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/ToStringExtractor.ts",
    "content": "import { MonacoTextVisualizationData } from \"../../../CommonDataTypes\";\nimport { expect } from \"../../../util\";\nimport {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../DataExtractorApi\";\n\nexport class ToStringDataExtractor implements DataExtractor {\n\treadonly id = \"to-string\";\n\n\tgetExtractions(\n\t\tdata: unknown,\n\t\tcollector: ExtractionCollector,\n\t\tcontext: DataExtractorContext\n\t): void {\n\t\tcollector.addExtraction({\n\t\t\tid: \"to-string\",\n\t\t\tname: \"To String\",\n\t\t\tpriority: 100,\n\t\t\textractData() {\n\t\t\t\treturn expect<MonacoTextVisualizationData>({\n\t\t\t\t\tkind: {\n\t\t\t\t\t\ttext: true,\n\t\t\t\t\t},\n\t\t\t\t\ttext: \"\" + data,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/TypeScriptDataExtractors.ts",
    "content": "import * as ts from \"typescript\"; // Only compile-time import!\nimport { AstTreeNode } from \"../../..\";\nimport { AstTreeVisualizationData } from \"../../../CommonDataTypes\";\nimport { expect } from \"../../../util\";\nimport {\n\tDataExtractor,\n\tExtractionCollector,\n\tDataExtractorContext,\n} from \"../DataExtractorApi\";\n\nexport class TypeScriptAstDataExtractor implements DataExtractor {\n\treadonly id = \"typescript-ast\";\n\n\tgetExtractions(\n\t\tdata: unknown,\n\t\tcollector: ExtractionCollector,\n\t\t{ evalFn }: DataExtractorContext\n\t): void {\n\t\tif (!data) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction getApi(): typeof ts {\n\t\t\tif (typeof data === \"object\" && \"typescript\" in (data as object)) {\n\t\t\t\treturn (data as any).typescript;\n\t\t\t} else {\n\t\t\t\t// This might refer to global.require which uses CWD for resolution!\n\t\t\t\tconst require = evalFn<(request: string) => unknown>(\"require\");\n\t\t\t\treturn require(\"typescript\") as typeof ts;\n\t\t\t}\n\t\t}\n\n\t\tlet tsApi: typeof ts;\n\t\ttry {\n\t\t\ttsApi = getApi();\n\t\t\tif (!tsApi) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst helper = new Helper(tsApi);\n\n\t\tlet rootSourceFile: ts.SourceFile | undefined = undefined;\n\t\tlet rootNode: ts.Node | undefined = undefined;\n\t\tlet marked: Set<ts.Node>;\n\t\tlet fn: (n: ts.Node) => string | undefined = (n: ts.Node) => undefined;\n\t\tif (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.every(helper.isNode) &&\n\t\t\tdata.length > 0\n\t\t) {\n\t\t\trootSourceFile = helper.getSourceFile(data[0] as ts.Node);\n\t\t\tmarked = new Set(data);\n\t\t} else if (helper.isNode(data)) {\n\t\t\trootSourceFile = helper.getSourceFile(data);\n\t\t\tmarked = new Set([data]);\n\t\t} else if (typeof data === \"object\" && data) {\n\t\t\tmarked = new Set();\n\t\t\tconst map = new Map<ts.Node, string>();\n\t\t\tfn = (n: ts.Node) => map.get(n);\n\t\t\tfor (const [key, item] of Object.entries(data)) {\n\t\t\t\tif (key === \"fn\") {\n\t\t\t\t\tfn = item;\n\t\t\t\t} else if (key === \"typescript\") {\n\t\t\t\t} else {\n\t\t\t\t\tif (key === \"rootNode\") {\n\t\t\t\t\t\trootNode = item;\n\t\t\t\t\t}\n\t\t\t\t\tlet nodes: Array<ts.Node>;\n\t\t\t\t\tif (helper.isNode(item)) {\n\t\t\t\t\t\tnodes = [item];\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tArray.isArray(item) &&\n\t\t\t\t\t\titem.every(helper.isNode)\n\t\t\t\t\t) {\n\t\t\t\t\t\tnodes = item;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (nodes.length > 0 && !rootSourceFile) {\n\t\t\t\t\t\trootSourceFile = helper.getSourceFile(nodes[0]);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\t\tmarked.add(n);\n\t\t\t\t\t\tmap.set(n, key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!rootSourceFile) {\n\t\t\treturn;\n\t\t}\n\t\tconst finalRootSourceFile = rootSourceFile;\n\n\t\tcollector.addExtraction({\n\t\t\tid: \"ts-ast\",\n\t\t\tname: \"TypeScript AST\",\n\t\t\tpriority: 1000,\n\t\t\textractData() {\n\t\t\t\treturn expect<AstTreeVisualizationData>({\n\t\t\t\t\tkind: { text: true, tree: true, ast: true },\n\t\t\t\t\troot: helper.toTreeNode(\n\t\t\t\t\t\trootNode || finalRootSourceFile,\n\t\t\t\t\t\t\"root\",\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\tmarked,\n\t\t\t\t\t\tfn\n\t\t\t\t\t),\n\t\t\t\t\ttext: finalRootSourceFile.text,\n\t\t\t\t\tfileName: \"index.ts\",\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}\n}\n\nclass Helper {\n\tconstructor(private readonly tsApi: typeof ts) {}\n\n\tgetPropertyNameInParent(value: any, parent: any): string | undefined {\n\t\tfor (const propertyName in parent) {\n\t\t\tif (propertyName.startsWith(\"_\")) continue;\n\n\t\t\tconst member = parent[propertyName];\n\t\t\tif (member === value) {\n\t\t\t\treturn propertyName;\n\t\t\t}\n\n\t\t\tif (Array.isArray(member)) {\n\t\t\t\tconst index = member.indexOf(value);\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\treturn `${propertyName}[${index}]`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tgetChildren(node: ts.Node): ts.Node[] {\n\t\tconst result = new Array<ts.Node>();\n\t\tthis.tsApi.forEachChild(node, n => {\n\t\t\tresult.push(n);\n\t\t});\n\t\treturn result;\n\t}\n\n\ttoTreeNode(\n\t\tnode: ts.Node,\n\t\tmemberName: string,\n\t\tsegmentName: string,\n\t\tmarked: Set<ts.Node>,\n\t\temphasizedValueFn: (node: ts.Node) => string | undefined\n\t): AstTreeNode {\n\t\tconst name = this.tsApi.SyntaxKind[node.kind];\n\t\tconst children = this.getChildren(node)\n\t\t\t.map((childNode, idx) => {\n\t\t\t\tlet parentPropertyName =\n\t\t\t\t\tthis.getPropertyNameInParent(childNode, node) || \"\";\n\n\t\t\t\tif (childNode.kind == this.tsApi.SyntaxKind.SyntaxList) {\n\t\t\t\t\tconst children = this.getChildren(childNode);\n\t\t\t\t\tfor (const c of children) {\n\t\t\t\t\t\tconst name =\n\t\t\t\t\t\t\tthis.getPropertyNameInParent(c, node) || \"\";\n\t\t\t\t\t\tif (name) {\n\t\t\t\t\t\t\tparentPropertyName = name;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet segmentName = \".\" + parentPropertyName;\n\t\t\t\tif (node.kind == this.tsApi.SyntaxKind.SyntaxList) {\n\t\t\t\t\tparentPropertyName = \"\" + idx;\n\t\t\t\t\tsegmentName = `[${idx}]`;\n\t\t\t\t}\n\n\t\t\t\treturn this.toTreeNode(\n\t\t\t\t\tchildNode,\n\t\t\t\t\tparentPropertyName,\n\t\t\t\t\tsegmentName,\n\t\t\t\t\tmarked,\n\t\t\t\t\temphasizedValueFn\n\t\t\t\t);\n\t\t\t})\n\t\t\t.filter(c => c !== null);\n\n\t\tlet value: string | undefined = undefined;\n\n\t\tif (this.tsApi.isIdentifier(node)) {\n\t\t\tvalue = node.text || (node.escapedText as string);\n\t\t} else if (this.tsApi.isLiteralExpression(node)) {\n\t\t\tvalue = node.text;\n\t\t}\n\n\t\tconst items: AstTreeNode[\"items\"] = [\n\t\t\t{ text: `${memberName}: `, emphasis: \"style1\" },\n\t\t\t{ text: name },\n\t\t];\n\n\t\tconst emphasizedVal = emphasizedValueFn(node);\n\t\tif (value) {\n\t\t\titems.push({ text: value, emphasis: \"style2\" });\n\t\t}\n\t\tif (emphasizedVal) {\n\t\t\titems.push({ text: emphasizedVal, emphasis: \"style3\" });\n\t\t}\n\n\t\treturn {\n\t\t\titems,\n\t\t\tchildren: children,\n\t\t\tsegment: segmentName,\n\t\t\tspan: {\n\t\t\t\tlength: node.end - node.pos,\n\t\t\t\tstart: node.pos,\n\t\t\t},\n\t\t\tisMarked: marked.has(node),\n\t\t};\n\t}\n\n\tisNode = (node: unknown): node is ts.Node => {\n\t\treturn (\n\t\t\ttypeof node === \"object\" &&\n\t\t\tnode !== null &&\n\t\t\t(this.tsApi.isToken(node as any) ||\n\t\t\t\t(this.tsApi as any).isNode(node))\n\t\t);\n\t};\n\n\tgetSourceFile(node: ts.Node | any): ts.SourceFile {\n\t\tif (!node) {\n\t\t\tthrow new Error(\"Detached node\");\n\t\t}\n\t\tif (this.tsApi.isSourceFile(node)) {\n\t\t\treturn node;\n\t\t}\n\t\tif (!(\"getSourceFile\" in node)) {\n\t\t\treturn this.getSourceFile(node.parent);\n\t\t}\n\t\treturn node.getSourceFile();\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/index.ts",
    "content": "export { registerDefaultExtractors } from \"./registerDefaultDataExtractors\";\n"
  },
  {
    "path": "data-extraction/src/js/api/default-extractors/registerDefaultDataExtractors.ts",
    "content": "import { DataExtractorApi } from \"../DataExtractorApi\";\nimport { TypeScriptAstDataExtractor } from \"./TypeScriptDataExtractors\";\nimport { AsIsDataExtractor } from \"./AsIsDataExtractor\";\nimport { GetVisualizationDataExtractor } from \"./GetDebugVisualizationDataExtractor\";\nimport { ToStringDataExtractor } from \"./ToStringExtractor\";\nimport { PlotlyDataExtractor } from \"./PlotlyDataExtractor\";\nimport { ObjectGraphExtractor } from \"./ObjectGraphExtractor\";\nimport { getDataExtractorApi } from \"../injection\";\nimport { GridExtractor } from \"./GridExtractor\";\nimport { TableDataExtractor } from \"./TableExtractor\";\nimport { StringDiffExtractor } from \"./StringDiffExtractor\";\nimport { StringRangeExtractor } from \"./StringRangeExtractor\";\nimport { MarkedGridFromArrayExtractor } from \"./MarkedGridExtractor\";\n\n/**\n * The default data extractors should be registered by VS Code automatically.\n * Registering them manually ensures that they are up to date.\n */\nexport function registerDefaultExtractors(\n\tapi: DataExtractorApi = getDataExtractorApi()\n) {\n\tfor (const item of [\n\t\tnew TypeScriptAstDataExtractor(),\n\t\tnew AsIsDataExtractor(),\n\t\tnew GetVisualizationDataExtractor(),\n\t\tnew ToStringDataExtractor(),\n\t\tnew PlotlyDataExtractor(),\n\t\tnew ObjectGraphExtractor(),\n\t\tnew GridExtractor(),\n\t\tnew TableDataExtractor(),\n\t\tnew StringDiffExtractor(),\n\t\tnew StringRangeExtractor(),\n\t\tnew MarkedGridFromArrayExtractor(),\n\t]) {\n\t\tapi.registerExtractor(item);\n\t}\n}\n"
  },
  {
    "path": "data-extraction/src/js/api/index.ts",
    "content": "export * from \"./DataExtractorApi\";\nexport * from \"./injection\";\nexport { DataExtractorApiImpl } from \"./DataExtractorApiImpl\";\nexport * from \"./LoadDataExtractorsFn\";\n"
  },
  {
    "path": "data-extraction/src/js/api/injection.ts",
    "content": "import * as fs from \"fs\";\nimport { getGlobal } from \"../../getGlobal\";\nimport * as globalHelpers from \"../global-helpers\";\nimport * as helpers from \"../helpers\";\nimport { DataExtractorApi } from \"./DataExtractorApi\";\nimport { DataExtractorApiImpl } from \"./DataExtractorApiImpl\";\n\n/**\n * Returns standalone JS code representing an expression that initializes the data extraction API.\n * This expression returns nothing.\n * This function is called in the VS Code extension, the expression is evaluated in the debugee.\n */\nexport function getExpressionToInitializeDataExtractorApi(): string {\n\tconst _fs = require(\"fs\") as typeof fs;\n\tconst moduleSrc = _fs.readFileSync(__filename, { encoding: \"utf8\" });\n\treturn `((function () {\n\t\tlet module = {};\n\t\t${moduleSrc}\n\t\treturn module.exports.getDataExtractorApi();\n\t})())`;\n}\n\n/**\n * Returns standalone JS code representing an expression that returns the data extraction API.\n * This expression returns an object of type `DataExtractorApi`.\n * This function is called in the VS Code extension, the expression is evaluated in the debugee.\n */\nexport function getExpressionForDataExtractorApi(): string {\n\treturn `((${selfContainedGetInitializedDataExtractorApi.toString()})())`;\n}\n\nconst apiKey = \"@hediet/data-extractor-api/v3\";\n\nexport function getDataExtractorApi(): DataExtractorApi {\n\tinstallHelpers();\n\tconst globalObj = getGlobal();\n\tif (!globalObj[apiKey]) {\n\t\tglobalObj[apiKey] = new DataExtractorApiImpl();\n\t}\n\treturn globalObj[apiKey];\n}\n\n/**\n * This code is used to detect if the API has not been initialized yet.\n * @internal\n */\n export const ApiHasNotBeenInitializedCode = \"EgH0cybXij1jYUozyakO\" as const;\n\n /**\n  * @internal\n  */\n function selfContainedGetInitializedDataExtractorApi(): DataExtractorApi {\n\tfunction getGlobal(): any {\n\t\tif (typeof globalThis === \"object\") {\n\t\t\treturn globalThis;\n\t\t} else if (typeof global === \"object\") {\n\t\t\treturn global;\n\t\t} else if (typeof window === \"object\") {\n\t\t\treturn window;\n\t\t}\n\t\tthrow new Error(\"No global available\");\n\t}\n\n\t const globalObj = getGlobal();\n\t const key: typeof apiKey = \"@hediet/data-extractor-api/v3\";\n\t let api: DataExtractorApi | undefined = globalObj[key];\n\t if (!api) {\n\t\t const code: typeof ApiHasNotBeenInitializedCode =\n\t\t\t \"EgH0cybXij1jYUozyakO\";\n\t\t throw new Error(\n\t\t\t `Data Extractor API has not been initialized. Code: ${code}`\n\t\t );\n\t }\n\t return api;\n }\n\nexport function installHelpers(): void {\n\tconst globalObj = getGlobal();\n\t// `hediet` as prefix to avoid name collision (I own `hediet.de`).\n\tglobalObj[\"hedietDbgVis\"] = { ...helpers, ...globalHelpers };\n}\n"
  },
  {
    "path": "data-extraction/src/js/global-helpers.ts",
    "content": "export { getDataExtractorApi as getApi } from \"./api/injection\";\n"
  },
  {
    "path": "data-extraction/src/js/helpers/asData.ts",
    "content": "import { KnownVisualizationData } from \"../../CommonDataTypes\";\nimport { VisualizationData } from \"../../DataExtractionResult\";\n\nexport function asData(data: KnownVisualizationData): VisualizationData {\n\treturn data;\n}\n"
  },
  {
    "path": "data-extraction/src/js/helpers/cache.ts",
    "content": "import { DataExtractorApiImpl } from \"../api\";\n\nconst cached = new Map<string, any>();\n\n/**\n * Evaluates an expression\n */\nexport function cache<T>(\n\texpression: string | (() => T),\n\tid: string | number | undefined = undefined\n): T {\n\tlet resultFn: () => any;\n\tlet key: string;\n\tif (typeof expression === \"string\") {\n\t\tconst context = DataExtractorApiImpl.lastContext!;\n\t\tresultFn = () => context.evalFn(expression);\n\t\tkey = JSON.stringify({ expr: expression, id });\n\t} else {\n\t\tresultFn = () => expression();\n\t\tkey = JSON.stringify({ expr: expression.toString(), id });\n\t}\n\n\tif (cached.has(key)) {\n\t\treturn cached.get(key);\n\t}\n\n\tconst result = resultFn();\n\tcached.set(key, result);\n\n\treturn result;\n}\n"
  },
  {
    "path": "data-extraction/src/js/helpers/createGraph.ts",
    "content": "import {\n\tGraphEdge,\n\tGraphNode,\n\tGraphVisualizationData,\n} from \"../../CommonDataTypes\";\n\nexport type CreateGraphEdge<T> = ({ to: T } | { from: T } | { include: T }) &\n\tOmit<GraphEdge, \"from\" | \"to\">;\n\n/**\n * Given a list of roots, it creates a graph by following their edges recursively.\n * Tracks cycles.\n */\nexport function createGraph<T>(\n\troots: T[],\n\tinfoSelector: (\n\t\titem: T\n\t) => {\n\t\tid?: string | number;\n\t\tedges: CreateGraphEdge<T>[];\n\t} & Omit<GraphNode, \"id\">,\n\toptions: { maxSize?: number } = {}\n): GraphVisualizationData {\n\tconst r: GraphVisualizationData = {\n\t\tkind: {\n\t\t\tgraph: true,\n\t\t},\n\t\tnodes: [],\n\t\tedges: [],\n\t};\n\tlet idCounter = 1;\n\tconst ids = new Map<T, string>();\n\tfunction getId(item: T): string {\n\t\tconst _id = infoSelector(item).id;\n\t\tif (_id !== undefined) {\n\t\t\treturn \"\" + _id;\n\t\t}\n\n\t\tlet id = ids.get(item);\n\t\tif (!id) {\n\t\t\tid = `hediet.de/id-${idCounter++}`;\n\t\t\tids.set(item, id);\n\t\t}\n\t\treturn id;\n\t}\n\n\tconst queue = new Array<{ item: T; dist: number }>(\n\t\t...roots.map(r => ({ item: r, dist: 0 }))\n\t);\n\tconst processed = new Set<T>();\n\n\twhile (queue.length > 0) {\n\t\tconst { item, dist } = queue.shift()!;\n\t\tif (processed.has(item)) {\n\t\t\tcontinue;\n\t\t}\n\t\tprocessed.add(item);\n\t\tconst nodeInfo = infoSelector(item);\n\t\tconst fromId = getId(item);\n\t\tr.nodes.push({ ...nodeInfo, id: fromId, [\"edges\" as any]: undefined });\n\t\tfor (const e of nodeInfo.edges) {\n\t\t\tlet other: T;\n\t\t\tlet toId: string | undefined;\n\t\t\tlet fromId_: string | undefined;\n\t\t\tif (\"to\" in e) {\n\t\t\t\tother = e.to;\n\t\t\t\ttoId = getId(e.to);\n\t\t\t\tfromId_ = fromId;\n\t\t\t} else if (\"from\" in e) {\n\t\t\t\tother = e.from;\n\t\t\t\ttoId = getId(e.from);\n\t\t\t\tfromId_ = fromId;\n\t\t\t} else if (\"include\" in e) {\n\t\t\t\tother = e.include;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Every edge must either have 'to' or 'from'\");\n\t\t\t}\n\n\t\t\tif (fromId_ !== undefined && toId !== undefined) {\n\t\t\t\tr.edges.push({\n\t\t\t\t\t...e,\n\t\t\t\t\tfrom: fromId_,\n\t\t\t\t\tto: toId,\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet shouldPush = !processed.has(other);\n\t\t\tif (\n\t\t\t\toptions.maxSize &&\n\t\t\t\tprocessed.size + queue.length > options.maxSize\n\t\t\t) {\n\t\t\t\tshouldPush = false;\n\t\t\t}\n\t\t\tif (shouldPush) {\n\t\t\t\tqueue.push({ item: other, dist: dist + 1 });\n\t\t\t}\n\t\t}\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "data-extraction/src/js/helpers/createGraphFromPointers.ts",
    "content": "import { GraphNode, GraphVisualizationData } from \"../../CommonDataTypes\";\nimport { CreateGraphEdge, createGraph } from \"./createGraph\";\n\n/**\n * Given a labeled list of roots, it creates a graph by following their edges recursively.\n * Tracks cycles.\n */\nexport function createGraphFromPointers<T>(\n\troots: Record<string, T | undefined | null>,\n\tinfoSelector: (item: T) => {\n\t\tid?: string | number;\n\t\tedges: CreateGraphEdge<T>[];\n\t} & Omit<GraphNode, \"id\">,\n\toptions: { maxSize?: number } = {}\n): GraphVisualizationData {\n\tconst marker = {};\n\n\tinterface Pointer {\n\t\tmarker: {};\n\t\tname: string;\n\t\tvalue: T | null | undefined;\n\t}\n\n\tconst items = Object.entries(roots).map<Pointer>(([name, value]) => ({\n\t\tmarker,\n\t\tname,\n\t\tvalue,\n\t}));\n\n\treturn createGraph<T | Pointer>(\n\t\titems,\n\t\t(item) => {\n\t\t\tif (\n\t\t\t\ttypeof item === \"object\" &&\n\t\t\t\titem &&\n\t\t\t\t\"marker\" in item &&\n\t\t\t\titem[\"marker\"] === marker\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tid: \"label____\" + item.name,\n\t\t\t\t\tcolor: \"orange\",\n\t\t\t\t\tlabel: item.name,\n\t\t\t\t\tedges: [\n\t\t\t\t\t\t{ to: item.value!, color: \"orange\", label: \"\" },\n\t\t\t\t\t].filter((t) => !!t.to),\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\treturn infoSelector(item as T);\n\t\t\t}\n\t\t},\n\t\toptions\n\t);\n}\n"
  },
  {
    "path": "data-extraction/src/js/helpers/find.ts",
    "content": "import { DataExtractorApiImpl } from \"../api\";\n\nexport function find(predicate: (obj: unknown) => boolean): unknown {\n\tconst processed = new Set();\n\tif (!DataExtractorApiImpl.lastContext) {\n\t\tthrow new Error(\"No data extractor context!\");\n\t}\n\n\tconst values = Object.values(\n\t\tDataExtractorApiImpl.lastContext.variablesInScope\n\t);\n\tconst queue = [\n\t\t...values.map((v) => {\n\t\t\ttry {\n\t\t\t\treturn v();\n\t\t\t} catch (e) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}),\n\t];\n\n\tlet i = 10000;\n\twhile (i > 0) {\n\t\ti--;\n\n\t\tconst top = queue.shift();\n\t\tprocessed.add(top);\n\n\t\tif (predicate(top)) {\n\t\t\treturn top;\n\t\t}\n\n\t\tif (typeof top === \"object\" && top) {\n\t\t\tfor (const val of Object.values(top)) {\n\t\t\t\tif (!processed.has(val)) {\n\t\t\t\t\tprocessed.add(val);\n\t\t\t\t\tqueue.push(val);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nexport function findVar(\n\toptions: { nameSimilarTo?: string; ctor?: string },\n\tpredicate?: (value: any) => boolean\n): unknown | undefined {\n\tif (!DataExtractorApiImpl.lastContext) {\n\t\tthrow new Error(\"No data extractor context!\");\n\t}\n\n\tlet bestValue = undefined;\n\tlet bestValueScore = undefined; // minimized\n\n\tfor (const [name, value] of Object.entries(\n\t\tDataExtractorApiImpl.lastContext.variablesInScope\n\t)) {\n\t\tconst v = value();\n\t\tif (options.ctor !== undefined) {\n\t\t\tif (\n\t\t\t\ttypeof v !== \"object\" ||\n\t\t\t\t!v ||\n\t\t\t\tv.constructor.name !== options.ctor\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (predicate) {\n\t\t\tif (!predicate(v)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tlet score = 0;\n\t\tif (options.nameSimilarTo !== undefined) {\n\t\t\tscore += similarityScore(name, options.nameSimilarTo);\n\t\t} else {\n\t\t\treturn v;\n\t\t}\n\t\tif (bestValueScore === undefined || score < bestValueScore) {\n\t\t\tbestValue = v;\n\t\t\tbestValueScore = score;\n\t\t}\n\t}\n\n\treturn bestValue;\n}\n\nfunction similarityScore(a: string, b: string): number {\n\tconst distance = levenshteinDistance(a, b);\n\n\tconst aSorted = a.split(\"\").sort().join(\"\");\n\tconst bSorted = b.split(\"\").sort().join(\"\");\n\tconst distance2 = levenshteinDistance(aSorted, bSorted);\n\n\treturn distance * 10 + distance2;\n}\n\nfunction levenshteinDistance(a: string, b: string): number {\n\tif (a.length === 0) return b.length;\n\tif (b.length === 0) return a.length;\n\n\tconst matrix = [];\n\n\t// increment along the first column of each row\n\tlet i;\n\tfor (i = 0; i <= b.length; i++) {\n\t\tmatrix[i] = [i];\n\t}\n\n\t// increment each column in the first row\n\tlet j;\n\tfor (j = 0; j <= a.length; j++) {\n\t\tmatrix[0][j] = j;\n\t}\n\n\t// Fill in the rest of the matrix\n\tfor (i = 1; i <= b.length; i++) {\n\t\tfor (j = 1; j <= a.length; j++) {\n\t\t\tif (b.charAt(i - 1) == a.charAt(j - 1)) {\n\t\t\t\tmatrix[i][j] = matrix[i - 1][j - 1];\n\t\t\t} else {\n\t\t\t\tmatrix[i][j] = Math.min(\n\t\t\t\t\tmatrix[i - 1][j - 1] + 1, // substitution\n\t\t\t\t\tMath.min(\n\t\t\t\t\t\tmatrix[i][j - 1] + 1, // insertion\n\t\t\t\t\t\tmatrix[i - 1][j] + 1\n\t\t\t\t\t)\n\t\t\t\t); // deletion\n\t\t\t}\n\t\t}\n\t}\n\n\treturn matrix[b.length][a.length];\n}\n"
  },
  {
    "path": "data-extraction/src/js/helpers/index.ts",
    "content": "export * from \"./createGraph\";\nexport * from \"./createGraphFromPointers\";\nexport * from \"./tryEval\";\nexport * from \"./markedGrid\";\nexport * from \"./cache\";\nexport * from \"./asData\";\nexport * from \"./find\";\n"
  },
  {
    "path": "data-extraction/src/js/helpers/markedGrid.ts",
    "content": "import { GridVisualizationData } from \"../../CommonDataTypes\";\n\nexport function markedGrid(\n\tarr: unknown[],\n\tmarked: Record<string, number | undefined>\n): GridVisualizationData {\n\tif (!Array.isArray(arr)) {\n\t\tarr = [...(arr as any)];\n\t}\n\n\treturn {\n\t\tkind: { grid: true },\n\t\trows: [\n\t\t\t{\n\t\t\t\tcolumns: arr.map((d) => ({\n\t\t\t\t\tcontent: \"\" + d,\n\t\t\t\t\ttag: \"\" + d,\n\t\t\t\t})),\n\t\t\t},\n\t\t],\n\t\tmarkers: marked\n\t\t\t? Object.entries(marked)\n\t\t\t\t\t.map(([key, val]) => ({\n\t\t\t\t\t\tid: \"\" + key,\n\t\t\t\t\t\trow: 0,\n\t\t\t\t\t\tcolumn: val!,\n\t\t\t\t\t}))\n\t\t\t\t\t.filter((c) => c.column !== undefined)\n\t\t\t: undefined,\n\t};\n}\n"
  },
  {
    "path": "data-extraction/src/js/helpers/tryEval.ts",
    "content": "import { DataExtractorApiImpl } from \"../api/DataExtractorApiImpl\";\n\n/**\n * Takes an object and eval's its values.\n * Each successfully evaluated value is added to the result object,\n * its original key is used as key in the result object.\n *\n * # Example\n * ```\n * const x = 1;\n * tryEval({ val1: \"x\", val2: \"x y\" })\n * // -> { val1: 1 }\n * ```\n */\nexport function tryEval(obj: Record<string, string>): Record<string, unknown>;\n/**\n * Takes an array of strings and eval's its items.\n * Each successfully evaluated value is added to the result object,\n * its original value is used as key.\n *\n * # Example\n * ```\n * const x = 1;\n * tryEval([\"x\", \"y\", \"a a\", \"x + 2\"])\n * // -> { x: 1, \"x + 2\": 3 }\n * ```\n */\nexport function tryEval(arr: string[]): Record<string, unknown>;\nexport function tryEval(\n\tobj: Record<string, string> | string[] | string\n): Record<string, unknown> | unknown {\n\tconst result: Record<string, unknown> = {};\n\tconst context = DataExtractorApiImpl.lastContext!;\n\tif (Array.isArray(obj)) {\n\t\tfor (const val of obj) {\n\t\t\ttry {\n\t\t\t\tresult[val] = context.evalFn(val);\n\t\t\t} catch (e) {}\n\t\t}\n\t} else {\n\t\tfor (const [key, val] of Object.entries(obj)) {\n\t\t\ttry {\n\t\t\t\tresult[key] = context.evalFn(val);\n\t\t\t} catch (e) {}\n\t\t}\n\t}\n\treturn result;\n}\n"
  },
  {
    "path": "data-extraction/src/js/index.ts",
    "content": "export * from \"./api\";\nexport * from \"./helpers\";\nexport { registerDefaultExtractors } from \"./api/default-extractors\";\n"
  },
  {
    "path": "data-extraction/src/util.ts",
    "content": "export function expect<T>(data: T): T {\n\treturn data;\n}\n"
  },
  {
    "path": "data-extraction/test/main.test.ts",
    "content": "import { DataExtractorApiImpl } from \"../\";\n\ndescribe(\"extractor\", () => {\n\tit(\"should not crash\", () => {\n\t\tconst dataExtractor = new DataExtractorApiImpl();\n\t\tdataExtractor.registerDefaultExtractors();\n\t\tconst result = dataExtractor.getData(\n\t\t\t() => [1, 2, 3],\n\t\t\t() => null!,\n\t\t\tundefined\n\t\t);\n\t});\n});\n"
  },
  {
    "path": "data-extraction/test/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"esnext\",\n\t\t\"module\": \"commonjs\",\n\t\t\"strict\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"rootDir\": \"./\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true,\n\t\t\"newLine\": \"LF\",\n\t\t\"sourceMap\": true,\n\t\t\"noEmit\": true\n\t},\n\t\"include\": [\"./**/*\"]\n}\n"
  },
  {
    "path": "data-extraction/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ES2018\",\n\t\t\"module\": \"commonjs\",\n\t\t\"strict\": true,\n\t\t\"outDir\": \"./dist\",\n\t\t\"skipLibCheck\": true,\n\t\t\"rootDir\": \"./src\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true,\n\t\t\"newLine\": \"LF\",\n\t\t\"sourceMap\": true\n\t},\n\t\"include\": [\"./src/**/*\"]\n}\n"
  },
  {
    "path": "data-extraction/webpack.config.ts",
    "content": "import { CleanWebpackPlugin } from \"clean-webpack-plugin\";\nimport * as path from \"path\";\nimport * as webpack from \"webpack\";\n\nconst r = (file: string) => path.resolve(__dirname, file);\n\nmodule.exports = {\n\ttarget: \"node\",\n\tentry: r(\"./src/index\"),\n\toutput: {\n\t\tpath: r(\"./dist\"),\n\t\tfilename: \"index.js\",\n\t\tlibraryTarget: \"commonjs2\",\n\t\tdevtoolModuleFilenameTemplate: \"../[resource-path]\",\n\t},\n\tdevtool: \"source-map\",\n\tresolve: {\n\t\textensions: [\".ts\", \".js\"],\n\t},\n\tmodule: {\n\t\trules: [\n\t\t\t{\n\t\t\t\ttest: /\\.ts$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\tuse: [\n\t\t\t\t\t{\n\t\t\t\t\t\tloader: \"ts-loader\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n\tnode: {\n\t\t__dirname: false,\n\t\t__filename: false,\n\t},\n\tplugins: [\n\t\tnew CleanWebpackPlugin({\n\t\t\t//protectWebpackAssets: true,\n\t\t\tcleanAfterEveryBuildPatterns: [\"!**/*.d.ts\", \"!**/*.d.ts.map\"],\n\t\t}),\n\t],\n} as webpack.Configuration;\n"
  },
  {
    "path": "demos/cpp/.gitignore",
    "content": "main"
  },
  {
    "path": "demos/cpp/.vscode/launch.json",
    "content": "{\n    // Use IntelliSense to learn about possible attributes.\n    // Hover to view descriptions of existing attributes.\n    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"g++ build and debug active file\",\n            \"type\": \"cppdbg\",\n            \"request\": \"launch\",\n            \"program\": \"${fileDirname}/${fileBasenameNoExtension}\",\n            \"args\": [],\n            \"stopAtEntry\": false,\n            \"cwd\": \"${workspaceFolder}\",\n            \"environment\": [],\n            \"externalConsole\": false,\n            \"MIMode\": \"gdb\",\n            \"setupCommands\": [\n                {\n                    \"description\": \"Enable pretty-printing for gdb\",\n                    \"text\": \"-enable-pretty-printing\",\n                    \"ignoreFailures\": true\n                }\n            ],\n            \"preLaunchTask\": \"g++ build active file\",\n            \"miDebuggerPath\": \"/usr/bin/gdb\"\n        }\n    ]\n}"
  },
  {
    "path": "demos/cpp/.vscode/tasks.json",
    "content": "{\n    // See https://go.microsoft.com/fwlink/?LinkId=733558 \n    // for the documentation about the tasks.json format\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"type\": \"shell\",\n            \"label\": \"g++ build active file\",\n            \"command\": \"/usr/bin/g++\",\n            \"args\": [\n                \"-g\",\n                \"${file}\",\n                \"-o\",\n                \"${fileDirname}/${fileBasenameNoExtension}\"\n            ],\n            \"options\": {\n                \"cwd\": \"/usr/bin\"\n            },\n            \"problemMatcher\": [\n                \"$gcc\"\n            ],\n            \"group\": \"build\"\n        }\n    ]\n}"
  },
  {
    "path": "demos/cpp/main.cpp",
    "content": "#include <iostream>\n#include <vector>\n#include <string>\n\nusing namespace std;\n\nint main()\n{\n    // visualize `myGraphJson`!\n    string myGraphJson = \"{\\\"kind\\\":{\\\"graph\\\":true},\"\n        \"\\\"nodes\\\":[{\\\"id\\\":\\\"1\\\"},{\\\"id\\\":\\\"2\\\"}],\"\n        \"\\\"edges\\\":[{\\\"from\\\":\\\"1\\\",\\\"to\\\":\\\"2\\\"}]}\";\n    cout << myGraphJson;\n}"
  },
  {
    "path": "demos/csharp/.gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.rsuser\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Mono auto generated files\nmono_crash.*\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n[Aa][Rr][Mm]/\n[Aa][Rr][Mm]64/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n[Ll]ogs/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUnit\n*.VisualState.xml\nTestResult.xml\nnunit-*.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_h.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*_wpftmp.csproj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Coverlet is a free, cross platform Code Coverage Tool\ncoverage*[.json, .xml, .info]\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# NuGet Symbol Packages\n*.snupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n*.appxbundle\n*.appxupload\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!?*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n*- [Bb]ackup.rdl\n*- [Bb]ackup ([0-9]).rdl\n*- [Bb]ackup ([0-9][0-9]).rdl\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# CodeRush personal settings\n.cr/personal\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# Local History for Visual Studio\n.localhistory/\n\n# BeatPulse healthcheck temp database\nhealthchecksdb\n\n# Backup folder for Package Reference Convert tool in Visual Studio 2017\nMigrationBackup/\n\n# Ionide (cross platform F# VS Code tools) working folder\n.ionide/"
  },
  {
    "path": "demos/csharp/.vscode/launch.json",
    "content": "{\n\t// Use IntelliSense to find out which attributes exist for C# debugging\n\t// Use hover for the description of the existing attributes\n\t// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"name\": \"C# - Demo: Linked List\",\n\t\t\t\"type\": \"coreclr\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"preLaunchTask\": \"csharp-build\",\n\t\t\t\"program\": \"${workspaceFolder}/bin/Debug/netcoreapp3.1/demo.dll\",\n\t\t\t\"args\": [],\n\t\t\t\"cwd\": \"${workspaceFolder}\",\n\t\t\t\"console\": \"internalConsole\",\n\t\t\t\"stopAtEntry\": false\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/csharp/.vscode/settings.json",
    "content": "{\n\t\"debugVisualizer.debugAdapterConfigurations\": {}\n}\n"
  },
  {
    "path": "demos/csharp/.vscode/tasks.json",
    "content": "{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t{\n\t\t\t\"label\": \"csharp-build\",\n\t\t\t\"command\": \"dotnet\",\n\t\t\t\"type\": \"process\",\n\t\t\t\"args\": [\n\t\t\t\t\"build\",\n\t\t\t\t\"${workspaceFolder}/csharp/demo.csproj\",\n\t\t\t\t\"/property:GenerateFullPaths=true\",\n\t\t\t\t\"/consoleloggerparameters:NoSummary\"\n\t\t\t],\n\t\t\t\"problemMatcher\": \"$msCompile\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/csharp/ExtractedData.cs",
    "content": "#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing Newtonsoft.Json;\n\nnamespace Hediet.DebugVisualizer.ExtractedData\n{\n    [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]\n    public abstract class ExtractedData\n    {\n        [JsonProperty(\"kind\")]\n        public Dictionary<string, bool> Kind\n        {\n            get\n            {\n                var d = new Dictionary<string, bool>();\n                foreach (var tag in Tags)\n                {\n                    d.Add(tag, true);\n                }\n                return d;\n            }\n        }\n\n        [JsonIgnore]\n        public abstract string[] Tags { get; }\n\n        public override string ToString()\n        {\n            return JsonConvert.SerializeObject(this);\n        }\n    }\n\n    public class TextData : ExtractedData\n    {\n        public override string[] Tags => new string[] { \"text\" };\n\n        [JsonProperty(\"text\")]\n        public string TextValue { get; set; }\n\n        public TextData(string text)\n        {\n            this.TextValue = text;\n        }\n    }\n\n    public class GraphData : ExtractedData\n    {\n        public override string[] Tags => new string[] { \"graph\" };\n\n        [JsonProperty(\"nodes\")]\n        public IList<NodeData> Nodes { get; set; } = new List<NodeData>();\n\n        [JsonProperty(\"edges\")]\n        public IList<EdgeData> Edges { get; set; } = new List<EdgeData>();\n\n        [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]\n        public class NodeData\n        {\n            public NodeData(string id)\n            {\n                Id = id;\n            }\n\n            [JsonProperty(\"id\")]\n            public string Id { get; set; }\n\n            [JsonProperty(\"label\")]\n            public string? Label { get; set; }\n\n            [JsonProperty(\"color\")]\n            public string? Color { get; set; }\n\n            [JsonProperty(\"shape\")]\n            public string? Shape { get; set; }\n        }\n\n        [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]\n\n        public class EdgeData\n        {\n            public EdgeData(string from, string to)\n            {\n                From = from;\n                To = to;\n            }\n\n            [JsonProperty(\"from\")]\n            public string From { get; set; }\n\n            [JsonProperty(\"to\")]\n            public string To { get; set; }\n\n            [JsonProperty(\"label\")]\n            public string? Label { get; set; }\n\n            [JsonProperty(\"id\")]\n            public string? Id { get; set; }\n\n            [JsonProperty(\"color\")]\n            public string? Color { get; set; }\n\n            [JsonProperty(\"dashes\")]\n            public bool? Dashes { get; set; }\n        }\n\n        public static GraphData From<T>(IEnumerable<T> items, Func<T, NodeInfo<T>, NodeInfo<T>> f) where T : notnull\n        {\n            var d = new GraphData();\n            var q = new Queue<T>(items);\n            var i = 0;\n            var infos = new Dictionary<T, NodeInfo<T>>();\n\n            string GetId(NodeInfo<T> item)\n            {\n                if (item.Id == null)\n                    item.Id = \"hediet.de/\" + (i++);\n                return item.Id;\n            }\n\n            NodeInfo<T> GetNodeInfo(T item)\n            {\n                if (infos.ContainsKey(item))\n                    return infos[item];\n\n                var info = f(item, new NodeInfo<T>());\n                infos.Add(item, info);\n                return info;\n            }\n\n            while (q.Count > 0)\n            {\n                var nodeInfo = GetNodeInfo(q.Dequeue());\n                var nd = new NodeData(GetId(nodeInfo));\n                d.Nodes.Add(nd);\n\n                nd.Label = nodeInfo.Label;\n                nd.Color = nodeInfo.Color;\n\n                foreach (var e in nodeInfo.Edges)\n                {\n                    var ed = new EdgeData(nd.Id, GetId(GetNodeInfo(e.To)));\n                    d.Edges.Add(ed);\n\n                    ed.Label = e.Label;\n                    ed.Id = e.Id;\n\n                    q.Enqueue(e.To);\n                }\n            }\n\n            return d;\n        }\n\n        public class NodeInfo<T>\n        {\n            public IList<EdgeInfo<T>> Edges { get; set; } = new List<EdgeInfo<T>>();\n            public string? Label { get; set; }\n            public string? Id { get; set; }\n            public string? Color { get; set; }\n\n            public NodeInfo<T> AddEdge(T to, string? id = null, string? label = null)\n            {\n                var e = new EdgeInfo<T>(to);\n                e.Id = id;\n                e.Label = label;\n                Edges.Add(e);\n                return this;\n            }\n        }\n\n        public class EdgeInfo<T>\n        {\n            public T To { get; set; }\n            public string? Label { get; set; }\n            public string? Id { get; set; }\n\n            public EdgeInfo(T to)\n            {\n                To = to;\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "demos/csharp/Program.cs",
    "content": "﻿\r\n// Install dotnet core clr see VS Code docs on how to setup VS Code so that you can debug C# applications.\r\n// The Debug Visualizer does not support C# data extractors yet.\r\n// If you want to visualize a value, it's `ToString` method must return supported json data.\r\n// See the readme of the extension for supported json schemas.\r\n\r\n#nullable enable\r\n\r\nusing System.Linq;\r\nusing Hediet.DebugVisualizer.ExtractedData;\r\n\r\nnamespace Demo\r\n{\r\n    class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            var list = new LinkedList<int>();\r\n            // visualize `list.Visualize()` here!\r\n            list.Append(1);\r\n            list.Append(2);\r\n            list.Append(3);\r\n            list.Append(4);\r\n        }\r\n    }\r\n\r\n    class LinkedList<T>\r\n    {\r\n        class Node\r\n        {\r\n            public Node(T value) { Value = value; }\r\n            public T Value { get; set; }\r\n            public Node? Next { get; set; }\r\n        }\r\n\r\n        private Node? Head { get; set; }\r\n\r\n        public void Append(T item)\r\n        {\r\n            if (this.Head == null)\r\n            {\r\n                this.Head = new Node(item);\r\n            }\r\n            else\r\n            {\r\n                var cur = this.Head;\r\n                while (cur.Next != null)\r\n                {\r\n                    cur = cur.Next;\r\n                }\r\n                cur.Next = new Node(item);\r\n            }\r\n        }\r\n\r\n        public string Visualize()\r\n        {\r\n            var list = new Node(default(T)!) { Next = this.Head };\r\n            return GraphData.From(new[] { list }, (item, info) =>\r\n            {\r\n                info.Id = item == list ? \"List\" : string.Format(\"{0}\", item.Value);\r\n                if (item == list)\r\n                {\r\n                    info.Color = \"orange\";\r\n                }\r\n                if (item.Next != null)\r\n                    info.AddEdge(item.Next!, label: item == list ? \"head\" : \"next\");\r\n                return info;\r\n            }).ToString();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "demos/csharp/demo.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>netcoreapp3.1</TargetFramework>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"newtonsoft.json\" Version=\"12.0.3\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "demos/dart/debug_visualizers.dart",
    "content": "import 'dart:convert';\n\nString graph(List<GraphNode> nodes, List<GraphEdge> edges) {\n  return jsonEncode({\n    'kind': {'graph': true},\n    'nodes': nodes,\n    'edges': edges,\n  });\n}\n\nString plotly(List<num> values) {\n  return jsonEncode({\n    'kind': {'plotly': true},\n    'data': [\n      {'y': values}\n    ],\n  });\n}\n\nString tree(TreeNode root) {\n  return jsonEncode({\n    'kind': {'tree': true},\n    'root': root,\n  });\n}\n\nclass Graph {\n  List<GraphNode> nodes;\n  List<GraphEdge> edges;\n}\n\nclass GraphEdge {\n  final String from;\n  final String to;\n  final String label;\n\n  GraphEdge(this.from, this.to, this.label);\n\n  Map<String, dynamic> toJson() => {\n        'from': from,\n        'to': to,\n        'label': label,\n      };\n}\n\nclass GraphNode {\n  final String id;\n  final String label;\n\n  GraphNode(\n    this.id,\n    this.label,\n  );\n\n  Map<String, dynamic> toJson() => {\n        'id': id,\n        'label': label,\n      };\n}\n\nclass TreeNode {\n  final List<TreeNode> children;\n  final List<TreeNodeItem> items;\n  final String segment;\n  final bool isMarked;\n\n  TreeNode(this.children, this.items, this.segment, [this.isMarked = false]);\n\n  Map<String, dynamic> toJson() => {\n        'children': children ?? [],\n        'items': items,\n        'segment': segment,\n        'isMarked': isMarked,\n      };\n}\n\nclass TreeNodeItem {\n  final String text;\n\n  TreeNodeItem(this.text);\n\n  Map<String, dynamic> toJson() => {\n        'text': text,\n      };\n}\n"
  },
  {
    "path": "demos/dart/demo.dart",
    "content": "import 'dart:collection';\nimport 'dart:developer';\nimport 'dart:math';\n\n// ignore: unused_import\nimport 'debug_visualizers.dart';\n\nfinal _rnd = Random();\n\nString Function() visualize;\n\nvoid main() {\n  debugger();\n  // Open a Debug Visualizer window and evalute the expression \"visualize()\"\n  // and then press Continue to step through the samples.\n  plotly_demo();\n  graph_demo();\n  tree_demo();\n}\n\nvoid plotly_demo() {\n  final values = <int>[];\n  visualize = () => plotly(values);\n  for (var i = 0; i < 20; i++) {\n    debugger();\n    values.add(i + _rnd.nextInt(5) - 2);\n  }\n}\n\nvoid graph_demo() {\n  graphFromDoubleLinked<T>(\n      DoubleLinkedQueue<T> values, String Function(T) toString) {\n    node(T s) => GraphNode(toString(s), toString(s));\n    edge(DoubleLinkedQueueEntry<T> e) => [\n          if (e.nextEntry() != null)\n            GraphEdge(\n              toString(e.element),\n              toString(e.nextEntry().element),\n              \"next\",\n            ),\n          if (e.previousEntry() != null)\n            GraphEdge(\n              toString(e.element),\n              toString(e.previousEntry().element),\n              \"prev\",\n            ),\n        ];\n\n    final nodes = values.map(node).toList();\n    final edges = <GraphEdge>[];\n    values.forEachEntry((e) => edges.addAll(edge(e)));\n    return graph(nodes, edges);\n  }\n\n  final values = DoubleLinkedQueue<String>();\n  visualize = () => graphFromDoubleLinked(values, (s) => s);\n\n  for (var i = 0; i < 10; i++) {\n    debugger();\n    values.addLast('Node $i');\n  }\n}\n\nvoid tree_demo() {\n  var nodeNum = 1;\n  TreeNode createNode(int levels) {\n    final name = 'Node ${nodeNum++}';\n    final children =\n        levels > 0 ? List.generate(2, (_) => createNode(levels - 1)) : null;\n    return TreeNode(children, [TreeNodeItem(name)], name);\n  }\n\n  var levels = 0;\n  visualize = () {\n    nodeNum = 1;\n    return tree(createNode(levels));\n  };\n\n  for (var i = 1; i < 5; i++) {\n    debugger();\n    levels = i;\n  }\n}\n"
  },
  {
    "path": "demos/golang/.vscode/launch.json",
    "content": "{\r\n    \"version\": \"0.2.0\",\r\n    \"configurations\": [\r\n        {\r\n            \"name\": \"Launch\",\r\n            \"type\": \"go\",\r\n            \"request\": \"launch\",\r\n            \"mode\": \"auto\",\r\n            \"program\": \"${fileDirname}\",\r\n            \"env\": {},\r\n            \"args\": [],\r\n            \"dlvLoadConfig\": {\r\n                \"followPointers\": true,\r\n                \"maxVariableRecurse\": 1,\r\n                \"maxStringLen\": 5000,\r\n                \"maxArrayValues\": 64,\r\n                \"maxStructFields\": -1\r\n            }\r\n        }\r\n    ]\r\n}"
  },
  {
    "path": "demos/golang/demo.go",
    "content": "package main\r\n\r\nimport (\r\n\t\"encoding/json\"\r\n\t\"math/rand\"\r\n\t\"strconv\"\r\n\t\"time\"\r\n)\r\n\r\n// If you want to visualize large data structures,\r\n// you need to increase Delve's maxStringLen.\r\n// (See here https://github.com/microsoft/vscode-go/issues/868 for more info)\r\n// You can do this by adding the following configuration to your launch.json:\r\n// \"dlvLoadConfig\": {\r\n//     \"followPointers\": true,\r\n//     \"maxVariableRecurse\": 1,\r\n//     \"maxStringLen\": 5000,\r\n//     \"maxArrayValues\": 64,\r\n//     \"maxStructFields\": -1\r\n// }\r\n// For debugging tests, you can set the maxStringLen in settings.json like this:\r\n// \"go.delveConfig\": {\r\n//     \"dlvLoadConfig\": {\r\n//         \"followPointers\": true,\r\n//         \"maxVariableRecurse\": 1,\r\n//         \"maxStringLen\": 5000,\r\n//         \"maxArrayValues\": 64,\r\n//         \"maxStructFields\": -1\r\n//     },\r\n//     \"apiVersion\": 2,\r\n//     \"showGlobalVariables\": true\r\n// }\r\n\r\n// Open a new Debug Visualizer and visualize \"s\"\r\nfunc main() {\r\n\trand.Seed(time.Now().UnixNano())\r\n\tgraph := NewGraph()\r\n\tvar s string\r\n\tfor i := 0; i < 100; i++ {\r\n\t\tid := strconv.Itoa(i)\r\n\t\tgraph.Nodes = append(graph.Nodes, NodeGraphData{\r\n\t\t\tID:    id,\r\n\t\t\tLabel: id,\r\n\t\t})\r\n\t\tif i > 0 {\r\n\t\t\ttargetId := rand.Intn(i)\r\n\t\t\tgraph.Edges = append(graph.Edges, EdgeGraphData{\r\n\t\t\t\tFrom: id,\r\n\t\t\t\tTo:   strconv.Itoa(targetId),\r\n\t\t\t})\r\n\t\t}\r\n\t\ts = graph.toString()\r\n\t\t_ = s\r\n\t\t//fmt.Printf(\"%s\", s)\r\n\t}\r\n}\r\n\r\ntype Graph struct {\r\n\tKind  map[string]bool `json:\"kind\"`\r\n\tNodes []NodeGraphData `json:\"nodes\"`\r\n\tEdges []EdgeGraphData `json:\"edges\"`\r\n}\r\n\r\ntype NodeGraphData struct {\r\n\tID    string `json:\"id\"`\r\n\tLabel string `json:\"label,omitempty\"`\r\n\tColor string `json:\"color,omitempty\"`\r\n\tShape string `json:\"shape,omitempty\"`\r\n}\r\n\r\ntype EdgeGraphData struct {\r\n\tFrom   string `json:\"from\"`\r\n\tTo     string `json:\"to\"`\r\n\tLabel  string `json:\"label,omitempty\"`\r\n\tID     string `json:\"id\"`\r\n\tColor  string `json:\"color,omitempty\"`\r\n\tDashes bool   `json:\"dashes,omitempty\"`\r\n}\r\n\r\nfunc NewGraph() *Graph {\r\n\treturn &Graph{\r\n\t\tKind:  map[string]bool{\"graph\": true},\r\n\t\tNodes: []NodeGraphData{},\r\n\t\tEdges: []EdgeGraphData{},\r\n\t}\r\n}\r\n\r\nfunc (this *Graph) toString() string {\r\n\trs, _ := json.Marshal(this)\r\n\treturn string(rs)\r\n}"
  },
  {
    "path": "demos/golang/go.mod",
    "content": "module demo\n\ngo 1.13\n"
  },
  {
    "path": "demos/java/.classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<classpath>\r\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11\"/>\r\n\t<classpathentry kind=\"src\" path=\"src\"/>\r\n\t<classpathentry kind=\"output\" path=\"bin\"/>\r\n\t<classpathentry exported=\"true\" kind=\"lib\" path=\"lib/jackson-annotations-2.9.8.jar\"/>\r\n\t<classpathentry exported=\"true\" kind=\"lib\" path=\"lib/jackson-core-2.9.8.jar\"/>\r\n\t<classpathentry exported=\"true\" kind=\"lib\" path=\"lib/jackson-databind-2.9.8.jar\"/>\r\n</classpath>\r\n"
  },
  {
    "path": "demos/java/.gitignore",
    "content": "# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.nar\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n!lib/**"
  },
  {
    "path": "demos/java/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>java</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n\t<filteredResources>\n\t\t<filter>\n\t\t\t<id>1599063072264</id>\n\t\t\t<name></name>\n\t\t\t<type>30</type>\n\t\t\t<matcher>\n\t\t\t\t<id>org.eclipse.core.resources.regexFilterMatcher</id>\n\t\t\t\t<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>\n\t\t\t</matcher>\n\t\t</filter>\n\t</filteredResources>\n</projectDescription>\n"
  },
  {
    "path": "demos/java/.settings/org.eclipse.jdt.core.prefs",
    "content": "eclipse.preferences.version=1\r\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r\norg.eclipse.jdt.core.compiler.codegen.targetPlatform=11\r\norg.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve\r\norg.eclipse.jdt.core.compiler.compliance=10\r\norg.eclipse.jdt.core.compiler.debug.lineNumber=generate\r\norg.eclipse.jdt.core.compiler.debug.localVariable=generate\r\norg.eclipse.jdt.core.compiler.debug.sourceFile=generate\r\norg.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r\norg.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r\norg.eclipse.jdt.core.compiler.source=11\r\n"
  },
  {
    "path": "demos/java/.vscode/launch.json",
    "content": "{\n\t// Use IntelliSense to find out which attributes exist for C# debugging\n\t// Use hover for the description of the existing attributes\n\t// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"type\": \"java\",\n\t\t\t\"name\": \"CodeLens (Launch) - DemoLinkedLists\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"mainClass\": \"DemoLinkedLists\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Java - Demo\",\n\t\t\t\"type\": \"java\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"projectName\": \"java\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/java/.vscode/settings.json",
    "content": "{\n\t\"java.dependency.packagePresentation\": \"flat\",\n\t\"java.dependency.syncWithFolderExplorer\": true,\n\t\"debugVisualizer.debugAdapterConfigurations\": {}\n}\n"
  },
  {
    "path": "demos/java/src/app/App.java",
    "content": "package app;\r\n\r\nimport app.GraphData.EdgeInfo;\r\n\r\npublic class App {\r\n\r\n    public static void main(String[] args) {\r\n        // watch `list.visualize()`\r\n        LinkedList<String> list = new LinkedList<String>();\r\n        list.append(\"1\");\r\n        list.append(\"2\");\r\n        list.append(\"3\");\r\n        list.append(\"4\");\r\n    }\r\n}\r\n\r\nclass LinkedList<T> {\r\n    private Node<T> head;\r\n\r\n    public void append(T value) {\r\n        if (head == null) {\r\n            head = new Node<T>(value);\r\n        } else {\r\n            Node<T> m = head;\r\n            while (m.next != null) {\r\n                m = m.next;\r\n            }\r\n            m.next = new Node<T>(value);\r\n        }\r\n    }\r\n\r\n    public String visualize() {\r\n        Node<T> list = new Node<T>(null);\r\n        list.next = this.head;\r\n\r\n        return GraphData.from(list, (item, info) -> {\r\n            if (item != list) {\r\n                info.id = item.value.toString();\r\n            } else {\r\n                info.label = \"list\";\r\n            }\r\n            if (item.next != null) {\r\n                EdgeInfo<LinkedList.Node<T>> ei = info.addEdge(item.next);\r\n                ei.label = \"next\";\r\n            }\r\n            return info;\r\n        }).toString();\r\n    }\r\n\r\n    static class Node<T> {\r\n        public T value;\r\n        public Node<T> next;\r\n\r\n        public Node(T value) {\r\n            this.value = value;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "demos/java/src/app/ExtractedData.java",
    "content": "package app;\n\nimport java.util.HashMap;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\npublic abstract class ExtractedData {\n    public HashMap<String, Boolean> getKind() {\n        HashMap<String, Boolean> m = new HashMap<>();\n        for (String s : getTags()) {\n            m.put(s, true);\n        }\n        return m;\n    }\n\n    @JsonIgnore\n    protected abstract String[] getTags();\n\n    @Override\n    public String toString() {\n        ObjectMapper objectMapper = new ObjectMapper();\n        try {\n            String val = objectMapper.writeValueAsString(this);\n            return val;\n        } catch (JsonProcessingException e) {\n            return \"JsonProcessingException\";\n        }\n    }\n}\n"
  },
  {
    "path": "demos/java/src/app/GraphData.java",
    "content": "package app;\n\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.annotation.JsonInclude.Include;\n\npublic class GraphData extends ExtractedData {\n    private List<NodeData> nodes = new ArrayList<>();\n    private List<EdgeData> edges = new ArrayList<>();\n\n    @Override\n    protected String[] getTags() {\n        return new String[] { \"graph\" };\n    }\n\n    public List<NodeData> getNodes() {\n        return this.nodes;\n    }\n\n    public List<EdgeData> getEdges() {\n        return this.edges;\n    }\n\n    @JsonInclude(Include.NON_NULL)\n    public static class NodeData {\n        private String id;\n        private String label; // can be null\n        private String color; // can be null\n        private String shape; // can be null\n\n        public NodeData(String id) {\n            this.id = id;\n        }\n\n        public String getId() {\n            return this.id;\n        }\n\n        public void setId(String id) {\n            this.id = id;\n        }\n\n        public String getLabel() {\n            return this.label;\n        }\n\n        public void setLabel(String label) {\n            this.label = label;\n        }\n\n        public String getColor() {\n            return this.color;\n        }\n\n        public void setColor(String color) {\n            this.color = color;\n        }\n\n        public String getShape() {\n            return this.shape;\n        }\n\n        public void setShape(String shape) {\n            this.shape = shape;\n        }\n    }\n\n    @JsonInclude(Include.NON_NULL)\n    public static class EdgeData {\n        private String from;\n        private String to;\n        private String label; // Can be null\n        private String id; // Can be null\n        private String color; // Can be null\n        private Boolean dashes; // Can be null\n\n        public EdgeData(String from, String to) {\n            this.from = from;\n            this.to = to;\n        }\n\n        public String getFrom() {\n            return this.from;\n        }\n\n        public void setFrom(String from) {\n            this.from = from;\n        }\n\n        public String getTo() {\n            return this.to;\n        }\n\n        public void setTo(String to) {\n            this.to = to;\n        }\n\n        public String getLabel() {\n            return this.label;\n        }\n\n        public void setLabel(String label) {\n            this.label = label;\n        }\n\n        public String getId() {\n            return this.id;\n        }\n\n        public void setId(String id) {\n            this.id = id;\n        }\n\n        public String getColor() {\n            return this.color;\n        }\n\n        public void setColor(String color) {\n            this.color = color;\n        }\n\n        public Boolean getDashes() {\n            return this.dashes;\n        }\n\n        public void setDashes(Boolean dashes) {\n            this.dashes = dashes;\n        }\n    }\n\n    public interface NodeInfoProvider<T> {\n        public NodeInfo<T> getNodeInfo(T item, NodeInfo<T> nodeInfo);\n    }\n\n    public static <T> GraphData from(T item, NodeInfoProvider<T> f) {\n        GraphData d = new GraphData();\n        ArrayDeque<T> q = new ArrayDeque<>();\n        q.add(item);\n\n        FromState<T> s = new FromState<>(f);\n\n        while (q.size() > 0) {\n            NodeInfo<T> nodeInfo = s.getNodeInfo(q.removeFirst());\n            NodeData nd = new NodeData(s.getId(nodeInfo));\n            d.nodes.add(nd);\n\n            nd.setLabel(nodeInfo.label);\n            nd.setColor(nodeInfo.color);\n\n            for (EdgeInfo<T> e : nodeInfo.edges) {\n                EdgeData ed = new EdgeData(nd.id, s.getId(s.getNodeInfo(e.to)));\n                d.edges.add(ed);\n                ed.setLabel(e.label);\n                ed.setId(e.id);\n\n                q.add(e.to);\n            }\n\n        }\n\n        return d;\n    }\n\n    static class FromState<T> {\n        private int i = 0;\n        private NodeInfoProvider<T> provider;\n        private HashMap<T, NodeInfo<T>> infos = new HashMap<>();\n\n        public FromState(NodeInfoProvider<T> provider) {\n            this.provider = provider;\n        }\n\n        public String getId(NodeInfo<T> nodeInfo) {\n            if (nodeInfo.id == null) {\n                nodeInfo.id = \"hediet.de/\" + (i++);\n            }\n            return nodeInfo.id;\n        }\n\n        public NodeInfo<T> getNodeInfo(T item) {\n            if (infos.containsKey(item)) {\n                return infos.get(item);\n            }\n\n            NodeInfo<T> info = this.provider.getNodeInfo(item, new NodeInfo<>());\n            infos.put(item, info);\n            return info;\n        }\n    }\n\n    public static class NodeInfo<T> {\n        public ArrayList<EdgeInfo<T>> edges = new ArrayList<EdgeInfo<T>>();\n        public String label; // Can be null.\n        public String id; // Can be null.\n        public String color; // Can be null.\n\n        public EdgeInfo<T> addEdge(T to) {\n            EdgeInfo<T> i = new EdgeInfo<>(to);\n            this.edges.add(i);\n            return i;\n        }\n    }\n\n    public static class EdgeInfo<T> {\n        public T to;\n        public String label; // Can be null.\n        public String id; // Can be null.\n\n        public EdgeInfo(T to) {\n            this.to = to;\n        }\n    }\n}"
  },
  {
    "path": "demos/java/src/app/TextData.java",
    "content": "package app;\n\npublic class TextData extends ExtractedData {\n    private final String textValue;\n\n    public TextData(String text) {\n        this.textValue = text;\n    }\n\n    @Override\n    protected String[] getTags() {\n        return new String[] { \"text\" };\n    }\n\n    public String getText() {\n        return this.textValue;\n    }\n}"
  },
  {
    "path": "demos/js/.vscode/settings.json",
    "content": "{\n    \"editor.minimap.enabled\": false,\n    \"git.enabled\": false,\n    \"typescript.tsc.autoDetect\": \"off\",\n    \"debugVisualizer.js.customScriptPaths\": [\n       \"${workspaceFolder}/custom-visualizer.js\",\n    ]\n}"
  },
  {
    "path": "demos/js/.vscode/tasks.json",
    "content": "{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t{\n\t\t\t\"type\": \"npm\",\n\t\t\t\"script\": \"dev\",\n\t\t\t\"problemMatcher\": \"$tsc-watch\",\n\t\t\t\"isBackground\": true,\n\t\t\t\"presentation\": {\n\t\t\t\t\"reveal\": \"never\"\n\t\t\t},\n\t\t\t\"group\": {\n\t\t\t\t\"kind\": \"build\",\n\t\t\t\t\"isDefault\": true\n\t\t\t}\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/js/README.md",
    "content": "# JS Demos\n\nSimply run `yarn` and select the launch target you want to debug in the debugger pane of VS Code.\n"
  },
  {
    "path": "demos/js/custom-visualizer.js",
    "content": "// @ts-check\n/**\n * @type {import(\"@hediet/debug-visualizer-data-extraction\").LoadDataExtractorsFn}\n */\n module.exports = (register, helpers) => {\n\tregister({\n\t\tid: \"map\",\n\t\tgetExtractions(data, collector, context) {\n\t\t\tif (!(data instanceof Map)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcollector.addExtraction({\n\t\t\t\tpriority: 1000,\n\t\t\t\tid: \"map\",\n\t\t\t\tname: \"Map\",\n\t\t\t\textractData() {\n\t\t\t\t\treturn helpers.asData({\n\t\t\t\t\t\tkind: { table: true },\n\t\t\t\t\t\trows: [...data].map(([k, v]) => ({ key: k, value: v }))\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t});\n\t\n\tregister({\n\t\tid: \"binaryViewer\",\n\t\tgetExtractions(data, collector, context) {\n\t\t\tif (typeof data !== \"number\") {\n\t\t\t\treturn;\n\t\t\t}\n/*\n\t\t\tcontext.addCallFrameRequest({\n\t\t\t\tmethodName: \"Module._load\",\n\t\t\t\tpathRegExp: \".*\",\n\t\t\t});\n\n\t\t\tcontext.addCallFrameRequest({\n\t\t\t\tmethodName: \"LinkedList.insertAt\",\n\t\t\t\tpathRegExp: \".*\",\n\t\t\t});*/\n\n\t\t\tcollector.addExtraction({\n\t\t\t\tpriority: 10000,\n\t\t\t\tid: \"binary\",\n\t\t\t\tname: \"Bits of Integer\",\n\t\t\t\textractData() {\n\t\t\t\t\treturn context.extract(JSON.stringify(context.callFrameInfos, undefined, 4));\n\t\t\t\t\t\n\t\t\t\t\treturn helpers.asData({\n\t\t\t\t\t\tkind: { text: true },\n\t\t\t\t\t\ttext: data.toString(2),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t});\n };\n"
  },
  {
    "path": "demos/js/package.json",
    "content": "{\r\n\t\"name\": \"demo\",\r\n\t\"version\": \"1.0.0\",\r\n\t\"license\": \"MIT\",\r\n\t\"dependencies\": {\r\n\t\t\"@hediet/node-reload\": \"0.7.3\",\r\n\t\t\"@types/node\": \"^13.7.4\",\r\n\t\t\"node-fetch\": \"^2.6.1\",\r\n\t\t\"typescript\": \"^3.8.2\"\r\n\t},\r\n\t\"scripts\": {\r\n\t\t\"dev\": \"tsc --watch\"\r\n\t}\r\n}\r\n"
  },
  {
    "path": "demos/js/src/MockLanguageServiceHost.ts",
    "content": "import * as ts from \"typescript\";\n\nexport class MockLanguageServiceHost implements ts.LanguageServiceHost {\n\tconstructor(\n\t\tprivate readonly files: Map<string, string>,\n\t\tprivate readonly compilationSettings: ts.CompilerOptions\n\t) {}\n\n\tgetScriptFileNames(): string[] {\n\t\treturn [...this.files.keys()];\n\t}\n\n\tgetScriptVersion(fileName: string): string {\n\t\treturn \"\"; // our files don't change\n\t}\n\n\tgetScriptSnapshot(fileName: string): ts.IScriptSnapshot | undefined {\n\t\tconst content = this.files.get(fileName);\n\t\tif (!content) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tdispose() {},\n\t\t\tgetChangeRange: () => undefined,\n\t\t\tgetLength: () => content.length,\n\t\t\tgetText: (start, end) => content.substr(start, end - start),\n\t\t};\n\t}\n\n\tgetCompilationSettings(): ts.CompilerOptions {\n\t\treturn this.compilationSettings;\n\t}\n\tgetCurrentDirectory(): string {\n\t\treturn \"/\";\n\t}\n\tgetDefaultLibFileName(options: ts.CompilerOptions): string {\n\t\treturn ts.getDefaultLibFileName(options);\n\t}\n}\n"
  },
  {
    "path": "demos/js/src/demo_address_book.ts",
    "content": "\nclass Person {\n    constructor(public id: number, public firstName: string, public lastName: string, public email: string, public gender: string, public company: string) {\n\n    }\n}\n\nclass Company {\n    constructor(public id: number, public name: string, public street: string, public email: string) { }\n}\n\nclass AddressBook {\n    public static loadPersons(): Person[] {\n        const contactsData = [{\n            \"id\": 1,\n            \"first_name\": \"Burg\",\n            \"last_name\": \"Legg\",\n            \"email\": \"blegg0@elpais.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Zoozzy\"\n        }, {\n            \"id\": 2,\n            \"first_name\": \"Erminia\",\n            \"last_name\": \"Heersema\",\n            \"email\": \"eheersema1@jugem.jp\",\n            \"gender\": \"Female\",\n            \"company\": \"Skipfire\"\n        }, {\n            \"id\": 3,\n            \"first_name\": \"Penrod\",\n            \"last_name\": \"Claxton\",\n            \"email\": \"pclaxton2@furl.net\",\n            \"gender\": \"Male\",\n            \"company\": \"Dabvine\"\n        }, {\n            \"id\": 4,\n            \"first_name\": \"Peterus\",\n            \"last_name\": \"Alabone\",\n            \"email\": \"palabone3@icio.us\",\n            \"gender\": \"Male\",\n            \"company\": \"Gabtune\"\n        }, {\n            \"id\": 5,\n            \"first_name\": \"Rickie\",\n            \"last_name\": \"Belsher\",\n            \"email\": \"rbelsher4@marketwatch.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Digitube\"\n        }, {\n            \"id\": 6,\n            \"first_name\": \"Griffie\",\n            \"last_name\": \"Poulsum\",\n            \"email\": \"gpoulsum5@printfriendly.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Mymm\"\n        }, {\n            \"id\": 7,\n            \"first_name\": \"Fidelio\",\n            \"last_name\": \"Gateland\",\n            \"email\": \"fgateland6@intel.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Meeveo\"\n        }, {\n            \"id\": 8,\n            \"first_name\": \"Fayth\",\n            \"last_name\": \"D'Oyly\",\n            \"email\": \"fdoyly7@twitter.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Podcat\"\n        }, {\n            \"id\": 9,\n            \"first_name\": \"Janela\",\n            \"last_name\": \"Shelton\",\n            \"email\": \"jshelton8@dion.ne.jp\",\n            \"gender\": \"Female\",\n            \"company\": \"Kayveo\"\n        }, {\n            \"id\": 10,\n            \"first_name\": \"Yance\",\n            \"last_name\": \"Vatcher\",\n            \"email\": \"yvatcher9@ask.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Photobug\"\n        }, {\n            \"id\": 11,\n            \"first_name\": \"Filippo\",\n            \"last_name\": \"Timoney\",\n            \"email\": \"ftimoneya@spotify.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Rhyzio\"\n        }, {\n            \"id\": 12,\n            \"first_name\": \"Helli\",\n            \"last_name\": \"Friskey\",\n            \"email\": \"hfriskeyb@usa.gov\",\n            \"gender\": \"Female\",\n            \"company\": \"Eare\"\n        }, {\n            \"id\": 13,\n            \"first_name\": \"Enos\",\n            \"last_name\": \"Connick\",\n            \"email\": \"econnickc@sitemeter.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Meetz\"\n        }, {\n            \"id\": 14,\n            \"first_name\": \"Lorri\",\n            \"last_name\": \"Chessun\",\n            \"email\": \"lchessund@wp.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Jaxworks\"\n        }, {\n            \"id\": 15,\n            \"first_name\": \"Justina\",\n            \"last_name\": \"Spedroni\",\n            \"email\": \"jspedronie@abc.net.au\",\n            \"gender\": \"Female\",\n            \"company\": \"Rhyzio\"\n        }, {\n            \"id\": 16,\n            \"first_name\": \"Odilia\",\n            \"last_name\": \"Ealden\",\n            \"email\": \"oealdenf@fastcompany.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Blognation\"\n        }, {\n            \"id\": 17,\n            \"first_name\": \"Dale\",\n            \"last_name\": \"Bretherick\",\n            \"email\": \"dbretherickg@dmoz.org\",\n            \"gender\": \"Male\",\n            \"company\": \"Skipfire\"\n        }, {\n            \"id\": 18,\n            \"first_name\": \"Syman\",\n            \"last_name\": \"Lawdham\",\n            \"email\": \"slawdhamh@so-net.ne.jp\",\n            \"gender\": \"Male\",\n            \"company\": \"Wordify\"\n        }, {\n            \"id\": 19,\n            \"first_name\": \"Catarina\",\n            \"last_name\": \"Stoile\",\n            \"email\": \"cstoilei@hud.gov\",\n            \"gender\": \"Female\",\n            \"company\": \"Avaveo\"\n        }, {\n            \"id\": 20,\n            \"first_name\": \"Simonette\",\n            \"last_name\": \"Danett\",\n            \"email\": \"sdanettj@eepurl.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Realblab\"\n        }, {\n            \"id\": 21,\n            \"first_name\": \"Fielding\",\n            \"last_name\": \"MacHarg\",\n            \"email\": \"fmachargk@blogtalkradio.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Photolist\"\n        }, {\n            \"id\": 22,\n            \"first_name\": \"Anni\",\n            \"last_name\": \"Hounsom\",\n            \"email\": \"ahounsoml@wikia.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Devify\"\n        }, {\n            \"id\": 23,\n            \"first_name\": \"Evelin\",\n            \"last_name\": \"Gaytor\",\n            \"email\": \"egaytorm@myspace.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Aivee\"\n        }, {\n            \"id\": 24,\n            \"first_name\": \"Lynde\",\n            \"last_name\": \"Itscowicz\",\n            \"email\": \"litscowiczn@fc2.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Skipfire\"\n        }, {\n            \"id\": 25,\n            \"first_name\": \"Reta\",\n            \"last_name\": \"Felipe\",\n            \"email\": \"rfelipeo@free.fr\",\n            \"gender\": \"Female\",\n            \"company\": \"Ainyx\"\n        }, {\n            \"id\": 26,\n            \"first_name\": \"Bar\",\n            \"last_name\": \"Shillingford\",\n            \"email\": \"bshillingfordp@sun.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Skilith\"\n        }, {\n            \"id\": 27,\n            \"first_name\": \"Mel\",\n            \"last_name\": \"Cooch\",\n            \"email\": \"mcoochq@icq.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Meevee\"\n        }, {\n            \"id\": 28,\n            \"first_name\": \"Wheeler\",\n            \"last_name\": \"Kettlesting\",\n            \"email\": \"wkettlestingr@miitbeian.gov.cn\",\n            \"gender\": \"Male\",\n            \"company\": \"Mybuzz\"\n        }, {\n            \"id\": 29,\n            \"first_name\": \"Corabel\",\n            \"last_name\": \"Pordall\",\n            \"email\": \"cpordalls@sourceforge.net\",\n            \"gender\": \"Female\",\n            \"company\": \"Blogtag\"\n        }, {\n            \"id\": 30,\n            \"first_name\": \"Merrily\",\n            \"last_name\": \"Weatherhill\",\n            \"email\": \"mweatherhillt@printfriendly.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Divape\"\n        }, {\n            \"id\": 31,\n            \"first_name\": \"Reynard\",\n            \"last_name\": \"Osgodby\",\n            \"email\": \"rosgodbyu@eepurl.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Yakijo\"\n        }, {\n            \"id\": 32,\n            \"first_name\": \"Guilbert\",\n            \"last_name\": \"Bilston\",\n            \"email\": \"gbilstonv@devhub.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Vinder\"\n        }, {\n            \"id\": 33,\n            \"first_name\": \"Farr\",\n            \"last_name\": \"Skehan\",\n            \"email\": \"fskehanw@t-online.de\",\n            \"gender\": \"Male\",\n            \"company\": \"Linkbuzz\"\n        }, {\n            \"id\": 34,\n            \"first_name\": \"Roger\",\n            \"last_name\": \"Langelay\",\n            \"email\": \"rlangelayx@pcworld.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Tekfly\"\n        }, {\n            \"id\": 35,\n            \"first_name\": \"Jemmy\",\n            \"last_name\": \"Yggo\",\n            \"email\": \"jyggoy@ifeng.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Jabberstorm\"\n        }, {\n            \"id\": 36,\n            \"first_name\": \"Cybill\",\n            \"last_name\": \"Chastaing\",\n            \"email\": \"cchastaingz@mayoclinic.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Riffpedia\"\n        }, {\n            \"id\": 37,\n            \"first_name\": \"Samuele\",\n            \"last_name\": \"Zorzoni\",\n            \"email\": \"szorzoni10@opensource.org\",\n            \"gender\": \"Male\",\n            \"company\": \"Devcast\"\n        }, {\n            \"id\": 38,\n            \"first_name\": \"Svend\",\n            \"last_name\": \"Hamill\",\n            \"email\": \"shamill11@google.co.jp\",\n            \"gender\": \"Male\",\n            \"company\": \"Kwilith\"\n        }, {\n            \"id\": 39,\n            \"first_name\": \"Carlin\",\n            \"last_name\": \"Roote\",\n            \"email\": \"croote12@gov.uk\",\n            \"gender\": \"Male\",\n            \"company\": \"Twitterlist\"\n        }, {\n            \"id\": 40,\n            \"first_name\": \"Dawna\",\n            \"last_name\": \"Lanfer\",\n            \"email\": \"dlanfer13@mlb.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Jayo\"\n        }, {\n            \"id\": 41,\n            \"first_name\": \"Melissa\",\n            \"last_name\": \"Chappelow\",\n            \"email\": \"mchappelow14@usa.gov\",\n            \"gender\": \"Female\",\n            \"company\": \"Skibox\"\n        }, {\n            \"id\": 42,\n            \"first_name\": \"George\",\n            \"last_name\": \"Hargreaves\",\n            \"email\": \"ghargreaves15@pagesperso-orange.fr\",\n            \"gender\": \"Female\",\n            \"company\": \"Zazio\"\n        }, {\n            \"id\": 43,\n            \"first_name\": \"Sampson\",\n            \"last_name\": \"Steaning\",\n            \"email\": \"ssteaning16@state.gov\",\n            \"gender\": \"Male\",\n            \"company\": \"Jaxworks\"\n        }, {\n            \"id\": 44,\n            \"first_name\": \"Brana\",\n            \"last_name\": \"Wims\",\n            \"email\": \"bwims17@icio.us\",\n            \"gender\": \"Female\",\n            \"company\": \"Flashset\"\n        }, {\n            \"id\": 45,\n            \"first_name\": \"Shawn\",\n            \"last_name\": \"Saffen\",\n            \"email\": \"ssaffen18@shutterfly.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Twitterwire\"\n        }, {\n            \"id\": 46,\n            \"first_name\": \"Alessandro\",\n            \"last_name\": \"Gasker\",\n            \"email\": \"agasker19@slashdot.org\",\n            \"gender\": \"Male\",\n            \"company\": \"Dabtype\"\n        }, {\n            \"id\": 47,\n            \"first_name\": \"Bobby\",\n            \"last_name\": \"Mulcock\",\n            \"email\": \"bmulcock1a@time.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Quamba\"\n        }, {\n            \"id\": 48,\n            \"first_name\": \"Ashlen\",\n            \"last_name\": \"Midner\",\n            \"email\": \"amidner1b@devhub.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Thoughtstorm\"\n        }, {\n            \"id\": 49,\n            \"first_name\": \"Mallory\",\n            \"last_name\": \"Joel\",\n            \"email\": \"mjoel1c@upenn.edu\",\n            \"gender\": \"Male\",\n            \"company\": \"Twitterbeat\"\n        }, {\n            \"id\": 50,\n            \"first_name\": \"Maximilian\",\n            \"last_name\": \"Scraggs\",\n            \"email\": \"mscraggs1d@ucla.edu\",\n            \"gender\": \"Male\",\n            \"company\": \"Twiyo\"\n        }, {\n            \"id\": 51,\n            \"first_name\": \"Beverlie\",\n            \"last_name\": \"Pittet\",\n            \"email\": \"bpittet1e@github.io\",\n            \"gender\": \"Female\",\n            \"company\": \"Riffpath\"\n        }, {\n            \"id\": 52,\n            \"first_name\": \"Enrique\",\n            \"last_name\": \"Rentilll\",\n            \"email\": \"erentilll1f@smugmug.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Blognation\"\n        }, {\n            \"id\": 53,\n            \"first_name\": \"Cathrin\",\n            \"last_name\": \"McKendry\",\n            \"email\": \"cmckendry1g@hc360.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Shuffledrive\"\n        }, {\n            \"id\": 54,\n            \"first_name\": \"Isabeau\",\n            \"last_name\": \"Quincey\",\n            \"email\": \"iquincey1h@msn.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Tagcat\"\n        }, {\n            \"id\": 55,\n            \"first_name\": \"Geoffrey\",\n            \"last_name\": \"Grzegorczyk\",\n            \"email\": \"ggrzegorczyk1i@loc.gov\",\n            \"gender\": \"Male\",\n            \"company\": \"Youfeed\"\n        }, {\n            \"id\": 56,\n            \"first_name\": \"Ruggiero\",\n            \"last_name\": \"Vaar\",\n            \"email\": \"rvaar1j@unesco.org\",\n            \"gender\": \"Male\",\n            \"company\": \"Babbleset\"\n        }, {\n            \"id\": 57,\n            \"first_name\": \"Alfonso\",\n            \"last_name\": \"Tarzey\",\n            \"email\": \"atarzey1k@weebly.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Pixonyx\"\n        }, {\n            \"id\": 58,\n            \"first_name\": \"Marylin\",\n            \"last_name\": \"Bissex\",\n            \"email\": \"mbissex1l@microsoft.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Tagfeed\"\n        }, {\n            \"id\": 59,\n            \"first_name\": \"Cathryn\",\n            \"last_name\": \"Morhall\",\n            \"email\": \"cmorhall1m@irs.gov\",\n            \"gender\": \"Female\",\n            \"company\": \"Tagopia\"\n        }, {\n            \"id\": 60,\n            \"first_name\": \"Terza\",\n            \"last_name\": \"Easey\",\n            \"email\": \"teasey1n@thetimes.co.uk\",\n            \"gender\": \"Female\",\n            \"company\": \"Devcast\"\n        }, {\n            \"id\": 61,\n            \"first_name\": \"Hale\",\n            \"last_name\": \"Gaudon\",\n            \"email\": \"hgaudon1o@webnode.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Quinu\"\n        }, {\n            \"id\": 62,\n            \"first_name\": \"Hadley\",\n            \"last_name\": \"Elwood\",\n            \"email\": \"helwood1p@japanpost.jp\",\n            \"gender\": \"Male\",\n            \"company\": \"Plajo\"\n        }, {\n            \"id\": 63,\n            \"first_name\": \"Seamus\",\n            \"last_name\": \"Straker\",\n            \"email\": \"sstraker1q@live.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Yoveo\"\n        }, {\n            \"id\": 64,\n            \"first_name\": \"Urbano\",\n            \"last_name\": \"Gisbey\",\n            \"email\": \"ugisbey1r@sitemeter.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Quinu\"\n        }, {\n            \"id\": 65,\n            \"first_name\": \"Gerri\",\n            \"last_name\": \"McInulty\",\n            \"email\": \"gmcinulty1s@businessinsider.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Agimba\"\n        }, {\n            \"id\": 66,\n            \"first_name\": \"Lena\",\n            \"last_name\": \"Gonthier\",\n            \"email\": \"lgonthier1t@newsvine.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Geba\"\n        }, {\n            \"id\": 67,\n            \"first_name\": \"Ameline\",\n            \"last_name\": \"Wheatcroft\",\n            \"email\": \"awheatcroft1u@163.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Twitternation\"\n        }, {\n            \"id\": 68,\n            \"first_name\": \"Kathryn\",\n            \"last_name\": \"Castelli\",\n            \"email\": \"kcastelli1v@about.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Photospace\"\n        }, {\n            \"id\": 69,\n            \"first_name\": \"Terrell\",\n            \"last_name\": \"Walicki\",\n            \"email\": \"twalicki1w@amazon.co.jp\",\n            \"gender\": \"Male\",\n            \"company\": \"Babblestorm\"\n        }, {\n            \"id\": 70,\n            \"first_name\": \"Claudianus\",\n            \"last_name\": \"Tremathack\",\n            \"email\": \"ctremathack1x@walmart.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Skyndu\"\n        }, {\n            \"id\": 71,\n            \"first_name\": \"Sanford\",\n            \"last_name\": \"Devinn\",\n            \"email\": \"sdevinn1y@ehow.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Dynazzy\"\n        }, {\n            \"id\": 72,\n            \"first_name\": \"Gwendolen\",\n            \"last_name\": \"Turfrey\",\n            \"email\": \"gturfrey1z@va.gov\",\n            \"gender\": \"Female\",\n            \"company\": \"Yacero\"\n        }, {\n            \"id\": 73,\n            \"first_name\": \"Alta\",\n            \"last_name\": \"Leap\",\n            \"email\": \"aleap20@ezinearticles.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Twitterlist\"\n        }, {\n            \"id\": 74,\n            \"first_name\": \"Johnath\",\n            \"last_name\": \"Andrzejowski\",\n            \"email\": \"jandrzejowski21@google.com.hk\",\n            \"gender\": \"Female\",\n            \"company\": \"Lazzy\"\n        }, {\n            \"id\": 75,\n            \"first_name\": \"Yancy\",\n            \"last_name\": \"Askham\",\n            \"email\": \"yaskham22@sciencedaily.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Yabox\"\n        }, {\n            \"id\": 76,\n            \"first_name\": \"Paula\",\n            \"last_name\": \"Warder\",\n            \"email\": \"pwarder23@harvard.edu\",\n            \"gender\": \"Female\",\n            \"company\": \"Zooxo\"\n        }, {\n            \"id\": 77,\n            \"first_name\": \"Grannie\",\n            \"last_name\": \"Hauxley\",\n            \"email\": \"ghauxley24@symantec.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Yakidoo\"\n        }, {\n            \"id\": 78,\n            \"first_name\": \"Enid\",\n            \"last_name\": \"Grealy\",\n            \"email\": \"egrealy25@homestead.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Gabcube\"\n        }, {\n            \"id\": 79,\n            \"first_name\": \"Lazarus\",\n            \"last_name\": \"Itscowicz\",\n            \"email\": \"litscowicz26@epa.gov\",\n            \"gender\": \"Male\",\n            \"company\": \"Demizz\"\n        }, {\n            \"id\": 80,\n            \"first_name\": \"Marmaduke\",\n            \"last_name\": \"Gilligan\",\n            \"email\": \"mgilligan27@tiny.cc\",\n            \"gender\": \"Male\",\n            \"company\": \"Yombu\"\n        }, {\n            \"id\": 81,\n            \"first_name\": \"Linnell\",\n            \"last_name\": \"Chree\",\n            \"email\": \"lchree28@ocn.ne.jp\",\n            \"gender\": \"Female\",\n            \"company\": \"Buzzshare\"\n        }, {\n            \"id\": 82,\n            \"first_name\": \"Pavia\",\n            \"last_name\": \"Pocke\",\n            \"email\": \"ppocke29@newsvine.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Eidel\"\n        }, {\n            \"id\": 83,\n            \"first_name\": \"Golda\",\n            \"last_name\": \"Stuchburie\",\n            \"email\": \"gstuchburie2a@oaic.gov.au\",\n            \"gender\": \"Female\",\n            \"company\": \"Flipstorm\"\n        }, {\n            \"id\": 84,\n            \"first_name\": \"Trace\",\n            \"last_name\": \"Lodge\",\n            \"email\": \"tlodge2b@whitehouse.gov\",\n            \"gender\": \"Male\",\n            \"company\": \"Zazio\"\n        }, {\n            \"id\": 85,\n            \"first_name\": \"Nikolia\",\n            \"last_name\": \"Bartolomivis\",\n            \"email\": \"nbartolomivis2c@opensource.org\",\n            \"gender\": \"Female\",\n            \"company\": \"Devshare\"\n        }, {\n            \"id\": 86,\n            \"first_name\": \"Dela\",\n            \"last_name\": \"Wimp\",\n            \"email\": \"dwimp2d@miitbeian.gov.cn\",\n            \"gender\": \"Female\",\n            \"company\": \"Wordware\"\n        }, {\n            \"id\": 87,\n            \"first_name\": \"Rustie\",\n            \"last_name\": \"Drury\",\n            \"email\": \"rdrury2e@sun.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Youbridge\"\n        }, {\n            \"id\": 88,\n            \"first_name\": \"Phedra\",\n            \"last_name\": \"Shrimptone\",\n            \"email\": \"pshrimptone2f@unicef.org\",\n            \"gender\": \"Female\",\n            \"company\": \"Realcube\"\n        }, {\n            \"id\": 89,\n            \"first_name\": \"Alaster\",\n            \"last_name\": \"Vittori\",\n            \"email\": \"avittori2g@senate.gov\",\n            \"gender\": \"Male\",\n            \"company\": \"Livepath\"\n        }, {\n            \"id\": 90,\n            \"first_name\": \"Pascal\",\n            \"last_name\": \"Neissen\",\n            \"email\": \"pneissen2h@mediafire.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Mydo\"\n        }, {\n            \"id\": 91,\n            \"first_name\": \"Brian\",\n            \"last_name\": \"Manuel\",\n            \"email\": \"bmanuel2i@blog.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Roomm\"\n        }, {\n            \"id\": 92,\n            \"first_name\": \"Jen\",\n            \"last_name\": \"Laydon\",\n            \"email\": \"jlaydon2j@hubpages.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Plambee\"\n        }, {\n            \"id\": 93,\n            \"first_name\": \"Beltran\",\n            \"last_name\": \"Brandoni\",\n            \"email\": \"bbrandoni2k@digg.com\",\n            \"gender\": \"Male\",\n            \"company\": \"Yacero\"\n        }, {\n            \"id\": 94,\n            \"first_name\": \"Sarene\",\n            \"last_name\": \"Gaymar\",\n            \"email\": \"sgaymar2l@surveymonkey.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Katz\"\n        }, {\n            \"id\": 95,\n            \"first_name\": \"Iormina\",\n            \"last_name\": \"Peedell\",\n            \"email\": \"ipeedell2m@seattletimes.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Youfeed\"\n        }, {\n            \"id\": 96,\n            \"first_name\": \"Abigail\",\n            \"last_name\": \"Kielty\",\n            \"email\": \"akielty2n@npr.org\",\n            \"gender\": \"Female\",\n            \"company\": \"Reallinks\"\n        }, {\n            \"id\": 97,\n            \"first_name\": \"Hallie\",\n            \"last_name\": \"Toomey\",\n            \"email\": \"htoomey2o@google.com.au\",\n            \"gender\": \"Female\",\n            \"company\": \"Flipbug\"\n        }, {\n            \"id\": 98,\n            \"first_name\": \"Sergeant\",\n            \"last_name\": \"Pourveer\",\n            \"email\": \"spourveer2p@amazon.co.uk\",\n            \"gender\": \"Male\",\n            \"company\": \"Skinix\"\n        }, {\n            \"id\": 99,\n            \"first_name\": \"Elfie\",\n            \"last_name\": \"McKinlay\",\n            \"email\": \"emckinlay2q@xrea.com\",\n            \"gender\": \"Female\",\n            \"company\": \"Devcast\"\n        }, {\n            \"id\": 100,\n            \"first_name\": \"Wainwright\",\n            \"last_name\": \"Juggins\",\n            \"email\": \"wjuggins2r@tamu.edu\",\n            \"gender\": \"Male\",\n            \"company\": \"Topiclounge\"\n        }];\n\n\n\n        const contacts = contactsData.map(d => new Person(d.id, d.first_name, d.last_name, d.email, d.gender, d.company));\n        return contacts;\n    }\n\n    public static loadCompanies() {\n        const companies = [{\n            \"id\": 101,\n            \"city\": \"Lakshmīpur\",\n            \"street\": \"36300 Lake View Center\",\n            \"email\": \"ogovier0@gmpg.org\",\n            \"company\": \"Fiveclub\"\n        }, {\n            \"id\": 102,\n            \"city\": \"El Quetzal\",\n            \"street\": \"551 New Castle Parkway\",\n            \"email\": \"elander1@g.co\",\n            \"company\": \"Twitterwire\"\n        }, {\n            \"id\": 103,\n            \"city\": \"Mayakovski\",\n            \"street\": \"1 Norway Maple Center\",\n            \"email\": \"dcustance2@hostgator.com\",\n            \"company\": \"Jabbersphere\"\n        }, {\n            \"id\": 104,\n            \"city\": \"Al Jawādīyah\",\n            \"street\": \"02 Carey Hill\",\n            \"email\": \"evanoort3@sciencedaily.com\",\n            \"company\": \"Zoovu\"\n        }, {\n            \"id\": 105,\n            \"city\": \"Girona\",\n            \"street\": \"3 Lillian Center\",\n            \"email\": \"dducker4@cbsnews.com\",\n            \"company\": \"Innojam\"\n        }, {\n            \"id\": 106,\n            \"city\": \"Vouani\",\n            \"street\": \"5165 Vera Avenue\",\n            \"email\": \"orzehorz5@arizona.edu\",\n            \"company\": \"Zoovu\"\n        }, {\n            \"id\": 107,\n            \"city\": \"Caibarién\",\n            \"street\": \"3739 Burrows Drive\",\n            \"email\": \"ltrahair6@pinterest.com\",\n            \"company\": \"Quamba\"\n        }, {\n            \"id\": 108,\n            \"city\": \"Wushi\",\n            \"street\": \"88 Bay Hill\",\n            \"email\": \"plebourn7@springer.com\",\n            \"company\": \"Feednation\"\n        }, {\n            \"id\": 109,\n            \"city\": \"Zbýšov\",\n            \"street\": \"38 Dovetail Place\",\n            \"email\": \"slace8@netscape.com\",\n            \"company\": \"Zoomzone\"\n        }, {\n            \"id\": 110,\n            \"city\": \"Nová Cerekev\",\n            \"street\": \"90194 Dixon Avenue\",\n            \"email\": \"mdoxey9@goo.gl\",\n            \"company\": \"Devpoint\"\n        }];\n\n        return companies.map(c => new Company(c.id, c.company, c.street, c.email));\n    }\n\n    public static loadContacts() {\n        const result = new Array<Person | Company>();\n        result.push(...this.loadPersons());\n        result.push(...this.loadCompanies());\n        let idx = 0;\n        while (idx++ < 1000) {\n            const i = Math.round(Math.random() * (result.length - 1));\n            const j = Math.round(Math.random() * (result.length - 1));\n            const temp = result[i];\n            result[i] = result[j];\n            result[j] = temp;\n        }\n        return result;\n    }\n}\n\n\nconst contacts = AddressBook.loadContacts();\n\ndebugger;\n"
  },
  {
    "path": "demos/js/src/demo_custom-data-extractor.ts",
    "content": "import { getDataExtractorApi } from \"@hediet/debug-visualizer-data-extraction\";\n\n// Registers all existing extractors.\ngetDataExtractorApi().registerDefaultExtractors();\n\ngetDataExtractorApi().registerExtractor({\n\tid: \"my-extractor\",\n\tgetExtractions: (data, collector) => {\n\t\tif (data instanceof Foo) {\n\t\t\tcollector.addExtraction({\n\t\t\t\tid: \"my-extractor\",\n\t\t\t\tname: \"My Extractor\",\n\t\t\t\tpriority: 2000,\n\t\t\t\textractData: () => ({ kind: { text: true }, text: \"Foo\" }),\n\t\t\t});\n\t\t}\n\t},\n});\n\nsetTimeout(() => {\n\tnew Main().run();\n}, 0);\n\nclass Foo {}\n\nclass Main {\n\trun() {\n\t\tconst f = new Foo();\n\t\t// visualize `f` here!\n\t\tdebugger;\n\t}\n}\n"
  },
  {
    "path": "demos/js/src/demo_doubly-linked-list.ts",
    "content": "import {\n\tgetDataExtractorApi,\n\tcreateGraphFromPointers,\n} from \"@hediet/debug-visualizer-data-extraction\";\n\ngetDataExtractorApi().registerDefaultExtractors();\n\nsetTimeout(() => {\n\tnew Main().run();\n}, 0);\n\nclass Main {\n\t/** @pure */\n\trun() {\n\t\tid = 0;\n\t\tconst head = new DoublyLinkedListNode(\"1\");\n\t\thead.setNext(new DoublyLinkedListNode(\"2\"));\n\t\thead.next!.setNext(new DoublyLinkedListNode(\"3\"));\n\t\tconst tail = new DoublyLinkedListNode(\"4\");\n\t\thead.next!.next!.setNext(tail);\n\t\treverse(new DoublyLinkedList(head, tail));\n\t\tconsole.log(\"finished\");\n\t}\n}\n\nfunction reverse(list: DoublyLinkedList) {\n\t// Open a new Debug Visualizer\n\t// and enter `visualize()`!\n\tconst visualize = () =>\n\t\tcreateGraphFromPointers(\n\t\t\t{\n\t\t\t\tlast,\n\t\t\t\t\"list.head\": list.head,\n\t\t\t\t\"list.tail\": list.tail\n\t\t\t},\n\t\t\ti => ({\n\t\t\t\tid: i.id,\n\t\t\t\tlabel: i.name,\n\t\t\t\tcolor: finished.has(i) ? \"lime\" : \"lightblue\",\n\t\t\t\tedges: [\n\t\t\t\t\t{ to: i.next!, label: \"next\", color: \"lightblue\", },\n\t\t\t\t\t{ to: i.prev!, label: \"prev\", color: \"lightgray\" },\n\t\t\t\t].filter(r => !!r.to),\n\t\t\t}));\n\n\t// Finished nodes have correct pointers,\n\t// their next node is also finished.\n\tconst finished = new Set();\n\tvar last: DoublyLinkedListNode | null = null;\n\tlist.tail = list.head;\n\twhile (list.head) {\n\t\tlist.head.prev = list.head.next;\n\t\tlist.head.next = last;\n\t\tfinished.add(list.head);\n\t\tlast = list.head;\n\t\tlist.head = list.head.prev;\n\t}\n\tlist.head = last;\n}\n\nclass DoublyLinkedList {\n\tconstructor(\n\t\tpublic head: DoublyLinkedListNode | null,\n\t\tpublic tail: DoublyLinkedListNode | null\n\t) { }\n}\n\nlet id = 0;\nclass DoublyLinkedListNode {\n\tpublic readonly id = (id++).toString();\n\tconstructor(public name: string) { }\n\n\tnext: DoublyLinkedListNode | null = null;\n\tprev: DoublyLinkedListNode | null = null;\n\n\tpublic setNext(val: DoublyLinkedListNode): void {\n\t\tval.prev = this;\n\t\tthis.next = val;\n\t}\n}\n"
  },
  {
    "path": "demos/js/src/demo_fetch.js",
    "content": "const fetch = require(\"node-fetch\");\n\nfetch(\"https://jsonplaceholder.typicode.com/users\")\n    .then((response) => response.json())\n    .then((json) => {\n        debugger;\n    });\n"
  },
  {
    "path": "demos/js/src/demo_random-walks.ts",
    "content": "// visualize `data`\nconst data = new Array<number>();\nlet curValue = 0;\n\nfor (let j = 0; j < 100; j++) {\n\taddManyRandomValues();\n}\n\nfunction addManyRandomValues() {\n\tfor (let i = 0; i < 100; i++) {\n\t\taddRandomValue();\n\t}\n}\n\nfunction addRandomValue() {\n\tconst delta = Math.random()\n\t\t> 0.5 ? 1 : -1;\n\tdata.push(curValue);\n\tcurValue += delta;\n}"
  },
  {
    "path": "demos/js/src/demo_singly-linked-list.js",
    "content": "// See https://codeburst.io/linked-lists-in-javascript-es6-code-part-1-6dd349c3dcc3\n/*\nAfter install the Debug Visualizer extension,\npress F1, enter \"Open Debug Visualizer\" and\nuse the following code as expression to visualize.\nThen, press F5 and chose \"node\".\n```\nhedietDbgVis.createGraphFromPointers(\n\thedietDbgVis.tryEval([\n\t\t\"list.head\",\n\t\t\"newNode\",\n\t\t\"node\",\n\t\t\"previous\",\n\t\tthis.constructor.name === \"LinkedList\" ? \"this.head\" : \"err\",\n\t]),\n\tn => ({\n\t\tid: n.data,\n\t\tcolor: \"lightblue\",\n\t\tlabel: `${n.data}`,\n\t\tedges: [{ to: n.next, label: \"next\" }].filter(i => !!i.to),\n\t})\n)\n```\n\n*/\n\nclass LinkedList {\n\tconstructor() {\n\t\tthis.head = null;\n\t}\n}\n\nclass Node {\n\tconstructor(data, next = null) {\n\t\t(this.data = data), (this.next = next);\n\t}\n}\n\nLinkedList.prototype.insertAtBeginning = function(data) {\n\t// A newNode object is created with property data\n\t// and next = null\n\tlet newNode = new Node(data);\n\t// The pointer next is assigned head pointer\n\t// so that both pointers now point at the same node.\n\tnewNode.next = this.head;\n\t// As we are inserting at the beginning the head pointer\n\t// needs to now point at the newNode.\n\tthis.head = newNode;\n\treturn this.head;\n};\n\nLinkedList.prototype.getAt = function(index) {\n\tlet counter = 0;\n\tlet node = this.head;\n\twhile (node) {\n\t\tif (counter === index) {\n\t\t\treturn node;\n\t\t}\n\t\tcounter++;\n\t\tnode = node.next;\n\t}\n\treturn null;\n};\n\n// The insertAt() function contains the steps to insert\n// a node at a given index.\nLinkedList.prototype.insertAt = function(data, index) {\n\t// if the list is empty i.e. head = null\n\tif (!this.head) {\n\t\tthis.head = new Node(data);\n\t\treturn;\n\t}\n\t// if new node needs to be inserted at the front\n\t// of the list i.e. before the head.\n\tif (index === 0) {\n\t\tthis.head = new Node(data, this.head);\n\t\treturn;\n\t}\n\t// else, use getAt() to find the previous node.\n\tconst previous = this.getAt(index - 1);\n\tlet newNode = new Node(data);\n\tnewNode.next = previous.next;\n\tprevious.next = newNode;\n\n\treturn this.head;\n};\n\nconst list = new LinkedList();\ndebugger; // Press F10 to continue\nlist.insertAtBeginning(\"4\");\nlist.insertAtBeginning(\"3\");\nlist.insertAtBeginning(\"2\");\nlist.insertAtBeginning(\"1\");\n\nlist.insertAt(\"3.5\", 3);\n\nconsole.log(\"finished\");\n\n// Some Plotting.\n// Use `data` as expression to visualize.\nconst data = [];\nfor (let x = 0; x < 1000; x += 1) {\n\tdata.push(Math.sin(x / 10));\n\n\tif (x % 10 === 0) {\n\t\tconsole.log(\"step\");\n\t}\n}\n"
  },
  {
    "path": "demos/js/src/demo_sorting.ts",
    "content": "import { getDataExtractorApi } from \"@hediet/debug-visualizer-data-extraction\";\n\ngetDataExtractorApi().registerDefaultExtractors();\n\n/*\nVisualize this expression:\n```ts\nhedietDbgVis.markedGrid(\n    array,\n    hedietDbgVis.tryEval([\"i\", \"j\", \"left\", \"right\"])\n)\n```\n*/\n\n// From https://github.com/AvraamMavridis/Algorithms-Data-Structures-in-Typescript/blob/master/algorithms/quickSort.md\n/** @pure */\nfunction main() {\n\tconst array = [1, 2, 33, 31, 1, 2, 63, 123, 6, 32, 943, 346, 24];\n\tconst sorted = quickSort(array, 0, array.length - 1);\n\tconsole.log(sorted);\n}\nmain();\n\nfunction swap(array: Array<number>, i: number, j: number) {\n\t[array[i], array[j]] = [array[j], array[i]];\n}\n\n/**\n * Split array and swap values\n *\n * @param {Array<number>} array\n * @param {number} [left=0]\n * @param {number} [right=array.length - 1]\n * @returns {number}\n */\nfunction partition(\n\tarray: Array<number>,\n\tleft: number = 0,\n\tright: number = array.length - 1\n) {\n\tconst pivot = Math.floor((right + left) / 2);\n\tconst pivotVal = array[pivot];\n\tlet i = left;\n\tlet j = right;\n\n\twhile (i <= j) {\n\t\twhile (array[i] < pivotVal) {\n\t\t\ti++;\n\t\t}\n\n\t\twhile (array[j] > pivotVal) {\n\t\t\tj--;\n\t\t}\n\n\t\tif (i <= j) {\n\t\t\tswap(array, i, j);\n\t\t\ti++;\n\t\t\tj--;\n\t\t}\n\t}\n\n\treturn i;\n}\n\n/**\n * Quicksort implementation\n *\n * @param {Array<number>} array\n * @param {number} [left=0]\n * @param {number} [right=array.length - 1]\n * @returns {Array<number>}\n */\nfunction quickSort(\n\tarray: Array<number>,\n\tleft: number = 0,\n\tright: number = array.length - 1\n) {\n\tlet index;\n\n\tif (array.length > 1) {\n\t\tindex = partition(array, left, right);\n\n\t\tif (left < index - 1) {\n\t\t\tquickSort(array, left, index - 1);\n\t\t}\n\n\t\tif (index < right) {\n\t\t\tquickSort(array, index, right);\n\t\t}\n\t}\n\n\treturn array;\n}\n"
  },
  {
    "path": "demos/js/src/demo_stack-frames.js",
    "content": "\nfunction test() {\n    let i = 1;\n    debugger;\n}\n\nlet i = 0;\ntest();"
  },
  {
    "path": "demos/js/src/demo_typescript-asts.ts",
    "content": "import * as ts from \"typescript\";\nimport { getDataExtractorApi } from \"@hediet/debug-visualizer-data-extraction\";\nimport { MockLanguageServiceHost } from \"./MockLanguageServiceHost\";\n\n// Registers all existing extractors.\ngetDataExtractorApi().registerDefaultExtractors();\n\nsetTimeout(() => {\n\tnew Main().run();\n}, 0);\n\nclass Main {\n\trun() {\n\t\t/*const files = new Map<string, string>([\n\t\t\t[\n\t\t\t\t\"main.ts\",\n\t\t\t\t`\nclass Test1 {\n\tpublic foo(a: number) {\n\t\tconst x = { a: 5 };\n\t\tconst y = { a: 5 };\n\t}\n}\n`,\n\t\t\t],\n\t\t]);\n\t\tconst serviceHost = new MockLanguageServiceHost(files, {});\n\t\tconst baseService = ts.createLanguageService(\n\t\t\tserviceHost,\n\t\t\tts.createDocumentRegistry()\n\t\t);\n\t\tconst prog = baseService.getProgram()!;\n\t\tdebugger;\n\n\t\tconst c = prog.getTypeChecker();\n\t\tlet myValue = undefined; // Visualize `myValue` here!\n\t\tconst sourceFileAst = prog.getSourceFiles()[0];\n\t\tmyValue = sourceFileAst;\n\t\tconsole.log(\"myValue is the source code of the AST\");\n\t\tdebugger;\n\n\t\tmyValue = {\n\t\t\tsf: sourceFileAst,\n\t\t\tfn: (n: ts.Node) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst t = c.getTypeAtLocation(n);\n\t\t\t\t\treturn t ? c.typeToString(t) : undefined;\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn \"\" + e;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tconsole.log(\"myValue is AST, annotated with type information\");\n\t\tdebugger;\n\n\t\tmyValue = {\n\t\t\tsf: sourceFileAst,\n\t\t\tfn: (n: ts.Node) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst t = c.getSymbolAtLocation(n);\n\t\t\t\t\treturn t ? ts.SymbolFlags[t.flags] : undefined;\n\t\t\t\t} catch (e) {\n\t\t\t\t\treturn \"\" + e;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tconsole.log(\"myValue is AST, annotated with symbol information\");\n\t\tdebugger;*/\n\t\trequire;\n\n\t\tconst sf = ts.createSourceFile(\"main.ts\",\n\t\t\t`\nclass Test1 {\n\tpublic foo(a: number) {\n\t\tconst x = { a: 5 };\n\t\tconst y = { a: 24 };\n\t}\n}\n\t\t\t`, ts.ScriptTarget.ESNext, true);\n\t\tconst traverse = (node: ts.Node) => {\n\t\t\tts.forEachChild(node, child => {\n\t\t\t\ttraverse(child);\n\t\t\t});\n\t\t};\n\t\ttraverse(sf);\n\t}\n}\n\n/*\n\t\tmyValue = {\n\t\t\tkind: { text: true, svg: true },\n\t\t\ttext: `\n\t\t\t\t<svg height=\"210\" width=\"500\">\n\t\t\t\t\t<polygon\n\t\t\t\t\t\tpoints=\"100,10 40,198 190,78 10,78 160,198\"\n\t\t\t\t\t\tstyle=\"fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t  \t\t`,\n\t\t};*/\n"
  },
  {
    "path": "demos/js/src/playground.ts",
    "content": "import {\n\tenableHotReload,\n\tregisterUpdateReconciler,\n\tgetReloadCount,\n\thotCallExportedFunction,\n} from \"@hediet/node-reload\";\n\nenableHotReload();\nregisterUpdateReconciler(module);\n\nimport { registerDefaultExtractors } from \"@hediet/debug-visualizer-data-extraction\";\nregisterDefaultExtractors();\n\nif (getReloadCount(module) === 0) {\n\t// set interval so that the file watcher can detect changes in other files.\n\tsetInterval(() => {\n\t\thotCallExportedFunction(module, run);\n\t}, 1000);\n}\n\nexport function run() {\n\tnew Demo().run();\n}\n\nclass Demo {\n\tprivate f = new Foo(new Foo(undefined));\n\tprivate arr = [new Foo(this.f), this.f];\n\tprivate set = new Set([this.arr[0], new Foo(new Foo(this.arr[1]))]);\n\n\trun() {\n\t\tdebugger;\n\t}\n}\n\nclass Foo {\n\tconstructor(public readonly next: Foo | undefined) {}\n}\n"
  },
  {
    "path": "demos/js/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"esnext\",\n\t\t\"module\": \"commonjs\",\n\t\t\"strict\": true,\n\t\t\"outDir\": \"dist\",\n\t\t\"skipLibCheck\": true,\n\t\t\"rootDir\": \"./src\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true,\n\t\t\"newLine\": \"LF\",\n\t\t\"sourceMap\": true,\n\t\t\"experimentalDecorators\": true\n\t},\n\t\"include\": [\"src/**/*\"]\n}\n"
  },
  {
    "path": "demos/nim/.vscode/launch.json",
    "content": "{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"type\": \"lldb\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"name\": \"Run your Executable\",\n\t\t\t\"program\": \"${workspaceFolder}/main\",\n\t\t\t\"args\": [],\n\t\t\t\"cwd\": \"${workspaceFolder}\",\n\t\t\t\"initCommands\": [\n\t\t\t\t// To let LLDB know that NCSTRING is just like a C string\n\t\t\t\t\"type format add --format c-string NCSTRING\"\n\t\t\t],\n\t\t\t\"preLaunchTask\": \"build\"\n\t\t}\n\t]\n}"
  },
  {
    "path": "demos/nim/.vscode/tasks.json",
    "content": "{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t{\n\t\t\t\"label\": \"build\",\n\t\t\t\"type\": \"shell\",\n\t\t\t\"command\": \"nim c main.nim\"\n\t\t}\n\t]\n}"
  },
  {
    "path": "demos/nim/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Danil Yarantsev\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject 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,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "demos/nim/main.nim",
    "content": "import random, json, options, sugar\n\ntype\n  Kind = object\n    array: bool\n  \n  Label = object\n    label: Option[string]\n  \n  Column = object\n    content: Option[string]\n    tag: Option[string]\n    color: Option[string]\n  \n  Row = object\n    label: Option[string]\n    columns: seq[Column]\n  \n  Marker = object\n    id: string\n    row: int\n    column: int\n    rows: Option[int]\n    columns: Option[int]\n    label: Option[string]\n    color: Option[string]\n  \n  Grid = object\n    kind: Kind\n    columnLabels: Option[seq[Label]]\n    rows: seq[Row]\n    markers: Option[seq[Marker]]\n\nproc showSeq[T](data: seq[T], markers: seq[(string, int)] = @[]): cstring = \n  # Need to use cstring string type for C-compatible strings\n  let labels = collect(newSeq):\n    # Labels are indexes of the seq\n    for x in 0 ..< data.len():\n      Label(label: some($x))\n  \n  let columns = collect(newSeq):\n    # Columns contain values of the seq\n    for x in data:\n      Column(content: some($x), tag: some($x))\n  \n  let marks = collect(newSeq):\n    # If there are any markers (id - string, index - int)\n    for marker in markers:\n      Marker(id: marker[0], row: 0, column: marker[1])\n\n  let grid = Grid(\n    kind: Kind(array: true),\n    rows: @[Row(columns: columns)],\n    columnLabels: some(labels),\n    markers: some(marks)\n  )\n  # Serialize to JSON\n  result = $ %grid\n\nproc main = \n  # Random seed\n  randomize()\n\n  # Fill seq with 10 random values from 1 to 999\n  var a = newSeq[int]()\n  for x in 0..10:\n    a.add rand(1..999)\n  \n  # Simple bubble sort with some markers\n  # Open the visualizer and type in \"ress\"\n  let n = a.len() - 1\n  var ress = showSeq(a, @[(\"i\", 0), (\"j\", 0)])\n  for i in 0 .. n:\n    for j in 0 .. n - i - 1:\n      if a[j] > a[j+1]:\n        ress = showSeq(a, @[(\"i\", i), (\"j\", j)]) # breakpoint\n        let temp = a[j]\n        a[j] = a[j + 1]\n        a[j + 1] = temp\n        ress = showSeq(a, @[(\"i\", i), (\"j\", j)]) # breakpoint\n\nmain()"
  },
  {
    "path": "demos/nim/nim.cfg",
    "content": "# For Nim source code lines\ndebugger:native"
  },
  {
    "path": "demos/php/.vscode/launch.json",
    "content": "{\n\t// Use IntelliSense to find out which attributes exist for C# debugging\n\t// Use hover for the description of the existing attributes\n\t// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"name\": \"PHP - Demo\",\n\t\t\t\"type\": \"php\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"program\": \"${workspaceFolder}/demo.php\",\n\t\t\t\"xdebugSettings\": {\n\t\t\t\t\"max_data\": -1\n\t\t\t}\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/php/.vscode/settings.json",
    "content": "{\n\t\"debugVisualizer.debugAdapterConfigurations\": {\n\t\t\"php\": {\n\t\t\t\"context\": \"watch\",\n\t\t\t\"expressionTemplate\": \"${expr}\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "demos/php/demo.php",
    "content": "<?php\n\n// Install php, xdebug and the php debug extension for VS Code\n// (https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug).\n\n// The Debug Visualizer has no support for PHP data extractors yet,\n// so to visualize data, your value must be a valid JSON string representing the data.\n// See readme for supported data schemas.\n\n$graph = [\n    \"kind\" => [\"graph\" => true],\n    \"nodes\" => [\n        [\"id\" => \"1\", \"label\" => \"1\"]\n    ],\n    \"edges\" => []\n];\n// Visualize \"$visualize()\"\n$visualize = function () use (&$graph) {\n    return json_encode($graph);\n};\n\nfor ($i = 2; $i < 100; $i++) {\n    // add a node\n    $id = \"\" . $i;\n    array_push($graph[\"nodes\"],\n        [\"id\" => $id, \"label\" => $id]);\n    // connects the node to a random edge\n    $targetId = \"\" . random_int(1, $i - 1);\n    array_push($graph[\"edges\"],\n        [\"from\" => $id, \"to\" => \"\" . $targetId]);\n}\n\necho \"finished\";\n"
  },
  {
    "path": "demos/python/.vscode/launch.json",
    "content": "{\n\t// Use IntelliSense to find out which attributes exist for C# debugging\n\t// Use hover for the description of the existing attributes\n\t// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md\n\t\"version\": \"0.2.0\",\n\t\"configurations\": []\n}\n"
  },
  {
    "path": "demos/python/Person.py",
    "content": "class Person:\n    def __init__(self, name, parents=None) -> None:\n        self.name = name\n        self.parents = [] if parents is None else parents\n\n    def addParent(self, parent: \"Person\"):\n        self.parents.append(parent)\n"
  },
  {
    "path": "demos/python/debugvisualizer.py",
    "content": "from Person import Person\nimport json\nfrom vscodedebugvisualizer import globalVisualizationFactory\n\n\nclass PersonVisualizer:\n    def checkType(self, t):\n        return isinstance(t, Person)\n\n    def visualizePerson(self, person: Person, nodes=[], edges=[]):\n        if person.name in [n[\"id\"] for n in nodes]:\n            return nodes, edges\n\n        nodes.append(\n            {\n                \"id\": person.name,\n                \"label\": person.name,\n            }\n        )\n\n        for p in person.parents:\n            nodes, edges = self.visualizePerson(p, nodes, edges)\n            edges.append(\n                {\n                    \"from\": p.name,\n                    \"to\": person.name,\n                }\n            )\n\n        return nodes, edges\n\n    def visualize(self, person: Person):\n        jsonDict = {\n            \"kind\": {\"graph\": True},\n            \"nodes\": [],\n            \"edges\": [],\n        }\n\n        self.visualizePerson(person, jsonDict[\"nodes\"], jsonDict[\"edges\"])\n\n        return json.dumps(jsonDict)\n\n\nglobalVisualizationFactory.addVisualizer(PersonVisualizer())\n"
  },
  {
    "path": "demos/python/demo.py",
    "content": "import numpy as np\n\n\n# put \"x\" in the Debug Visualizer and use step by step\n# debugging to see the diffrent types of data visualization\n\n\nx = 5\nx = \"asdf\"\nx = 5.5\nx = [1, 2, 3, 4, 5, 6, \"a\", \"b\"]\nx = [\"b\", \"a\", \"c\", \"d\", \"e\"]\nx.sort()\nx = {\n    \"asdf1\": \"dasdf\",\n    \"asdf2\": \"dasdf\",\n    \"asdf3\": {\"foo\": \"bar\"},\n}\n\nx = [1, 2, 3, 4, 5, 6]\n# histogram\nx = np.concatenate([np.arange(i) for i in range(9)])\nx = x.reshape(2, -1)\n\n\n# one dimension\nx = np.arange(100)\nx = np.linspace(-np.pi, np.pi, 100)\nx = np.sin(x)\n\n# 2 dimension\nx = x.reshape(5, 20)\n# 2 dimension transpose\nx = x.transpose()\nx = x.transpose()\n\n# 3 dimensions\nx = x.reshape(2, 5, 10)\n\n# 4 dimensions\nx = x.reshape(2, 5, 2, 5)\n\n# big number\nx = np.empty(2 ** 24)\nx[0:1000000] = 1\nx[1000000:10000000] = 5\n\n# pyTorch\ntry:\n    import torch\n\n    x = np.concatenate([np.arange(i) for i in range(9)])\n    x = x.reshape(2, -1)\n    x = torch.Tensor(x)\n    pass\n\nexcept ImportError:\n    pass\n\n\n# tensorflow\n\ntry:\n    import tensorflow as tf\n\n    x = np.concatenate([np.arange(i) for i in range(9)])\n    x = x.reshape(2, -1)\n    x = tf.convert_to_tensor(x)\n    pass\nexcept ImportError:\n    pass\n\n\n# pandas\n\ntry:\n    import pandas as pd\n    import plotly.express as px\n\n    x = px.data.gapminder().query(\"year == 2007\")\n    pass\nexcept ImportError:\n    pass\n\n# custom visualizer defined in ./debugvisualizer.py (this file is included automatically)\n\nfrom Person import Person\n\nx = Person(\"Aria\")\nparent1 = Person(\"Eduart\")\nparent2 = Person(\"Catelyn\")\nx.addParent(parent1)\nx.addParent(parent2)\nparent1.addParent(Person(\"Benjen\"))\n\n# direct debug-visualizer json as dict with property \"kind\"\n\nx = {\n    \"kind\": {\"dotGraph\": True},\n    \"text\": '\\ndigraph G {\\n    subgraph cluster_0 {\\n      style=filled;\\n      color=lightgrey;\\n      node [style=filled,color=white];\\n      a0 -> a1 -> a2 -> a3;\\n      label = \"process #1\";\\n    }\\n  \\n    subgraph cluster_1 {\\n      node [style=filled];\\n      b0 -> b1 -> b2 -> b3;\\n      label = \"process #2\";\\n      color=blue\\n    }\\n    start -> a0;\\n    start -> b0;\\n    a1 -> b3;\\n    b2 -> a3;\\n    a3 -> a0;\\n    a3 -> end;\\n    b3 -> end;\\n  \\n    start [shape=Mdiamond];\\n    end [shape=Msquare];\\n}\\n',\n}\n\nx = {\n    \"kind\": {\"plotly\": True},\n    \"data\": [\n        {\n            \"mode\": \"lines\",\n            \"type\": \"scatter\",\n            \"x\": [\"A\", \"B\", \"C\"],\n            \"xaxis\": \"x\",\n            \"y\": [4488916, 3918072, 3892124],\n            \"yaxis\": \"y\",\n        },\n        {\n            \"cells\": {\"values\": [[\"A\", \"B\", \"C\"], [341319, 281489, 294786], [4488916, 3918072, 3892124]]},\n            \"domain\": {\"x\": [0.0, 1.0], \"y\": [0.0, 0.60]},\n            \"header\": {\"align\": \"left\", \"font\": {\"size\": 10}, \"values\": [\"Date\", \"Number\", \"Output\"]},\n            \"type\": \"table\",\n        },\n    ],\n    \"layout\": {\"xaxis\": {\"anchor\": \"y\", \"domain\": [0.0, 1.0]}, \"yaxis\": {\"anchor\": \"x\", \"domain\": [0.75, 1.0]}},\n}\npass"
  },
  {
    "path": "demos/python/graph.py",
    "content": "# Install the python extension for VS Code\n# (https:#marketplace.visualstudio.com/items?itemName=ms-python.python).\n\n# The Debug Visualizer has no support for Python data extractors yet,\n# so to visualize data, your value must be a valid JSON string representing the data.\n# See readme for supported data schemas.\n\nfrom json import dumps\nfrom random import randint\n\ngraph = {\n    \"kind\": {\"graph\": True},\n    \"nodes\": [\n        {\"id\": \"1\", \"label\": \"1\"}\n    ],\n    \"edges\": []\n}\n\nfor i in range(2,100):\n    # add a node\n    id = str(i)\n    graph[\"nodes\"].append({\"id\": id, \"label\": id})\n    # connects the node to a random edge\n    targetId = str(randint(1, i - 1))\n    graph[\"edges\"].append({\"from\": id, \"to\": targetId})\n    print(\"i is \" + str(i))\n    # try setting a breakpoint right above\n    # then put graph into the visualization console and press enter\n    # when you step through the code each time you hit the breakpoint\n    # the graph should automatically refresh!\n    \n# example of json_graph visualization with 10 nodes:\n# https://i.imgur.com/RqZuYHH.png\n\nprint(\"finished\")\n"
  },
  {
    "path": "demos/python/insertion_sort.py",
    "content": "\"\"\"Python demo for sorting using VS Code Debug Visualizer.\"\"\"\n\n\ndef serialize(arr):\n    \"\"\"Serialize an array into a format the visualizer can understand.\"\"\"\n    formatted = {\n        \"kind\": {\"grid\": True},\n        \"rows\": [\n            {\n                \"columns\": [\n                    {\"content\": str(value), \"tag\": str(value)} for value in arr\n                ],\n            }\n        ],\n    }\n    return formatted\n\n\narr = [6, 9, 3, 12, 1, 11, 5, 13, 8, 14, 2, 4, 10, 0, 7]\n\n# Put serialized into the Debug Visualizer console\nserialized = serialize(arr)\n\n# Set a breakpoint on the line below and go through the code in debug mode to\n# watch it update\nfor target_idx in range(1, len(arr)):\n    target_value = arr[target_idx]\n    compare_idx = target_idx - 1\n\n    while compare_idx >= 0 and arr[compare_idx] > target_value:\n        arr[compare_idx + 1] = arr[compare_idx]\n        serialized = serialize(arr)\n        compare_idx -= 1\n\n    arr[compare_idx + 1] = target_value\n    serialized = serialize(arr)\n\nassert arr == sorted(arr)\n"
  },
  {
    "path": "demos/ruby/README.md",
    "content": "# Ruby Demos\n\nTo visualize Ruby objects, you need to install [debugvisualizer.gem](https://github.com/ono-max/debugvisualizer).\n\nInstall the gem by executing:\n\n    $ gem install debugvisualizer\n"
  },
  {
    "path": "demos/ruby/src/demo_custom_visualizer.rb",
    "content": "require 'debugvisualizer'\n\nclass Foo; end\n\nDebugVisualizer.register Foo do |data|\n  {\n    id: \"my_visualizer\",\n    name: \"My Visualizer\",\n    data: {\n        kind: { text: true },\n        text: \"Foo\"\n    }\n  }\nend\n\nf = Foo.new\n# visualize `f` here!\nbinding.break\n"
  },
  {
    "path": "demos/ruby/src/demo_random_walks.rb",
    "content": "data = []\ncurVal = 0\n\n100.times{\n  100.times{\n    delta = rand > 0.5 ? 1 : -1\n    data << curVal\n    curVal += delta\n    # visualize `data` here and press F5(or Continue button) over and over!\n    binding.break\n  }\n}\n"
  },
  {
    "path": "demos/rust/.gitignore",
    "content": "# Generated by Cargo\n# will have compiled files and executables\n/target/\n\n# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries\n# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html\nCargo.lock\n\n# These are backup files generated by rustfmt\n**/*.rs.bk"
  },
  {
    "path": "demos/rust/.vscode/launch.json",
    "content": "{\n    // Use IntelliSense to learn about possible attributes.\n    // Hover to view descriptions of existing attributes.\n    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"type\": \"lldb\",\n            \"request\": \"launch\",\n            \"name\": \"run rust demo\",\n            \"cargo\": {\n                \"args\": [\n                    \"build\",\n                    \"--bin=rust_demo\",\n                    \"--package=rust_demo\",\n                ],\n                \"filter\": {\n                    \"name\": \"rust_demo\",\n                    \"kind\": \"bin\",\n                },\n            },\n            \"args\": [],\n            \"cwd\": \"${workspaceFolder}\"\n        }\n    ]\n}"
  },
  {
    "path": "demos/rust/.vscode/settings.json",
    "content": "{\n    \"debugVisualizer.debugAdapterConfigurations\": {\n        \"lldb\": {\n            \"expressionTemplate\": \"${expr}\",\n            \"context\": \"watch\"\n        }\n    }\n}"
  },
  {
    "path": "demos/rust/Cargo.toml",
    "content": "[package]\nname = \"rust_demo\"\nversion = \"0.1.0\"\nauthors = [\"hediet\"]\nedition = \"2018\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\""
  },
  {
    "path": "demos/rust/src/main.rs",
    "content": "use serde::Serialize;\n\n// expected to mirror\n// https://hediet.github.io/visualization/docs/visualization-data-schema.json\n//\n// implements the grid visualizer as an example\n\npub type Label = String;\n\n/// `GridVisualizationData` in schema\n#[derive(Debug, Serialize)]\npub struct Grid {\n    kind: Kind,\n    rows: Vec<Row>,\n\n    #[serde(rename = \"columnLabels\")]\n    #[serde(skip_serializing_if=\"Option::is_none\")]\n    column_labels: Option<Vec<Label>>,\n}\n\n#[derive(Debug, Serialize)]\npub struct Kind {\n    grid: bool,\n}\n\n#[derive(Debug, Serialize)]\npub struct Row {\n    columns: Vec<Column>,\n\n    #[serde(skip_serializing_if=\"Option::is_none\")]\n    label: Option<Label>,\n}\n\n#[derive(Debug, Serialize)]\npub struct Column {\n    /// value to display to the user\n    #[serde(skip_serializing_if=\"Option::is_none\")]\n    content: Option<String>,\n\n    /// unique value to identify this cell, if desired\n    #[serde(skip_serializing_if=\"Option::is_none\")]\n    tag: Option<String>,\n\n    // TODO: valid values / syntax?\n    #[serde(skip_serializing_if=\"Option::is_none\")]\n    color: Option<String>,\n}\n\nfn show_arr(a: &[i32]) -> String {\n    let columns: Vec<Column> = a\n        .iter()\n        .map(|x| Column {\n            content: Some(format!(\"{:?}\", x)),\n            tag: None,\n\n            // TODO: `color` value doesn't seem to change visualizer's output at all\n            color: \"who-knows\".to_owned().into(),\n        })\n        .collect();\n\n    let row = Row {\n        columns,\n        // TODO: visualizer doesn't seem to render this\n        label: \"my row\".to_owned().into(),\n    };\n\n    let kind = Kind { grid: true };\n\n    let grid = Grid {\n        kind,\n        rows: vec![row],\n\n        // TODO: visualizer doesn't seem to work if this is non-`None`\n        column_labels: None,\n    };\n\n    serde_json::to_string(&grid).unwrap()\n}\n\nfn main() {\n    let mut arr = vec![1, 2, 3];\n    let mut _s = show_arr(&arr);\n    for _ in 0..5 {\n        arr.swap(0, 2); // set a break-point here, to easily observe the change\n        _s = show_arr(&arr);\n    }\n    dbg!(arr);\n    println!(\"break-point here, too\");\n}"
  },
  {
    "path": "demos/swift/.gitignore",
    "content": ".DS_Store\n/.build\n/Packages\n/*.xcodeproj\nxcuserdata/\n"
  },
  {
    "path": "demos/swift/.vscode/launch.json",
    "content": "// .vscode/launch.json\n{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t// Running executables\n\t\t{\n\t\t\t\"type\": \"lldb\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"name\": \"Run your Executable\",\n\t\t\t\"program\": \"${workspaceFolder}/.build/debug/swiftDemo\",\n\t\t\t\"args\": [],\n\t\t\t\"cwd\": \"${workspaceFolder}\",\n\t\t\t\"preLaunchTask\": \"swift-build\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/swift/.vscode/settings.json",
    "content": "{\n\t// You need to adapt this path to your swift installation.\n\t// See here for more info:\n\t// https://github.com/vadimcn/vscode-lldb/issues/234\n\t\"lldb.library\": \"/home/hediet/swift-5.1.5-RELEASE-ubuntu14.04/usr/lib/liblldb.so\"\n}\n"
  },
  {
    "path": "demos/swift/.vscode/tasks.json",
    "content": "{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t// compile your SPM project\n\t\t{\n\t\t\t\"label\": \"swift-build\",\n\t\t\t\"type\": \"shell\",\n\t\t\t\"command\": \"swift build\" // for TensorFlow add -Xlinker -ltensorflow\n\t\t},\n\t\t// compile your SPM tests\n\t\t{\n\t\t\t\"label\": \"swift-build-tests\",\n\t\t\t\"type\": \"process\",\n\t\t\t\"command\": \"swift\",\n\t\t\t\"group\": \"build\",\n\t\t\t\"args\": [\n\t\t\t\t\"build\",\n\t\t\t\t\"--build-tests\"\n\t\t\t\t// for TensorFlow add \"-Xlinker\", \"-ltensorflow\"\n\t\t\t]\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "demos/swift/Package.swift",
    "content": "// swift-tools-version:5.1\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"swiftDemo\",\n    dependencies: [\n        // Dependencies declare other packages that this package depends on.\n        // .package(url: /* package url */, from: \"1.0.0\"),\n    ],\n    targets: [\n        // Targets are the basic building blocks of a package. A target can define a module or a test suite.\n        // Targets can depend on other targets in this package, and on products in packages which this package depends on.\n        .target(\n            name: \"swiftDemo\",\n            dependencies: []),\n        .testTarget(\n            name: \"swiftDemoTests\",\n            dependencies: [\"swiftDemo\"]),\n    ]\n)\n"
  },
  {
    "path": "demos/swift/Sources/swiftDemo/main.swift",
    "content": "let s = \"{\\\"kind\\\":{\\\"graph\\\":true},\"\n        + \"\\\"nodes\\\":[{\\\"id\\\":\\\"1\\\"},{\\\"id\\\":\\\"2\\\"}],\"\n        + \"\\\"edges\\\":[{\\\"from\\\":\\\"1\\\",\\\"to\\\":\\\"2\\\"}]}\";\n\nprint(s)\n"
  },
  {
    "path": "demos/swift/Tests/LinuxMain.swift",
    "content": "import XCTest\n\nimport swiftTests\n\nvar tests = [XCTestCaseEntry]()\ntests += swiftTests.allTests()\nXCTMain(tests)\n"
  },
  {
    "path": "demos/swift/Tests/swiftDemoTests/XCTestManifests.swift",
    "content": "import XCTest\n\n#if !canImport(ObjectiveC)\npublic func allTests() -> [XCTestCaseEntry] {\n    return [\n        testCase(swiftTests.allTests),\n    ]\n}\n#endif\n"
  },
  {
    "path": "demos/swift/Tests/swiftDemoTests/swiftDemoTests.swift",
    "content": "import XCTest\nimport class Foundation.Bundle\n\nfinal class swiftTests: XCTestCase {\n    func testExample() throws {\n        // This is an example of a functional test case.\n        // Use XCTAssert and related functions to verify your tests produce the correct\n        // results.\n\n        // Some of the APIs that we use below are available in macOS 10.13 and above.\n        guard #available(macOS 10.13, *) else {\n            return\n        }\n\n        let fooBinary = productsDirectory.appendingPathComponent(\"swift\")\n\n        let process = Process()\n        process.executableURL = fooBinary\n\n        let pipe = Pipe()\n        process.standardOutput = pipe\n\n        try process.run()\n        process.waitUntilExit()\n\n        let data = pipe.fileHandleForReading.readDataToEndOfFile()\n        let output = String(data: data, encoding: .utf8)\n\n        XCTAssertEqual(output, \"Hello, world!\\n\")\n    }\n\n    /// Returns path to the built products directory.\n    var productsDirectory: URL {\n      #if os(macOS)\n        for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(\".xctest\") {\n            return bundle.bundleURL.deletingLastPathComponent()\n        }\n        fatalError(\"couldn't find the products directory\")\n      #else\n        return Bundle.main.bundleURL\n      #endif\n    }\n\n    static var allTests = [\n        (\"testExample\", testExample),\n    ]\n}\n"
  },
  {
    "path": "demos/swift/main.swift",
    "content": "import Swift\nprint(\"Hello, World!\")"
  },
  {
    "path": "docs/main.plantuml",
    "content": "@startuml Main\n\n[data-extraction] \n[webview]\n[extension]\n[hediet/visualization]\n\n[webview] ..> [extension]: \"Uses RPC contracts, connects using websockets\"\n[extension] ..> [webview]: \"Loads into a Webview in VS Code\"\n\n[webview] ..> [hediet/visualization]: \"Uses React Components\"\n\n\n[extension] ..> [data-extraction]: \"Injects Runtime into JavaScript applications\"\n\n[webview] ..> [data-extraction]: \"Uses common types\"\n\n@enduml"
  },
  {
    "path": "extension/.vscodeignore",
    "content": "./node_modules"
  },
  {
    "path": "extension/CHANGELOG.md",
    "content": "# Change Log\n\n## 2.6.0\n\n-   Improved JS data extractors\n-   Uses the active stack frame (instead of the top-most) for evaluating expressions\n\n## 2.4.0\n\n-   [Ruby support](https://github.com/hediet/vscode-debug-visualizer/pull/159)\n-   New setting `debugVisualizer.customVisualizerScriptPaths` to support custom visualizations\n-   Added JS data extractors\n\n## 2.3.0\n\n-   [Improves support for python](https://github.com/hediet/vscode-debug-visualizer/pull/122)\n\n## 2.2.0\n\n-   Adds setting `debugVisualizer.js.customScriptPaths` to inject custom scripts when debugging JavaScript. Such scripts are reloaded automatically when changed.\n\n## 2.1.0\n\n-   Adds text diff and text decoration viewer.\n-   Supports more js debug adapters\n\n## 2.0.6\n\n-   Fixes grid extractor bug\n-   Fixes Perspective.js bug\n-   Fixes AST visualizer bug\n-   Adds table data extractor\n-   Improves typescript data extractor\n\n## 2.0.0\n\n-   Support for the new JS debug adapters\n-   Moved visualizations to [github.com/hediet/visualization](https://github.com/hediet/visualization).\n-   New Visualizations / Improved design / Improved dark theme\n-   New Logo\n\n## 1.1.0\n\n-   Fixes a bug that occurs when the debug visualizer is opened after the debug session has started.\n-   Fixes a bug that is caused by VS Code invoking the debug tracker multiple times for the same session.\n-   Adds support for the new `pwa-chrome` debug adapter.\n-   Uses `repl` mode as default evaluation context so that responses don't get truncated.\n-   Improves error messages when evaluating an expression or parsing the result goes wrong.\n-   Sets `webview.retainContextWhenHidden` to true, so that visualizer views load faster when they were already opened.\n-   Configures `webview.portMapping` so that this extension should work with remote development.\n\n## 1.0.0\n\n-   \"Debug Visualizer: Use Selection as Expression\" will open a new view if no Debug Visualizer view was opened.\n-   Enables type based autocompletion in the input field when debugging JavaScript/TypeScript.\n-   Changes license from MIT to GPL-3.0.\n-   Fixes bug where loading animation didn't stop.\n-   Catches visualization errors rather than letting the entire webview crash.\n\n## 0.14.0\n\n-   Submits the expression when the expression input loses focus.\n-   Changes text of command \"Open a new Debug Visualizer View\" to \"Debug Visualizer: New View\".\n-   Adds command \"Debug Visualizer: Use Selection as Expression\" (Shift+F1)\n-   Optimizes load time by splitting code into multiple bundles.\n-   Fixes monaco load errors.\n-   Sets the mode of the expression input to text rather than typescript, as this extension supports multiple languages.\n-   Improves error messages.\n\n## 0.13.0\n\n-   Adds \"debugVisualizer.debugAdapterConfigurations\" config to customize the expression template.\n-   Code Restructuring\n\n## 0.12.1\n\n-   Tries to parse evaluated strings twice as JSON in case of C++/C# escape sequences.\n\n## 0.12.0\n\n-   Generic Debug Adapter Support (tested with PHP, Java, C#)\n-   Dark Theme Support\n-   Grid Visualizer\n-   Some Bugfixes\n\n## 0.11.1\n\n-   Fixes crash on start\n\n## 0.11.0\n\n-   Multiline Expression Input\n-   Helper Bundle Injection\n-   Plotly Visualizer\n-   Object Graph Data Extractor\n-   Plotly Data Extractor\n-   Some Bugfixes\n\n## 0.10.0\n\n-   Minor refactoring of `@hediet/debug-visualizer-data-extraction`'s API\n-   Improved documentation.\n\n## 0.9.0\n\n-   Initial release\n"
  },
  {
    "path": "extension/LICENSE.md",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\nCopyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\n                            Preamble\n\nThe GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\nThe licenses for most software and other practical works are designed\nto take away your freedom to share and change the works. By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users. We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors. You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not\nprice. Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\nTo protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights. Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\nFor example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received. You must make sure that they, too, receive\nor can get the source code. And you must show them these terms so they\nknow their rights.\n\nDevelopers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\nFor the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software. For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\nSome devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so. This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software. The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable. Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts. If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\nFinally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary. To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\nThe precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n0. Definitions.\n\n\"This License\" refers to version 3 of the GNU General Public License.\n\n\"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n\"The Program\" refers to any copyrightable work licensed under this\nLicense. Each licensee is addressed as \"you\". \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\nTo \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy. The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\nA \"covered work\" means either the unmodified Program or a work based\non the Program.\n\nTo \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy. Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\nTo \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies. Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\nAn interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License. If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n1. Source Code.\n\nThe \"source code\" for a work means the preferred form of the work\nfor making modifications to it. \"Object code\" means any non-source\nform of a work.\n\nA \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\nThe \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form. A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\nThe \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities. However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work. For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\nThe Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\nThe Corresponding Source for a work in source code form is that\nsame work.\n\n2. Basic Permissions.\n\nAll rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met. This License explicitly affirms your unlimited\npermission to run the unmodified Program. The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work. This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\nYou may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force. You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright. Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\nConveying under any other circumstances is permitted solely under\nthe conditions stated below. Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\nNo covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\nWhen you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n4. Conveying Verbatim Copies.\n\nYou may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\nYou may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n5. Conveying Modified Source Versions.\n\nYou may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\nA compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit. Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n6. Conveying Non-Source Forms.\n\nYou may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\nA separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\nA \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling. In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage. For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product. A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n\"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source. The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\nIf you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information. But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\nThe requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed. Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\nCorresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n7. Additional Terms.\n\n\"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law. If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\nWhen you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit. (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.) You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\nNotwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\nAll other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10. If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term. If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\nIf you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\nAdditional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n8. Termination.\n\nYou may not propagate or modify a covered work except as expressly\nprovided under this License. Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\nHowever, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\nMoreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\nTermination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License. If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n9. Acceptance Not Required for Having Copies.\n\nYou are not required to accept this License in order to receive or\nrun a copy of the Program. Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance. However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work. These actions infringe copyright if you do\nnot accept this License. Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n10. Automatic Licensing of Downstream Recipients.\n\nEach time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License. You are not responsible\nfor enforcing compliance by third parties with this License.\n\nAn \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations. If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\nYou may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License. For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n11. Patents.\n\nA \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based. The\nwork thus licensed is called the contributor's \"contributor version\".\n\nA contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version. For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\nEach contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\nIn the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement). To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\nIf you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients. \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\nIf, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\nA patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License. You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\nNothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n12. No Surrender of Others' Freedom.\n\nIf conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License. If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all. For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n13. Use with the GNU Affero General Public License.\n\nNotwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work. The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n14. Revised Versions of this License.\n\nThe Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time. Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number. If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation. If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\nIf the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\nLater license versions may give you additional or different\npermissions. However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n15. Disclaimer of Warranty.\n\nTHERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n16. Limitation of Liability.\n\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n17. Interpretation of Sections 15 and 16.\n\nIf the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and`show c' should show the appropriate\nparts of the General Public License. Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\nYou should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\nThe GNU General Public License does not permit incorporating your program\ninto proprietary programs. If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library. If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License. But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "extension/README.md",
    "content": "# Debug Visualizer\n\n[![](https://img.shields.io/twitter/follow/hediet_dev.svg?style=social)](https://twitter.com/intent/follow?screen_name=hediet_dev)\n\nA VS Code extension for visualizing data structures while debugging.\nLike the VS Code's watch view, but with rich visualizations of the watched value.\n\n![](../docs/demo.gif)\n\n## [Visualization Playground](https://hediet.github.io/visualization/)\n\nClick [here](https://hediet.github.io/visualization/) to explore all available visualizations.\n\n## Supported Languages\n\nSee [demos](../demos/) for demos. These languages and debuggers are verified to work with this extension:\n\n-   JavaScript/TypeScript/... using `node`/`node2`/`extensionHost`/`chrome`/`pwa-chrome`/`pwa-node` debug adapter: [⭐ Full Support](../demos/js)\n-   Dart/Flutter using `dart` debug adapter: [✅ Basic Support](../demos/dart)\n-   Go using `go` (Delve) debug adapter: [✅ Basic Support](../demos/golang)\n-   Python using `python` debug adapter: [✅ Basic Support](../demos/python)\n-   C# using `coreclr` debug adapter: [✅ Basic Support](../demos/csharp) (work in progress for Full Support)\n-   PHP using `php` debug adapter: [✅ Basic Support](../demos/php)\n-   Java using `java` debug adapter: [✅ Basic Support](../demos/java)\n-   C++ using `cppdbg` debug adapter: [✅ Basic Support](../demos/cpp)\n-   Swift using `lldb` debug adapter: [✅ Basic Support](../demos/swift)\n-   Rust using `lldb` debug adapter: [✅ Basic Support](../demos/rust)\n-   Ruby using `rdbg` debug adapter: [✅ Basic Support](../demos/ruby)\n\nAll other languages and debuggers might work too.\nFor languages with _Basic Support_, only JSON strings can be visualized - you must implement some logic that builds this JSON for your data structure!\nFully supported languages offer _Data Extractors_ which convert some well known data structures to json.\n\n## Usage\n\nAfter installing this extension, use the command `Debug Visualizer: New View` to open a new visualizer view.\nIn this view you can enter an expression that is evaluated and visualized while stepping through your application.\nThis view works the same as the watch view of VS Code, except that the resulting value is presented visually rather than textually and you can only watch one expression (but you can still open multiple windows).\n\nUse the command `Debug Visualizer: Use Selection as Expression` _(Shift + F1)_ to use the currently selected text as expression\nin the most recently opened debug visualizer.\n\n## Supported Values\n\nNot all values can be processed.\nVisualizers consume specific JSON data. This extension uses [hediet/visualization](https://github.com/hediet/visualization), a generic visualization framework.\nYou can see in its [playground](https://hediet.github.io/visualization/) which data can be visualized and how the visualization looks like.\n\nThe currently watched expression should evaluate to a JSON Object string,\nmatching the [schema](https://hediet.github.io/visualization/docs/visualization-data-schema.json) of one of the supported visualizers. This JSON string may be surrounded by single or double quotation marks (or none at all) and must not be escaped.\nA valid example is `\"{ \"kind\": { \"text\": true }, \"text\": \"some text\\nmore text\" }\"`.\nUse the watch window to see what an expression evaluates to. This extension simply interprets that result.\n\nFor some languages (TypeScript/JavaScript), runtime code is injected to support _Data Extractors_.\nA Data Extractor lifts the requirement for the visualized value to be a JSON string\nand acts as a bridge between custom data structures and the JSON data processed by the visualizers.\nWhen multiple Data Extractors are applicable, a preferred one can be selected in the visualization view.\n\nThere is a [JSON Schema for all supported visualizations](https://hediet.github.io/visualization/docs/visualization-data-schema.json) and a [typescript declaration file](https://hediet.github.io/visualization/docs/visualization-data.ts).\n\n## Selected Demos\n\n### Reversing a Doubly Linked List\n\n![](../docs/doubly-linked-list-reverse-demo.gif)\n\n### Random Walk\n\n![](../docs/visualization-plotly-random-walk.gif)\n\n### Ast Visualizer\n\n![](../docs/ast-demo.gif)\n\n### Table Visualizer\n\n![](../docs/table-demo.gif)\n\n## JavaScript/TypeScript Integrated Data Extractors\n\nData extractors convert arbitrary values into data consumable by visualizers.\nThey live in the debugee. The following data extractors are injected automatically into the debugee by this extension when using the `node`, `node2`, `extensionHost`, `chrome` or `pwa-chrome` debug adapter.\nCustom data extractors can be registered too.\nSee the package `@hediet/debug-visualizer-data-extraction` and its [README](../data-extraction/README.md) for the implementation and its API.\nAlso, a global object of name `hedietDbgVis` with helper functions is injected.\n\n-   **ToString**\n    -   Just calls `.toString()` on values and treats the result as text.\n-   **TypeScript AST**\n    -   Direct Visualization of `ts.Node`s\n    -   Visualization of `Record<string, ts.Node>` and `ts.Node[]`. If the record contains a key `fn`, its value is displayed for each node.\n-   **As Is Data Extractor**\n    -   Treats the data as direct input to the visualizer.\n-   **Use Method 'getVisualizationData'**\n    -   Calls `.getVisualizationData()` on values and treats the result as direct input to the visualizer.\n-   **Plotly y-Values**\n    -   Uses plotly to plot an array of numbers.\n-   **Object Graph**\n    -   Constructs a graph containing all objects reachable from object the expression evaluates to.\n        Graph is constructed using a breadth search. Stops after 50 nodes.\n-   **Array Grid**\n    -   Creates Grid visualization data for an array.\n\n## UI Features\n\n-   **Multi-line Expressions**: Press `shift+enter` to add a new line and `ctrl+enter` to evaluate the expression.\n    When only having a single line, `enter` submits the current expression,\n    but when having multiple lines, `enter` inserts another line break.\n\n    ![](../docs/multiline-expression.png)\n\n## Configuration\n\nThis extension provides these configuration options:\n\n### **debugVisualizer.debugAdapterConfigurations**\n\nAllows to set expression templates for specific debug adapter types.\nExample:\n\n```json\n\"debugVisualizer.debugAdapterConfigurations\": {\n    \"lldb\": {\n        \"expressionTemplate\": \"script to_json(\\\"${expr}\\\")\",\n        \"context\": \"repl\"\n    }\n}\n```\n\nConfigurations here overwrite the built-in support for the corresponding debug adapter type.\n\n### **debugVisualizer.useChromeKioskMode**\n\nSpecifies whether to pop out Debug Visualization Views with Chrome in Kiosk Mode. Uses the default browser otherwise or if Chrome is not found. Defaults to `true`.\n\n### **debugVisualizer.js.customScriptPaths**\n\nSpecifies a list of JavaScript files that are injected into the debugee when debugging JavaScript.\nEach script must assign `module.exports` with a function of type `import(\"@hediet/debug-visualizer-data-extraction\").LoadDataExtractorsFn`.\nPaths must be absolute and can use the variable `${workspaceFolder}`.\nScripts are automatically reloaded when they are changed.\n\nExample:\n\n```js\n// @ts-check\n/**\n * @type {import(\"@hediet/debug-visualizer-data-extraction\").LoadDataExtractorsFn}\n */\nmodule.exports = (register, helpers) => {\n\tregister({\n\t\tid: \"map\",\n\t\tgetExtractions(data, collector, context) {\n\t\t\tif (!(data instanceof Map)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcollector.addExtraction({\n\t\t\t\tpriority: 1000,\n\t\t\t\tid: \"map\",\n\t\t\t\tname: \"Map\",\n\t\t\t\textractData() {\n\t\t\t\t\treturn helpers.asData({\n\t\t\t\t\t\tkind: { table: true },\n\t\t\t\t\t\trows: [...data].map(([k, v]) => ({\n\t\t\t\t\t\t\tkey: k,\n\t\t\t\t\t\t\tvalue: v,\n\t\t\t\t\t\t})),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t});\n};\n```\n\n![](../docs/custom-script-map.png)\n\nUse the `helpers` object to access some magic functions.\n`helpers.find(val => ...)` can be used to find an object that is reachable by any variable in scope.\n\n# See Also\n\nThis extension works very well together with my library [`@hediet/node-reload`](https://github.com/hediet/node-reload) for TypeScript/JavaScript.\nTogether, they provide an interactive playground.\n\n![](../docs/demo-hot.gif)\n\n# Contributing\n\nFeel free to ping me on GitHub by opening an issue!\nHaving runtime infrastructures for languages other than JavaScript would be awesome and I happily accept PRs!\n"
  },
  {
    "path": "extension/package.json",
    "content": "{\n\t\"name\": \"debug-visualizer\",\n\t\"private\": true,\n\t\"displayName\": \"Debug Visualizer\",\n\t\"description\": \"A visual watch window that lets you visualize your data structures while debugging.\",\n\t\"icon\": \"docs/logo.drawio.png\",\n\t\"version\": \"2.6.0\",\n\t\"license\": \"GPL-3.0\",\n\t\"engines\": {\n\t\t\"vscode\": \"^1.84.0\"\n\t},\n\t\"publisher\": \"hediet\",\n\t\"keywords\": [\n\t\t\"debugger\",\n\t\t\"debugging\",\n\t\t\"debug\",\n\t\t\"visual\",\n\t\t\"javascript\",\n\t\t\"graph\",\n\t\t\"ast\",\n\t\t\"visualization\"\n\t],\n\t\"bugs\": {\n\t\t\"url\": \"https://github.com/hediet/vscode-debug-visualizer/issues\"\n\t},\n\t\"author\": {\n\t\t\"email\": \"henning.dieterichs@live.de\",\n\t\t\"name\": \"Henning Dieterichs\"\n\t},\n\t\"readme\": \"./README.md\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/hediet/vscode-debug-visualizer.git\"\n\t},\n\t\"categories\": [\n\t\t\"Other\"\n\t],\n\t\"activationEvents\": [\n\t\t\"onDebug\",\n\t\t\"onWebviewPanel:debugVisualizer\"\n\t],\n\t\"capabilities\": {\n\t\t\"untrustedWorkspaces\": {\n\t\t\t\"supported\": false\n\t\t}\n\t},\n\t\"main\": \"./dist/extension.js\",\n\t\"contributes\": {\n\t\t\"commands\": [\n\t\t\t{\n\t\t\t\t\"command\": \"vscode-debug-visualizer.new-visualizer\",\n\t\t\t\t\"title\": \"Debug Visualizer: New View\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"vscode-debug-visualizer.visualizer-set-expression\",\n\t\t\t\t\"title\": \"Debug Visualizer: Use Selection as Expression\"\n\t\t\t}\n\t\t],\n\t\t\"keybindings\": [\n\t\t\t{\n\t\t\t\t\"command\": \"vscode-debug-visualizer.visualizer-set-expression\",\n\t\t\t\t\"key\": \"shift+f1\",\n\t\t\t\t\"when\": \"editorTextFocus\"\n\t\t\t}\n\t\t],\n\t\t\"configuration\": {\n\t\t\t\"title\": \"Debug Visualizer\",\n\t\t\t\"properties\": {\n\t\t\t\t\"debugVisualizer.js.customScriptPaths\": {\n\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\"description\": \"Defines JavaScript sources that are injected into the debuggee to provide custom data extractors.\",\n\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\"description\": \"The file path to a custom js script. Must be absolute. You can use ${workspaceFolder}. Must assign `module.exports` an object of type `import('@hediet/debug-visualizer-data-extraction').LoadDataExtractorsFn`.\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"debugVisualizer.customVisualizerScriptPaths\": {\n\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\"description\": \"Defines JavaScript sources that are injected into the visualizer to provide custom visualizations.\",\n\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\"description\": \"The file path to a custom js script. Must be absolute. You can use ${workspaceFolder}. Must assign `module.exports` an object of type `import('@hediet/visualization-core').RegisterVisualizerFn`.\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"debugVisualizer.useChromeKioskMode\": {\n\t\t\t\t\t\"type\": \"boolean\",\n\t\t\t\t\t\"default\": true,\n\t\t\t\t\t\"description\": \"Pop out Debug Visualization Views with Chrome in Kiosk Mode.\"\n\t\t\t\t},\n\t\t\t\t\"debugVisualizer.debugAdapterConfigurations\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"additionalProperties\": {\n\t\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\t\"expressionTemplate\": {\n\t\t\t\t\t\t\t\t\"type:\": \"string\",\n\t\t\t\t\t\t\t\t\"description\": \"A template for the final expression sent to the debugger for evaluation. Use `${expr}` to refer to the currently visualized expression.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"context\": {\n\t\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\t\"enum\": [\n\t\t\t\t\t\t\t\t\t\"watch\",\n\t\t\t\t\t\t\t\t\t\"repl\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"description\": \"The context to use for evaluating the expression.\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t\"scripts\": {\n\t\t\"pub\": \"vsce publish --packagePath ./dist/extension.vsix\",\n\t\t\"package\": \"vsce package --no-dependencies -o ./dist/extension.vsix --yarn --baseImagesUrl https://github.com/hediet/vscode-debug-visualizer/raw/master/extension --baseContentUrl https://github.com/hediet/vscode-debug-visualizer/raw/master/extension\",\n\t\t\"vscode:prepublish\": \"\",\n\t\t\"build\": \"webpack --mode production\",\n\t\t\"dev\": \"shx rm -rf dist && tsc -watch -p ./\"\n\t},\n\t\"dependencies\": {\n\t\t\"@hediet/std\": \"^0.6.0\",\n\t\t\"@hediet/typed-json-rpc\": \"^0.7.7\",\n\t\t\"@hediet/typed-json-rpc-websocket-server\": \"^0.7.7\",\n\t\t\"chrome-launcher\": \"^0.12.0\",\n\t\t\"@hediet/node-reload\": \"^0.7.3\",\n\t\t\"express\": \"^4.17.1\",\n\t\t\"open\": \"^7.0.2\",\n\t\t\"serve-static\": \"^1.14.1\",\n\t\t\"ws\": \"^7.2.1\",\n\t\t\"crypto-random-string\": \"^3.1.0\",\n\t\t\"mobx-utils\": \"^5.6.1\"\n\t},\n\t\"devDependencies\": {\n\t\t\"copy-webpack-plugin\": \"^11.0.0\",\n\t\t\"@types/copy-webpack-plugin\": \"^10.1.0\",\n\t\t\"@types/express\": \"^4.17.2\",\n\t\t\"@types/serve-static\": \"^1.13.3\",\n\t\t\"@types/node\": \"^13.7.4\",\n\t\t\"@types/vscode\": \"^1.84.0\",\n\t\t\"tslint\": \"^6.1.3\",\n\t\t\"typescript\": \"^5.1.6\",\n\t\t\"webpack\": \"^5.88.1\",\n\t\t\"webpack-cli\": \"^5.1.4\",\n\t\t\"ts-loader\": \"^9.4.4\",\n\t\t\"shx\": \"^0.3.2\",\n\t\t\"vsce\": \"2.9.3\"\n\t}\n}\n"
  },
  {
    "path": "extension/src/Config.ts",
    "content": "import { workspace, window, ColorThemeKind } from \"vscode\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { observable } from \"mobx\";\nimport { DataExtractorId } from \"@hediet/debug-visualizer-data-extraction\";\nimport { VsCodeSetting, serializerWithDefault } from \"./utils/VsCodeSettings\";\n\nexport class Config {\n\tpublic dispose = Disposable.fn();\n\n\tprivate readonly _useChromeKioskMode = new VsCodeSetting(\n\t\t\"debugVisualizer.useChromeKioskMode\",\n\t\t{ serializer: serializerWithDefault<boolean>(true) }\n\t);\n\n\tpublic get useChromeKioskMode(): boolean {\n\t\treturn this._useChromeKioskMode.get();\n\t}\n\n\tprivate readonly _debugAdapterConfigs = new VsCodeSetting(\n\t\t\"debugVisualizer.debugAdapterConfigurations\",\n\t\t{ serializer: serializerWithDefault<DebugAdapterConfigs>({}) }\n\t);\n\n\tprivate readonly _customScriptPaths = new VsCodeSetting(\n\t\t\"debugVisualizer.js.customScriptPaths\",\n\t\t{ serializer: serializerWithDefault<string[]>([]) }\n\t);\n\n\tpublic get customScriptPaths(): string[] {\n\t\treturn this._customScriptPaths.get().map((p) => {\n\t\t\tconst tpl = new SimpleTemplate(p);\n\t\t\treturn tpl.render({\n\t\t\t\tworkspaceFolder: () => {\n\t\t\t\t\tconst workspaceFolder = (workspace.workspaceFolders ||\n\t\t\t\t\t\t[])[0];\n\t\t\t\t\tif (!workspaceFolder) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Cannot get workspace folder - '${p}' cannot be evaluated!`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn workspaceFolder.uri.fsPath;\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate readonly _customVisualizerScriptPaths = new VsCodeSetting(\n\t\t\"debugVisualizer.customVisualizerScriptPaths\",\n\t\t{ serializer: serializerWithDefault<string[]>([]) }\n\t);\n\n\tpublic get customVisualizerScriptPaths(): string[] {\n\t\treturn this._customVisualizerScriptPaths.get().map((p) => {\n\t\t\tconst tpl = new SimpleTemplate(p);\n\t\t\treturn tpl.render({\n\t\t\t\tworkspaceFolder: () => {\n\t\t\t\t\tconst workspaceFolder = (workspace.workspaceFolders ||\n\t\t\t\t\t\t[])[0];\n\t\t\t\t\tif (!workspaceFolder) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Cannot get workspace folder - '${p}' cannot be evaluated!`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn workspaceFolder.uri.fsPath;\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\t@observable\n\tprivate _vsCodeTheme = window.activeColorTheme;\n\n\tpublic get theme(): \"light\" | \"dark\" {\n\t\tif (this._vsCodeTheme.kind === ColorThemeKind.Light) {\n\t\t\treturn \"light\";\n\t\t} else if (this._vsCodeTheme.kind === ColorThemeKind.Dark) {\n\t\t\treturn \"dark\";\n\t\t}\n\t\treturn \"light\";\n\t}\n\n\tconstructor() {\n\t\tthis.dispose.track(\n\t\t\twindow.onDidChangeActiveColorTheme(() => {\n\t\t\t\tthis._vsCodeTheme = window.activeColorTheme;\n\t\t\t})\n\t\t);\n\t}\n\n\tpublic getDebugAdapterConfig(\n\t\tdebugAdapterType: string\n\t): DebugAdapterConfig | undefined {\n\t\tconst c = this._debugAdapterConfigs.get()[debugAdapterType];\n\t\tif (!c) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tcontext: c.context || \"watch\",\n\t\t\tgetFinalExpression: ({ expression, preferredExtractorId }) =>\n\t\t\t\tevaluateTemplate(c.expressionTemplate || \"${expr}\", {\n\t\t\t\t\texpr: expression,\n\t\t\t\t\tpreferredDataExtractorId: preferredExtractorId || \"\",\n\t\t\t\t}),\n\t\t};\n\t}\n}\n\ntype DebugAdapterConfigs = {\n\t[debugAdapter: string]: {\n\t\tcontext?: \"watch\" | \"repl\";\n\t\texpressionTemplate?: \"string\";\n\t};\n};\n\nexport interface DebugAdapterConfig {\n\tcontext: \"watch\" | \"repl\";\n\tgetFinalExpression(vars: {\n\t\texpression: string;\n\t\tpreferredExtractorId: DataExtractorId | undefined;\n\t}): string;\n}\n\nfunction evaluateTemplate(\n\ttemplate: string,\n\tdata: Record<string, string>\n): string {\n\tlet result = template;\n\tfor (const [key, val] of Object.entries(data)) {\n\t\tresult = result.split(`\\${${key}}`).join(val);\n\t}\n\treturn result;\n}\n\nexport class SimpleTemplate {\n\tconstructor(private readonly str: string) {}\n\n\trender(data: Record<string, () => string>): string {\n\t\treturn this.str.replace(/\\$\\{([a-zA-Z0-9]+)\\}/g, (substr, grp1) => {\n\t\t\treturn data[grp1]();\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/ComposedVisualizationSupport.ts",
    "content": "import {\n\tDebugSessionVisualizationSupport,\n\tVisualizationBackend,\n} from \"./VisualizationBackend\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\n\nexport class ComposedVisualizationSupport\n\timplements DebugSessionVisualizationSupport {\n\tconstructor(public readonly engines: DebugSessionVisualizationSupport[]) {}\n\n\tcreateBackend(\n\t\tsession: DebugSessionProxy\n\t): VisualizationBackend | undefined {\n\t\tfor (const f of this.engines) {\n\t\t\tconst evaluator = f.createBackend(session);\n\t\t\tif (evaluator) {\n\t\t\t\treturn evaluator;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/ConfigurableVisualizationSupport.ts",
    "content": "import { DataExtractorId } from \"@hediet/debug-visualizer-data-extraction\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\nimport {\n\tDebugSessionVisualizationSupport,\n\tVisualizationBackend,\n} from \"./VisualizationBackend\";\nimport { Config, DebugAdapterConfig } from \"../Config\";\nimport { GenericVisualizationBackend } from \"./GenericVisualizationSupport\";\nimport { registerUpdateReconciler, hotClass } from \"@hediet/node-reload\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\n\nregisterUpdateReconciler(module);\n\n@hotClass(module)\nexport class ConfigurableVisualizationSupport\n\timplements DebugSessionVisualizationSupport {\n\tconstructor(\n\t\tprivate readonly config: Config,\n\t\tprivate readonly debuggerView: DebuggerViewProxy\n\t) {}\n\n\tcreateBackend(\n\t\tsession: DebugSessionProxy\n\t): VisualizationBackend | undefined {\n\t\tconst config = this.config.getDebugAdapterConfig(session.session.type);\n\t\tif (!config) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new ConfiguredVisualizationBackend(\n\t\t\tsession,\n\t\t\tthis.debuggerView,\n\t\t\tconfig\n\t\t);\n\t}\n}\n\nclass ConfiguredVisualizationBackend extends GenericVisualizationBackend {\n\tconstructor(\n\t\tdebugSession: DebugSessionProxy,\n\t\tdebuggerView: DebuggerViewProxy,\n\t\tprivate readonly config: DebugAdapterConfig\n\t) {\n\t\tsuper(debugSession, debuggerView);\n\t}\n\n\tprotected getContext() {\n\t\treturn this.config.context;\n\t}\n\n\tprotected getFinalExpression({\n\t\texpression,\n\t\tpreferredExtractorId,\n\t}: {\n\t\texpression: string;\n\t\tpreferredExtractorId: DataExtractorId | undefined;\n\t}) {\n\t\treturn this.config.getFinalExpression({\n\t\t\texpression,\n\t\t\tpreferredExtractorId,\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/DispatchingVisualizationBackend.ts",
    "content": "import { DataExtractionResult } from \"@hediet/debug-visualizer-data-extraction\";\nimport { CompletionItem, FormattedMessage } from \"../webviewContract\";\nimport {\n\tDebugSessionVisualizationSupport,\n\tGetVisualizationDataArgs,\n\tVisualizationBackend,\n} from \"./VisualizationBackend\";\nimport { EventEmitter, EventSource } from \"@hediet/std/events\";\nimport { debug } from \"vscode\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\nimport { autorun, reaction } from \"mobx\";\n\nexport class DispatchingVisualizationBackend implements VisualizationBackend {\n\tpublic readonly dispose = Disposable.fn();\n\tprivate readonly visualizationBackends = new Map<\n\t\tDebugSessionProxy,\n\t\tVisualizationBackend\n\t>();\n\n\tprotected readonly onChangeEmitter = new EventEmitter();\n\tpublic readonly onChange = this.onChangeEmitter;\n\n\tconstructor(\n\t\tprivate readonly visualizationSupport: DebugSessionVisualizationSupport,\n\t\tprivate readonly debuggerView: DebuggerViewProxy\n\t) {\n\t\tthis.dispose.track(\n\t\t\tdebug.onDidTerminateDebugSession(session => {\n\t\t\t\tconst existing = [...this.visualizationBackends].find(\n\t\t\t\t\tv => v[0].session === session\n\t\t\t\t);\n\t\t\t\tif (existing) {\n\t\t\t\t\tthis.visualizationBackends.delete(existing[0]);\n\t\t\t\t\texisting[1].dispose();\n\t\t\t\t}\n\t\t\t})\n\t\t);\n\n\t\tthis.dispose.track({\n\t\t\tdispose: () => {\n\t\t\t\tfor (const backend of this.visualizationBackends.values()) {\n\t\t\t\t\tbackend.dispose();\n\t\t\t\t}\n\t\t\t\tthis.visualizationBackends.clear();\n\t\t\t},\n\t\t});\n\n\t\tthis.dispose.track({\n\t\t\tdispose: reaction(\n\t\t\t\t() => this.debuggerView.activeDebugSession,\n\t\t\t\tdebugSession => {\n\t\t\t\t\tif (debugSession !== undefined) {\n\t\t\t\t\t\tthis.onChangeEmitter.emit();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t),\n\t\t});\n\t}\n\n\tprivate getVisualizationBackend(\n\t\tdebugSession: DebugSessionProxy\n\t): VisualizationBackend | undefined {\n\t\tconst existing = this.visualizationBackends.get(debugSession);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst newBackend = this.visualizationSupport.createBackend(\n\t\t\tdebugSession\n\t\t);\n\n\t\tif (!newBackend) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tnewBackend.onChange.sub(() => {\n\t\t\tthis.onChangeEmitter.emit();\n\t\t});\n\n\t\tthis.visualizationBackends.set(debugSession, newBackend);\n\n\t\treturn newBackend;\n\t}\n\n\tprivate get activeVisualizationBackend(): VisualizationBackend | undefined {\n\t\tconst activeDebugSession = this.debuggerView.activeDebugSession;\n\t\tif (!activeDebugSession) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst backend = this.getVisualizationBackend(activeDebugSession);\n\t\treturn backend;\n\t}\n\n\tpublic async getVisualizationData(\n\t\targs: GetVisualizationDataArgs\n\t): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t> {\n\t\tconst activeDebugSession = this.debuggerView.activeDebugSession;\n\t\tif (!activeDebugSession) {\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: \"No active debug session.\",\n\t\t\t};\n\t\t}\n\t\tconst backend = this.getVisualizationBackend(activeDebugSession);\n\t\tif (!backend) {\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: `The debug adapter \"${activeDebugSession.session.type}\" is not supported.`,\n\t\t\t};\n\t\t}\n\t\treturn await backend.getVisualizationData(args);\n\t}\n\n\tpublic get expressionLanguageId(): string | undefined {\n\t\treturn this.activeVisualizationBackend?.expressionLanguageId;\n\t}\n\n\tpublic async getCompletions(\n\t\ttext: string,\n\t\tcolumn: number\n\t): Promise<CompletionItem[]> {\n\t\treturn (\n\t\t\t(await this.activeVisualizationBackend?.getCompletions(\n\t\t\t\ttext,\n\t\t\t\tcolumn\n\t\t\t)) || []\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/GenericVisualizationSupport.ts",
    "content": "import {\n\tDataExtractionResult,\n\tDataExtractorId,\n\tGraphNode,\n\tGraphVisualizationData,\n} from \"@hediet/debug-visualizer-data-extraction\";\nimport { hotClass, registerUpdateReconciler } from \"@hediet/node-reload\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\nimport { FormattedMessage } from \"../webviewContract\";\nimport {\n\tDebugSessionVisualizationSupport,\n\tGetVisualizationDataArgs,\n\tVisualizationBackend,\n\tVisualizationBackendBase,\n} from \"./VisualizationBackend\";\nimport { parseEvaluationResultFromGenericDebugAdapter } from \"./parseEvaluationResultFromGenericDebugAdapter\";\n\nregisterUpdateReconciler(module);\n\n@hotClass(module)\nexport class GenericVisualizationSupport\n\timplements DebugSessionVisualizationSupport {\n\tconstructor(private readonly debuggerView: DebuggerViewProxy) { }\n\n\tcreateBackend(\n\t\tsession: DebugSessionProxy\n\t): VisualizationBackend | undefined {\n\t\treturn new GenericVisualizationBackend(session, this.debuggerView);\n\t}\n}\n\nexport class GenericVisualizationBackend extends VisualizationBackendBase {\n\tpublic readonly expressionLanguageId = \"text\";\n\n\tconstructor(\n\t\tdebugSession: DebugSessionProxy,\n\t\tdebuggerView: DebuggerViewProxy\n\t) {\n\t\tsuper(debugSession, debuggerView);\n\t}\n\n\tpublic async getVisualizationData({\n\t\texpression,\n\t\tpreferredExtractorId,\n\t}: GetVisualizationDataArgs): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t> {\n\t\tconst frameId = this.debuggerView.getActiveStackFrameId(\n\t\t\tthis.debugSession\n\t\t);\n\n\t\tconst finalExpression = this.getFinalExpression({\n\t\t\texpression,\n\t\t\tpreferredExtractorId,\n\t\t});\n\t\tlet reply: { result: string; variablesReference: number };\n\t\ttry {\n\t\t\treply = await this.debugSession.evaluate({\n\t\t\t\texpression: finalExpression,\n\t\t\t\tframeId,\n\t\t\t\tcontext: this.getContext(),\n\t\t\t});\n\n\t\t\tconst result = parseEvaluationResultFromGenericDebugAdapter(\n\t\t\t\treply.result,\n\t\t\t\t{\n\t\t\t\t\tdebugAdapterType:\n\t\t\t\t\t\tthis.debugSession.session.configuration.type,\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (result.kind === \"data\") {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\t// Use structural information about variables\n\t\t\t// from the evaluation response if present.\n\t\t\tif (reply.variablesReference) {\n\t\t\t\tconst graph = await this.constructGraphFromVariablesReference(\n\t\t\t\t\treply.result,\n\t\t\t\t\treply.variablesReference\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"data\",\n\t\t\t\t\tresult: {\n\t\t\t\t\t\tavailableExtractors: [],\n\t\t\t\t\t\tusedExtractor: {\n\t\t\t\t\t\t\tid: \"generic\" as any,\n\t\t\t\t\t\t\tname: \"Generic\",\n\t\t\t\t\t\t\tpriority: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdata: graph,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error: any) {\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: {\n\t\t\t\t\tkind: \"list\",\n\t\t\t\t\titems: [\n\t\t\t\t\t\t\"An error occurred while evaluating the expression:\",\n\t\t\t\t\t\terror.message,\n\t\t\t\t\t\t`Used debug adapter: ${this.debugSession.session.configuration.type}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"inlineList\",\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\"Evaluated expression is\",\n\t\t\t\t\t\t\t\t{ kind: \"code\", content: finalExpression },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Constructs GraphVisualizationData from a DAP variables\n\t * reference by successively querying the debug adapter for\n\t * variables. Objects are considered to be equivalent if\n\t * they share the same variables reference (this is important\n\t * for representing cyclic relationships).\n\t *\n\t * @param rootLabel - The root object's label\n\t * @param rootVariablesReference - The root object's DAP variables reference\n\t * @param maxDepth - The maximum depth to search at\n\t * @param maxKnownNodes - The maximum number of nodes\n\t */\n\tprivate async constructGraphFromVariablesReference(\n\t\trootLabel: string,\n\t\trootVariablesReference: number,\n\t\tmaxDepth: number = 30,\n\t\tmaxKnownNodes: number = 50\n\t): Promise<GraphVisualizationData> {\n\t\t// Perform a breadth-first search on the object to construct the graph\n\n\t\tconst graph: GraphVisualizationData = {\n\t\t\tkind: { graph: true },\n\t\t\tnodes: [],\n\t\t\tedges: [],\n\t\t};\n\t\tconst knownNodeIds: { [ref: number]: string } = {};\n\t\tconst bfsQueue: {\n\t\t\tsource: { id: string; name: string } | undefined;\n\t\t\tlabel: string;\n\t\t\tvariablesReference: number;\n\t\t\tdepth: number;\n\t\t}[] = [\n\t\t\t\t{\n\t\t\t\t\tsource: undefined,\n\t\t\t\t\tlabel: rootLabel,\n\t\t\t\t\tvariablesReference: rootVariablesReference,\n\t\t\t\t\tdepth: 0,\n\t\t\t\t},\n\t\t\t];\n\n\t\tlet knownCount: number = 0;\n\n\t\tdo {\n\t\t\tconst variable = bfsQueue.shift()!;\n\t\t\tconst hasChilds = variable.variablesReference > 0;\n\n\t\t\tif (variable.depth > maxDepth) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tlet nodeId: string;\n\n\t\t\tif (!hasChilds || !(variable.variablesReference in knownNodeIds)) {\n\t\t\t\t// The variable is a leaf or an unvisited object: create the node.\n\n\t\t\t\tconst node: GraphNode = {\n\t\t\t\t\tid: hasChilds\n\t\t\t\t\t\t? `${variable.variablesReference}`\n\t\t\t\t\t\t: `__${variable.label}@${knownCount}__`,\n\t\t\t\t\tlabel: variable.label,\n\t\t\t\t\tcolor: variable.depth == 0 ? \"lightblue\" : undefined,\n\t\t\t\t\tshape: \"box\",\n\t\t\t\t};\n\n\t\t\t\tgraph.nodes.push(node);\n\t\t\t\tknownCount++;\n\n\t\t\t\tif (hasChilds) {\n\t\t\t\t\tknownNodeIds[variable.variablesReference] = node.id;\n\n\t\t\t\t\tfor (const child of await this.debugSession.getVariables({\n\t\t\t\t\t\tvariablesReference: variable.variablesReference,\n\t\t\t\t\t})) {\n\t\t\t\t\t\tbfsQueue.push({\n\t\t\t\t\t\t\tsource: { id: node.id, name: child.name },\n\t\t\t\t\t\t\tlabel: child.value,\n\t\t\t\t\t\t\tvariablesReference: child.variablesReference,\n\t\t\t\t\t\t\tdepth: variable.depth + 1,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnodeId = node.id;\n\t\t\t} else {\n\t\t\t\t// The variable is a visited object (e.g. due to a cyclic reference)\n\n\t\t\t\tnodeId = knownNodeIds[variable.variablesReference];\n\t\t\t}\n\n\t\t\tif (variable.source) {\n\t\t\t\tgraph.edges.push({\n\t\t\t\t\tfrom: variable.source.id,\n\t\t\t\t\tto: nodeId,\n\t\t\t\t\tlabel: variable.source.name,\n\t\t\t\t});\n\t\t\t}\n\t\t} while (bfsQueue.length > 0 && knownCount <= maxKnownNodes);\n\n\t\treturn graph;\n\t}\n\n\tprotected getFinalExpression(args: {\n\t\texpression: string;\n\t\tpreferredExtractorId: DataExtractorId | undefined;\n\t}): string {\n\t\treturn args.expression;\n\t}\n\n\tprotected getContext(): \"watch\" | \"repl\" {\n\t\t// we will use \"repl\" as default so that results are not truncated.\n\t\treturn \"repl\";\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/JsVisualizationSupport.ts",
    "content": "import {\n\tApiHasNotBeenInitializedCode,\n\tCallFrameRequest,\n\tCallFramesRequest,\n\tDataExtractionResult,\n\tDataExtractorId,\n\tDataResult,\n\tgetExpressionForDataExtractorApi,\n\tgetExpressionToInitializeDataExtractorApi,\n} from \"@hediet/debug-visualizer-data-extraction\";\nimport { hotClass, registerUpdateReconciler } from \"@hediet/node-reload\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { window } from \"vscode\";\nimport { Config } from \"../Config\";\nimport { DebugSessionProxy, StackFrame, StackTraceInfo } from \"../proxies/DebugSessionProxy\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\nimport { FileWatcher } from \"../webview/WebviewConnection\";\nimport { FormattedMessage } from \"../webviewContract\";\nimport {\n\tDebugSessionVisualizationSupport,\n\tGetVisualizationDataArgs,\n\tVisualizationBackend,\n\tVisualizationBackendBase,\n} from \"./VisualizationBackend\";\n\nregisterUpdateReconciler(module);\n\n@hotClass(module)\nexport class JsEvaluationEngine implements DebugSessionVisualizationSupport {\n\tconstructor(private readonly debuggerView: DebuggerViewProxy, private readonly config: Config) {}\n\n\tcreateBackend(session: DebugSessionProxy): VisualizationBackend | undefined {\n\t\tconst supportedDebugAdapters = [\n\t\t\t\"node\",\n\t\t\t\"node2\",\n\t\t\t\"extensionHost\",\n\t\t\t\"chrome\",\n\t\t\t\"pwa-chrome\",\n\t\t\t\"pwa-node\",\n\t\t\t\"pwa-extensionHost\",\n\t\t\t\"node-terminal\",\n\t\t\t\"pwa-msedge\",\n\t\t];\n\n\t\tif (supportedDebugAdapters.indexOf(session.session.type) !== -1) {\n\t\t\treturn new JsVisualizationBackend(session, this.debuggerView, this.config);\n\t\t}\n\t\treturn undefined;\n\t}\n}\n\nclass CallFrameState {\n\tpublic request: CallFramesRequest | undefined = undefined;\n}\n\nclass JsVisualizationBackend extends VisualizationBackendBase {\n\tpublic readonly expressionLanguageId = \"javascript\";\n\tprivate initializePromise: Promise<void> | undefined = undefined;\n\n\tconstructor(debugSession: DebugSessionProxy, debuggerView: DebuggerViewProxy, private readonly config: Config) {\n\t\tsuper(debugSession, debuggerView);\n\t}\n\n\tprivate getContext(): \"copy\" | \"repl\" {\n\t\tif (this.debugSession.session.type.startsWith(\"pwa-\")) {\n\t\t\treturn \"copy\";\n\t\t}\n\t\treturn \"repl\";\n\t}\n\n\tpublic async getVisualizationData(\n\t\targs: GetVisualizationDataArgs\n\t): Promise<{ kind: \"data\"; result: DataExtractionResult } | { kind: \"error\"; message: FormattedMessage }> {\n\t\tlet result = await this.getVisualizationDataIfInitialized(args);\n\n\t\tif (result.kind === \"not-initialized\") {\n\t\t\tawait this.initializeApiOrWait();\n\t\t\tresult = await this.getVisualizationDataIfInitialized(args);\n\t\t\tif (result.kind === \"not-initialized\") {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"error\",\n\t\t\t\t\tmessage: \"Could not initialize API\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate async getVisualizationDataIfInitialized(\n\t\targs: GetVisualizationDataArgs\n\t): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t\t| { kind: \"not-initialized\" }\n\t> {\n\t\tconst { expression, preferredExtractorId } = args;\n\t\tlet callFrameState: CallFrameState;\n\t\tif (args.sessionStore.data instanceof CallFrameState) {\n\t\t\tcallFrameState = args.sessionStore.data;\n\t\t} else {\n\t\t\tcallFrameState = new CallFrameState();\n\t\t\targs.sessionStore.data = callFrameState;\n\t\t}\n\n\t\ttry {\n\t\t\tconst frameId = this.debuggerView.getActiveStackFrameId(this.debugSession);\n\n\t\t\tconst stackTrace = await this.debuggerView.activeDebugSession!.getStackTrace({\n\t\t\t\tthreadId: 0,\n\t\t\t\tlevels: 20,\n\t\t\t});\n\n\t\t\tconst variableNames = await getVariableNames(this.debugSession, frameId);\n\n\t\t\tlet tryCount = 0;\n\t\t\twhile (true) {\n\t\t\t\ttryCount++;\n\n\t\t\t\tlet callFrameDataValue = \"null\";\n\t\t\t\tif (callFrameState.request) {\n\t\t\t\t\tcallFrameDataValue = await getCallFramesSnapshotValue(\n\t\t\t\t\t\tthis.debugSession,\n\t\t\t\t\t\tstackTrace,\n\t\t\t\t\t\tcallFrameState.request\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst result = await this.evaluateVisualizationDataRequest(\n\t\t\t\t\texpression,\n\t\t\t\t\tpreferredExtractorId,\n\t\t\t\t\tvariableNames,\n\t\t\t\t\tcallFrameDataValue,\n\t\t\t\t\tframeId\n\t\t\t\t);\n\n\t\t\t\tif (result.kind === \"NoExtractors\") {\n\t\t\t\t\tthrow new Error(\"No extractors\");\n\t\t\t\t} else if (result.kind === \"Error\") {\n\t\t\t\t\tthrow new Error(result.message + \"\\n\" + (result as any).stack);\n\t\t\t\t} else if (result.kind === \"Data\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkind: \"data\",\n\t\t\t\t\t\tresult: result.extractionResult,\n\t\t\t\t\t};\n\t\t\t\t} else if (result.kind === \"OutdatedCallFrameSnapshot\") {\n\t\t\t\t\tif (tryCount >= 2) {\n\t\t\t\t\t\tthrow new Error(\"OutdatedCallFrameSnapshot\");\n\t\t\t\t\t}\n\t\t\t\t\tcallFrameState.request = result.callFramesRequest;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Invalid Data\");\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\tif (typeof error.message === \"string\" && error.message.indexOf(ApiHasNotBeenInitializedCode) !== -1) {\n\t\t\t\treturn { kind: \"not-initialized\" };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: error.message,\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate async evaluateVisualizationDataRequest(\n\t\texpression: string,\n\t\tpreferredExtractorId: DataExtractorId | undefined,\n\t\tvariableNames: string[],\n\t\tcallFrameDataValue: string,\n\t\tframeId: number | undefined\n\t): Promise<DataResult> {\n\t\tconst preferredExtractorExpr = preferredExtractorId ? `\"${preferredExtractorId}\"` : \"undefined\";\n\t\tconst body = `${getExpressionForDataExtractorApi()}.getData(\n\t\t\t\t() => (${expression}),\n\t\t\t\texpr => eval(expr),\n\t\t\t\t${preferredExtractorExpr},\n\t\t\t\t{${variableNames.map((n) => `${n}: () => ${n}`).join(\",\")}},\n\t\t\t\t${callFrameDataValue}\n\t\t\t)`;\n\n\t\tconst wrappedExpr = `(() => {\n\ttry { return ${body}; }\n\tcatch (e) { return JSON.stringify({ kind: \"Error\", message: e.message, stack: e.stack }); }\n})()\n\t`;\n\n\t\tconst reply = await this.debugSession.evaluate({\n\t\t\texpression: wrappedExpr,\n\t\t\tframeId,\n\t\t\tcontext: this.getContext(),\n\t\t});\n\t\tconst resultStr = reply.result;\n\t\tconst jsonData = this.getContext() === \"copy\" ? resultStr : resultStr.substr(1, resultStr.length - 2);\n\t\tconst result = JSON.parse(jsonData) as DataResult;\n\t\treturn result;\n\t}\n\n\tprivate initializeApiOrWait(): Promise<void> {\n\t\tif (!this.initializePromise) {\n\t\t\tthis.initializePromise = this.initializeApi().finally(() => (this.initializePromise = undefined));\n\t\t}\n\t\treturn this.initializePromise;\n\t}\n\n\tprivate async initializeApi(): Promise<void> {\n\t\t// prefer existing is true, so that manually registered (possibly newer) extractors are not overwritten.\n\t\tconst expression = `${getExpressionToInitializeDataExtractorApi()}.registerDefaultExtractors(true);`;\n\t\tconst frameId = this.debuggerView.getActiveStackFrameId(this.debugSession);\n\t\tconst result = await this.debugSession.evaluate({\n\t\t\texpression,\n\t\t\tframeId,\n\t\t\tcontext: this.getContext(),\n\t\t});\n\n\t\tawait this.initializeCustomScripts();\n\t}\n\n\tprivate customScripts: undefined | CustomScripts;\n\n\tprivate async initializeCustomScripts(): Promise<void> {\n\t\tthis.dispose.untrack(this.customScripts);\n\t\tthis.customScripts?.dispose();\n\t\tthis.customScripts = this.dispose.track(\n\t\t\tnew CustomScripts(this.debugSession, this.debuggerView, this.config, () => this.onChangeEmitter.emit())\n\t\t);\n\t}\n}\n\nlet globalCallFrameId = 0;\n\nasync function getCallFramesSnapshotValue(\n\tdebugSession: DebugSessionProxy,\n\tstackTrace: StackTraceInfo,\n\tcallFramesRequest: CallFramesRequest\n): Promise<string> {\n\tconst globalFnDef = `\nfunction getGlobal() {\n\tif (typeof globalThis === \"object\") {\n\t\treturn globalThis;\n\t} else if (typeof global === \"object\") {\n\t\treturn global;\n\t} else if (typeof window === \"object\") {\n\t\treturn window;\n\t}\n\tthrow new Error(\"No global available\");\n}`;\n\n\tconst callFrameId = globalCallFrameId++;\n\tlet idx = 0;\n\tlet skippedCount = 0;\n\tconst skippedCounts: Record<number, number> = {};\n\n\tlet frames = stackTrace.stackFrames;\n\tconst firstAsyncFrameIdx = frames.findIndex((f) => f.id === 0);\n\tif (firstAsyncFrameIdx !== -1) {\n\t\tframes = frames.slice(0, firstAsyncFrameIdx);\n\t}\n\n\tconst result = await Promise.all(\n\t\tframes.map(async (frame) => {\n\t\t\tfunction matches(frame: StackFrame, callFrameRequest: CallFrameRequest): boolean {\n\t\t\t\tif (frame.name !== callFrameRequest.methodName) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!callFramesRequest.requestedCallFrames.some((r) => matches(frame, r))) {\n\t\t\t\tif (skippedCount === 0) {\n\t\t\t\t\tidx++;\n\t\t\t\t}\n\t\t\t\tskippedCount++;\n\t\t\t\tskippedCounts[idx - 1] = skippedCount;\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tskippedCount = 0;\n\t\t\tconst curFrameIdx = idx;\n\t\t\tidx++;\n\n\t\t\tconst scopes = await debugSession.getScopes({ frameId: frame.id });\n\t\t\tconst scopeVariables = await Promise.all(\n\t\t\t\tscopes\n\t\t\t\t\t.filter((s) => !s.expensive && s.name.indexOf(\":\") !== -1)\n\t\t\t\t\t.map((s) => debugSession.getVariables({ variablesReference: s.variablesReference }))\n\t\t\t);\n\t\t\tconst variables = new Set(scopeVariables.flatMap((v) => v.map((v) => v.name)));\n\n\t\t\tawait debugSession.evaluate({\n\t\t\t\texpression: `\n(() => {\n\t${globalFnDef}\n\tconst g = getGlobal();\n\t(g.$$hedietDbgVslzr${callFrameId} = g.$$hedietDbgVslzr${callFrameId} || [])[${curFrameIdx}] = {\n\t\tvars: { ${[...variables].map((v) => `${v}: ${v}`).join(\", \")} },\n\t\t...${JSON.stringify({\n\t\t\tmethodName: frame.name,\n\t\t\tsource: { path: frame.source.path, name: frame.source.name },\n\t\t})}\n\t};\n})();\n`,\n\t\t\t\tframeId: frame.id,\n\t\t\t\tcontext: \"repl\",\n\t\t\t});\n\n\t\t\treturn true;\n\t\t})\n\t);\n\n\tif (!result.some((r) => r)) {\n\t\treturn `{ requestId: ${JSON.stringify(callFramesRequest.requestId)}, frames: [] }`;\n\t}\n\n\treturn `\n(() => {\n\t${globalFnDef}\n\tconst g = getGlobal();\n\tconst r = g.$$hedietDbgVslzr${callFrameId};\n\tdelete g.$$hedietDbgVslzr${callFrameId};\n\t${Object.entries(skippedCounts)\n\t\t.map(([idx, val]) => `r[${idx}] = { skippedFrames: ${val} };\\n`)\n\t\t.join(\"\")}\n\treturn { requestId: ${JSON.stringify(callFramesRequest.requestId)}, frames: r };\n})()\n`;\n}\n\nasync function getVariableNames(debugSession: DebugSessionProxy, frameId: number | undefined) {\n\tconst variableNames = new Array<string>();\n\tif (frameId) {\n\t\tconst scopes = await debugSession.getScopes({ frameId });\n\t\tconst scopeVariables = await Promise.all(\n\t\t\tscopes\n\t\t\t\t.filter((s) => !s.expensive && s.name !== \"Global\")\n\t\t\t\t.map((s) =>\n\t\t\t\t\tdebugSession.getVariables({\n\t\t\t\t\t\tvariablesReference: s.variablesReference,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t);\n\t\tfor (const variables of scopeVariables) {\n\t\t\tvariableNames.push(...variables.filter((v) => v.value !== \"undefined\").map((v) => v.name));\n\t\t}\n\n\t\tif (variableNames.length > 50) {\n\t\t\tvariableNames.length = 50;\n\t\t}\n\t}\n\treturn variableNames;\n}\n\nclass CustomScripts {\n\tpublic readonly dispose = Disposable.fn();\n\n\tconstructor(\n\t\tdebugSession: DebugSessionProxy,\n\t\tdebuggerView: DebuggerViewProxy,\n\t\tconfig: Config,\n\t\tchangeHandler: () => void\n\t) {\n\t\tthis.dispose.track(\n\t\t\tnew FileWatcher(\n\t\t\t\t() => config.customScriptPaths,\n\t\t\t\tasync (files) => {\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tif (!file.fileExists) {\n\t\t\t\t\t\t\twindow.showErrorMessage(`The file ${file.path} does not exist.`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet expression = `\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\trunCode => {\n\t\t\t\t\t\t\t\tlet fn = undefined;\n\t\t\t\t\t\t\t\tif (runCode) {\n\t\t\t\t\t\t\t\t\tconst module = {};\n\t\t\t\t\t\t\t\t\trunCode(module);\n\t\t\t\t\t\t\t\t\tfn = module.exports;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t${getExpressionForDataExtractorApi()}.setDataExtractorFn(\n\t\t\t\t\t\t\t\t\t${JSON.stringify(file.path)},\n\t\t\t\t\t\t\t\t\tfn\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t${file.content === undefined ? \"undefined\" : `function (module) { ${file.content} }`}\n\t\t\t\t\t\t)`;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait debugSession.evaluate({\n\t\t\t\t\t\t\t\texpression,\n\t\t\t\t\t\t\t\tframeId: debuggerView.getActiveStackFrameId(debugSession),\n\t\t\t\t\t\t\t\tcontext: \"repl\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\twindow.showErrorMessage(\n\t\t\t\t\t\t\t\t'Error while running custom visualization extractor script \"' +\n\t\t\t\t\t\t\t\t\tfile.path +\n\t\t\t\t\t\t\t\t\t'\": ' +\n\t\t\t\t\t\t\t\t\te.message\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tchangeHandler();\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/PyVisualizationSupport.ts",
    "content": "import {\n\tDataExtractionResult,\n\tDataExtractorId,\n} from \"@hediet/debug-visualizer-data-extraction\";\nimport { hotClass, registerUpdateReconciler } from \"@hediet/node-reload\";\nimport { Config } from \"../Config\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\nimport { FormattedMessage } from \"../webviewContract\";\nimport {\n\tDebugSessionVisualizationSupport,\n\tGetVisualizationDataArgs,\n\tVisualizationBackend,\n\tVisualizationBackendBase,\n} from \"./VisualizationBackend\";\nimport { parseEvaluationResultFromGenericDebugAdapter } from \"./parseEvaluationResultFromGenericDebugAdapter\";\n\nregisterUpdateReconciler(module);\n\n@hotClass(module)\nexport class PyEvaluationEngine implements DebugSessionVisualizationSupport {\n\tconstructor(\n\t\tprivate readonly debuggerView: DebuggerViewProxy,\n\t\tprivate readonly config: Config\n\t) {}\n\n\tcreateBackend(\n\t\tsession: DebugSessionProxy\n\t): VisualizationBackend | undefined {\n\t\tconst supportedDebugAdapters = [\"python\", \"debugpy\"];\n\n\t\tif (supportedDebugAdapters.indexOf(session.session.type) !== -1) {\n\t\t\treturn new PyVisualizationBackend(\n\t\t\t\tsession,\n\t\t\t\tthis.debuggerView,\n\t\t\t\tthis.config\n\t\t\t);\n\t\t}\n\t\treturn undefined;\n\t}\n}\n\nexport class PyVisualizationBackend extends VisualizationBackendBase {\n\tpublic readonly expressionLanguageId = \"python\";\n\n\tconstructor(\n\t\tdebugSession: DebugSessionProxy,\n\t\tdebuggerView: DebuggerViewProxy,\n\t\tprivate readonly config: Config\n\t) {\n\t\tsuper(debugSession, debuggerView);\n\t}\n\n\tprotected getContext(): \"watch\" | \"repl\" {\n\t\t// we will use \"repl\" as default so that results are not truncated.\n\t\treturn \"repl\";\n\t}\n\n\tpublic async getVisualizationData({\n\t\texpression,\n\t\tpreferredExtractorId,\n\t}: GetVisualizationDataArgs): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t> {\n\t\tconst frameId = this.debuggerView.getActiveStackFrameId(\n\t\t\tthis.debugSession\n\t\t);\n\n\t\tconst finalExpression = this.getFinalExpression({\n\t\t\texpression,\n\t\t\tpreferredExtractorId,\n\t\t});\n\t\tlet reply: { result: string; variablesReference: number };\n\t\ttry {\n\t\t\t// inject vscodedebugvisualizer for python\n\t\t\tawait this.debugSession.evaluate({\n\t\t\t\texpression:\n\t\t\t\t\t\"from vscodedebugvisualizer import visualize\\ntry:\\n  import debugvisualizer\\nexcept ImportError:\\n  pass\",\n\t\t\t\tframeId,\n\t\t\t\tcontext: this.getContext(),\n\t\t\t});\n\n\t\t\treply = await this.debugSession.evaluate({\n\t\t\t\texpression: finalExpression,\n\t\t\t\tframeId,\n\t\t\t\tcontext: this.getContext(),\n\t\t\t});\n\n\t\t\tlet result = reply.result;\n\t\t\t// remove the initial escape by the the debug session e.g. `''{\"kind\": {\"text\": true}, \"text\": \"{\"asdf1\\'\"}''`\n\t\t\tresult = result.replace(/\\\\'/g, \"'\");\n\t\t\tresult = result.replace(/\\\\\\\\/g, \"\\\\\");\n\n\t\t\treturn parseEvaluationResultFromGenericDebugAdapter(result, {\n\t\t\t\tdebugAdapterType: this.debugSession.session.configuration.type,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet errorTyped = error as Error;\n\t\t\tif (\n\t\t\t\terrorTyped.message.includes(\n\t\t\t\t\t\"ModuleNotFoundError: No module named 'vscodedebugvisualizer'\"\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"error\",\n\t\t\t\t\tmessage: {\n\t\t\t\t\t\tkind: \"list\",\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\"Please make sure vscodedebugvisualizer is installed: `pip install vscodedebugvisualizer`\",\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: {\n\t\t\t\t\tkind: \"list\",\n\t\t\t\t\titems: [\n\t\t\t\t\t\t\"An error occurred while evaluating the expression:\",\n\t\t\t\t\t\terrorTyped.message,\n\t\t\t\t\t\t`Used debug adapter: ${this.debugSession.session.configuration.type}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"inlineList\",\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\"Evaluated expression is\",\n\t\t\t\t\t\t\t\t{ kind: \"code\", content: finalExpression },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\tprotected getFinalExpression(args: {\n\t\texpression: string;\n\t\tpreferredExtractorId: DataExtractorId | undefined;\n\t}): string {\n\t\t// wrap expression with visualize function\n\t\tlet pythonInject = \"\";\n\t\tpythonInject += \"visualize(\" + args.expression + \")\";\n\t\treturn pythonInject;\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/RbVisualizationSupport.ts",
    "content": "import {\n\tDataExtractionResult,\n\tDataResult,\n} from \"@hediet/debug-visualizer-data-extraction\";\nimport { hotClass, registerUpdateReconciler } from \"@hediet/node-reload\";\nimport { Config } from \"../Config\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\nimport { FormattedMessage } from \"../webviewContract\";\nimport {\n\tDebugSessionVisualizationSupport,\n\tGetVisualizationDataArgs,\n\tVisualizationBackend,\n\tVisualizationBackendBase,\n} from \"./VisualizationBackend\";\n\nregisterUpdateReconciler(module);\n\n@hotClass(module)\nexport class RbEvaluationEngine implements DebugSessionVisualizationSupport {\n\tconstructor(\n\t\tprivate readonly debuggerView: DebuggerViewProxy,\n\t\tprivate readonly config: Config\n\t) {}\n\n\tcreateBackend(\n\t\tsession: DebugSessionProxy\n\t): VisualizationBackend | undefined {\n\t\tconst supportedDebugAdapters = [\"rdbg\"];\n\n\t\tif (supportedDebugAdapters.indexOf(session.session.type) !== -1) {\n\t\t\treturn new RbVisualizationBackend(\n\t\t\t\tsession,\n\t\t\t\tthis.debuggerView,\n\t\t\t\tthis.config\n\t\t\t);\n\t\t}\n\t\treturn undefined;\n\t}\n}\n\nclass RbVisualizationBackend extends VisualizationBackendBase {\n\tpublic readonly expressionLanguageId = \"ruby\";\n\tconstructor(\n\t\tdebugSession: DebugSessionProxy,\n\t\tdebuggerView: DebuggerViewProxy,\n\t\tprivate readonly config: Config\n\t) {\n\t\tsuper(debugSession, debuggerView);\n\t}\n\n\tprivate readonly defaultContext = \"repl\";\n\n\tpublic async getVisualizationData(\n\t\targs: GetVisualizationDataArgs\n\t): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t> {\n\t\tconst result = await this._getVisualizationData(args);\n\t\treturn result;\n\t}\n\n\tprivate async _getVisualizationData({\n\t\texpression,\n\t\tpreferredExtractorId,\n\t}: GetVisualizationDataArgs): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t> {\n\t\ttry {\n\t\t\tif (expression.length === 0) throw new Error(\"No extractors\");\n\n\t\t\tconst frameId = this.debuggerView.getActiveStackFrameId(\n\t\t\t\tthis.debugSession\n\t\t\t);\n\t\t\tconst initialReply = await this.debugSession.evaluate({\n\t\t\t\texpression: \"require 'debugvisualizer'\",\n\t\t\t\tframeId,\n\t\t\t\tcontext: this.defaultContext,\n\t\t\t});\n\t\t\tif (initialReply.result.includes(\"LoadError\")) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"error\",\n\t\t\t\t\tmessage: {\n\t\t\t\t\t\tkind: \"list\",\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\"LoadError: Failed to load debugvisualizer.\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: \"inlineList\",\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t\"Install the gem by executing:\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: \"code\",\n\t\t\t\t\t\t\t\t\t\tcontent: \"$ bundle add debugvisualizer\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: \"inlineList\",\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t\"If bundler is not being used, install the gem by executing:\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkind: \"code\",\n\t\t\t\t\t\t\t\t\t\tcontent:\n\t\t\t\t\t\t\t\t\t\t\t\"$ gem install debugvisualizer\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst preferredId = preferredExtractorId || \"\";\n\t\t\tconst wrappedExpr = `\n\t\t\t\tDebugVisualizer.to_debug_visualizer_protocol_json(\"${preferredId}\", ${expression})\n\t\t\t`;\n\t\t\tconst reply = await this.debugSession.evaluate({\n\t\t\t\texpression: wrappedExpr,\n\t\t\t\tframeId,\n\t\t\t\tcontext: this.defaultContext,\n\t\t\t});\n\n\t\t\tlet dataResult: DataResult;\n\t\t\ttry {\n\t\t\t\t// Debuggee converts result to a JSON string twice.\n\t\t\t\tdataResult = JSON.parse(JSON.parse(reply.result)) as DataResult;\n\t\t\t} catch (error: any) {\n\t\t\t\tlet message = error.message;\n\t\t\t\t// The `reply.result` is as follows when error occurs in the evaluation of an expression and parsing will fail.\n\t\t\t\t// e.g. \"#<ZeroDivisionError: divided by 0>\"\n\t\t\t\t// In this case, it is more beneficial to display this error message.\n\t\t\t\tif (reply.result.includes(\"Error\")) message = reply.result;\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\n\t\t\tswitch (dataResult.kind) {\n\t\t\t\tcase \"NoExtractors\":\n\t\t\t\t\tthrow new Error(\"No extractors\");\n\t\t\t\tcase \"Error\":\n\t\t\t\t\tthrow new Error(dataResult.message);\n\t\t\t\tcase \"Data\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkind: \"data\",\n\t\t\t\t\t\tresult: dataResult.extractionResult,\n\t\t\t\t\t};\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\"Invalid Data\");\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: error.message,\n\t\t\t};\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/VisualizationBackend.ts",
    "content": "import {\n\tDataExtractionResult,\n\tDataExtractorId,\n} from \"@hediet/debug-visualizer-data-extraction\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { EventEmitter, EventSource } from \"@hediet/std/events\";\nimport { reaction } from \"mobx\";\nimport { DebugSessionProxy } from \"../proxies/DebugSessionProxy\";\nimport { DebuggerViewProxy } from \"../proxies/DebuggerViewProxy\";\nimport { CompletionItem, FormattedMessage } from \"../webviewContract\";\n\nexport interface DebugSessionVisualizationSupport {\n\tcreateBackend(session: DebugSessionProxy): VisualizationBackend | undefined;\n}\n\nexport interface VisualizationBackend extends Disposable {\n\treadonly onChange: EventSource;\n\n\tgetVisualizationData(\n\t\targs: GetVisualizationDataArgs\n\t): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t>;\n\n\t/**\n\t * The language that expressions must be written in.\n\t */\n\treadonly expressionLanguageId: string | undefined;\n\n\tgetCompletions(text: string, column: number): Promise<CompletionItem[]>;\n}\n\nexport interface GetVisualizationDataArgs {\n\treadonly expression: string;\n\treadonly preferredExtractorId: DataExtractorId | undefined;\n\n\t// Can be used to attach data to the session.\n\treadonly sessionStore: { data: unknown };\n}\n\nexport abstract class VisualizationBackendBase implements VisualizationBackend {\n\tpublic readonly dispose = Disposable.fn();\n\n\tprotected readonly onChangeEmitter = new EventEmitter();\n\tpublic readonly onChange = this.onChangeEmitter;\n\n\tconstructor(\n\t\tprotected readonly debugSession: DebugSessionProxy,\n\t\tprotected readonly debuggerView: DebuggerViewProxy\n\t) {\n\t\tthis.dispose.track({\n\t\t\tdispose: reaction(\n\t\t\t\t() => debuggerView.getActiveStackFrameId(debugSession),\n\t\t\t\t(activeStackFrameId) => {\n\t\t\t\t\tif (activeStackFrameId !== undefined) {\n\t\t\t\t\t\tthis.onChangeEmitter.emit();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t),\n\t\t});\n\t}\n\n\tpublic abstract readonly expressionLanguageId: string | undefined;\n\n\tpublic abstract getVisualizationData(\n\t\targs: GetVisualizationDataArgs\n\t): Promise<\n\t\t| { kind: \"data\"; result: DataExtractionResult }\n\t\t| { kind: \"error\"; message: FormattedMessage }\n\t>;\n\n\tpublic async getCompletions(\n\t\ttext: string,\n\t\tcolumn: number\n\t): Promise<CompletionItem[]> {\n\t\treturn await this.debugSession.getCompletions({\n\t\t\ttext,\n\t\t\tframeId: this.debuggerView.getActiveStackFrameId(this.debugSession),\n\t\t\tcolumn,\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationBackend/index.ts",
    "content": "export * from \"./VisualizationBackend\";\n\nexport { ComposedVisualizationSupport } from \"./ComposedVisualizationSupport\";\nexport { JsEvaluationEngine } from \"./JsVisualizationSupport\";\nexport { PyEvaluationEngine } from \"./PyVisualizationSupport\";\nexport { RbEvaluationEngine } from './RbVisualizationSupport';\nexport { GenericVisualizationSupport } from \"./GenericVisualizationSupport\";\nexport { ConfigurableVisualizationSupport } from \"./ConfigurableVisualizationSupport\";\n"
  },
  {
    "path": "extension/src/VisualizationBackend/parseEvaluationResultFromGenericDebugAdapter.ts",
    "content": "import {\n\tDataExtractionResult,\n\tisVisualizationData,\n} from \"@hediet/debug-visualizer-data-extraction\";\nimport { FormattedMessage } from \"../webviewContract\";\n\nexport interface ParseEvaluationResultContext {\n\tdebugAdapterType: string;\n}\n\nexport function parseEvaluationResultFromGenericDebugAdapter(\n\tresultText: string,\n\tcontext: ParseEvaluationResultContext\n):\n\t| { kind: \"data\"; result: DataExtractionResult }\n\t| { kind: \"error\"; message: FormattedMessage } {\n\tconst jsonData = resultText.trim();\n\n\tlet resultObj;\n\ttry {\n\t\ttry {\n\t\t\tlet jsonData2;\n\t\t\t// Remove optionally enclosing characters.\n\t\t\tif (\n\t\t\t\tisEnclosedWith(jsonData, '\"') ||\n\t\t\t\tisEnclosedWith(jsonData, \"'\")\n\t\t\t) {\n\t\t\t\t// In case of JavaScript: `\"{ \"kind\": { ... }, \"text\": \"some\\ntext\" }\"`\n\t\t\t\tjsonData2 = jsonData.substr(1, jsonData.length - 2);\n\t\t\t} else {\n\t\t\t\t// Just in case no quoting is done.\n\t\t\t\tjsonData2 = jsonData;\n\t\t\t}\n\t\t\tresultObj = parseJson(jsonData2, context);\n\t\t} catch (e) {\n\t\t\t// in case of C++: `\"{ \\\"kind\\\": { ... }, \\\"text\\\": \\\"some\\\\ntext\\\" }\"`\n\t\t\tconst str = parseJson(jsonData, context);\n\t\t\t// str is now `{ \"kind\": { ... }, \"text\": \"some\\ntext\" }\"`\n\t\t\tresultObj = parseJson(str, context);\n\t\t\t// result is now { kind: { ... }, text: \"some\\ntext\" }\n\t\t}\n\n\t\tif (!isVisualizationData(resultObj)) {\n\t\t\treturn {\n\t\t\t\tkind: \"error\",\n\t\t\t\tmessage: {\n\t\t\t\t\tkind: \"list\",\n\t\t\t\t\titems: [\n\t\t\t\t\t\t\"Evaluation result does not match ExtractedData interface.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"inlineList\",\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\"Evaluation result was:\",\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tkind: \"code\",\n\t\t\t\t\t\t\t\t\tcontent: JSON.stringify(\n\t\t\t\t\t\t\t\t\t\tresultObj,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\t4\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t} catch (e: any) {\n\t\treturn {\n\t\t\tkind: \"error\",\n\t\t\tmessage: e.message,\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"data\",\n\t\tresult: {\n\t\t\tavailableExtractors: [],\n\t\t\tusedExtractor: {\n\t\t\t\tid: \"generic\" as any,\n\t\t\t\tname: \"Generic\",\n\t\t\t\tpriority: 1,\n\t\t\t},\n\t\t\tdata: resultObj,\n\t\t},\n\t};\n}\n\nfunction isEnclosedWith(str: string, char: string): boolean {\n\treturn str.startsWith(char) && str.endsWith(char);\n}\n\nfunction parseJson(str: string, context: ParseEvaluationResultContext) {\n\ttry {\n\t\treturn JSON.parse(str);\n\t} catch (error: any) {\n\t\tthrow new FormattedError({\n\t\t\tkind: \"list\",\n\t\t\titems: [\n\t\t\t\t\"Could not parse evaluation result as JSON:\",\n\t\t\t\terror.message,\n\t\t\t\t{\n\t\t\t\t\tkind: \"inlineList\",\n\t\t\t\t\titems: [\n\t\t\t\t\t\t\"Evaluation result was:\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"code\",\n\t\t\t\t\t\t\tcontent: str,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t`Used debug adapter: ${context.debugAdapterType}`,\n\t\t\t],\n\t\t});\n\t}\n}\n\nclass FormattedError {\n\tconstructor(public readonly message: FormattedMessage) {}\n}\n"
  },
  {
    "path": "extension/src/VisualizationWatchModel/VisualizationWatchModel.ts",
    "content": "import { DataExtractorId } from \"@hediet/debug-visualizer-data-extraction\";\nimport { CompletionItem, DataExtractionState } from \"../webviewContract\";\n\nexport interface VisualizationWatchModel {\n\tcreateWatch(\n\t\texpression: string,\n\t\toptions: VisualizationWatchOptions\n\t): VisualizationWatch;\n\n\tgetCompletions(text: string, column: number): Promise<CompletionItem[]>;\n\n\t/**\n\t * The language the expressions must be written in.\n\t * `undefined`, if unknown.\n\t * This field is observable.\n\t */\n\treadonly languageId: string | undefined;\n}\n\nexport interface VisualizationWatchOptions {\n\tpreferredDataExtractor?: DataExtractorId | undefined;\n\tsessionState?: unknown;\n}\n\nexport interface VisualizationWatch {\n\t/** This field is constant. */\n\treadonly expression: string;\n\n\t/** This field is observable */\n\treadonly state: DataExtractionState;\n\n\t/** This field is observable */\n\treadonly preferredDataExtractor: DataExtractorId | undefined;\n\n\treadonly sessionState: unknown;\n\n\tsetPreferredDataExtractor(id: DataExtractorId | undefined): void;\n\trefresh(): void;\n\tdispose(): void;\n}\n"
  },
  {
    "path": "extension/src/VisualizationWatchModel/VisualizationWatchModelImpl.ts",
    "content": "import { DataExtractorId } from \"@hediet/debug-visualizer-data-extraction\";\nimport { hotClass } from \"@hediet/node-reload\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { EventEmitter } from \"@hediet/std/events\";\nimport { wait } from \"@hediet/std/timer\";\nimport { action, observable } from \"mobx\";\nimport { CancellationToken, CancellationTokenSource } from \"vscode\";\nimport { VisualizationBackend } from \"../VisualizationBackend/VisualizationBackend\";\nimport { CompletionItem, DataExtractionState } from \"../webviewContract\";\nimport { VisualizationWatch, VisualizationWatchModel, VisualizationWatchOptions } from \"./VisualizationWatchModel\";\n\n@hotClass(module)\nexport class VisualizationWatchModelImpl implements VisualizationWatchModel {\n\tpublic readonly dispose = Disposable.fn();\n\tprivate readonly watchers = new Set<ObservableVisualizationWatch>();\n\n\tconstructor(private readonly visualizationBackend: VisualizationBackend) {\n\t\tthis.dispose.track(\n\t\t\tvisualizationBackend.onChange.sub(() => {\n\t\t\t\tif (visualizationBackend.expressionLanguageId !== undefined) {\n\t\t\t\t\tthis.lastLanguageId = visualizationBackend.expressionLanguageId;\n\t\t\t\t}\n\t\t\t})\n\t\t);\n\t\tthis.lastLanguageId = visualizationBackend.expressionLanguageId;\n\t}\n\n\tpublic createWatch(expression: string, options: VisualizationWatchOptions): VisualizationWatch {\n\t\tconst w = new ObservableVisualizationWatch(expression, options, this.visualizationBackend);\n\t\tw.onDispose.sub(() => {\n\t\t\tthis.watchers.delete(w);\n\t\t});\n\t\tthis.watchers.add(w);\n\t\treturn w;\n\t}\n\n\t@observable\n\tprivate lastLanguageId: string | undefined = undefined;\n\n\tget languageId(): string | undefined {\n\t\treturn this.lastLanguageId;\n\t}\n\n\tpublic getCompletions(text: string, column: number): Promise<CompletionItem[]> {\n\t\treturn this.visualizationBackend.getCompletions(text, column);\n\t}\n}\n\nclass ObservableVisualizationWatch implements VisualizationWatch {\n\tpublic readonly dispose = Disposable.fn();\n\tprivate readonly onDisposeEmitter = new EventEmitter();\n\tpublic readonly onDispose = this.onDisposeEmitter.asEvent();\n\n\tconstructor(\n\t\tpublic readonly expression: string,\n\t\toptions: VisualizationWatchOptions,\n\t\tprivate readonly visualizationBackend: VisualizationBackend\n\t) {\n\t\tthis._preferredDataExtractor = options.preferredDataExtractor;\n\n\t\tthis.dispose.track(\n\t\t\tvisualizationBackend.onChange.sub(() => {\n\t\t\t\tthis.refresh();\n\t\t\t})\n\t\t);\n\n\t\tthis.dispose.track({\n\t\t\tdispose: () => {\n\t\t\t\tthis.onDisposeEmitter.emit();\n\t\t\t},\n\t\t});\n\n\t\tthis.refresh();\n\t}\n\n\tprivate _preferredDataExtractor: DataExtractorId | undefined = undefined;\n\n\tpublic get preferredDataExtractor(): DataExtractorId | undefined {\n\t\treturn this._preferredDataExtractor;\n\t}\n\n\t@action\n\tpublic setPreferredDataExtractor(id: DataExtractorId | undefined): void {\n\t\tthis._preferredDataExtractor = id;\n\t\tthis.refresh();\n\t}\n\n\tprivate runningRefreshOperation: Disposable | undefined;\n\n\tpublic refresh(): void {\n\t\tif (this.runningRefreshOperation) {\n\t\t\tthis.runningRefreshOperation.dispose();\n\t\t}\n\t\tconst tokenSource = new CancellationTokenSource();\n\t\tthis.runningRefreshOperation = {\n\t\t\tdispose: () => {\n\t\t\t\ttokenSource.cancel();\n\t\t\t},\n\t\t};\n\t\tthis._refresh(tokenSource.token);\n\t}\n\n\tpublic sessionState: unknown = undefined;\n\n\tprivate async _refresh(token: CancellationToken): Promise<void> {\n\t\tthis._state = { kind: \"loading\" };\n\t\tconst that = this;\n\t\tconst result = await this.visualizationBackend.getVisualizationData({\n\t\t\texpression: this.expression,\n\t\t\tpreferredExtractorId: this.preferredDataExtractor,\n\t\t\tsessionStore: {\n\t\t\t\tget data(): unknown {\n\t\t\t\t\treturn that.sessionState;\n\t\t\t\t},\n\t\t\t\tset data(value: unknown) {\n\t\t\t\t\tthat.sessionState = value;\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\tif (result.kind === \"error\") {\n\t\t\t// give cancellation requested more time in case of errors\n\t\t\tawait wait(330);\n\t\t}\n\n\t\tif (token.isCancellationRequested) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._state = result;\n\t}\n\n\t@observable\n\tpublic _state: DataExtractionState = { kind: \"loading\" };\n\tpublic get state(): DataExtractionState {\n\t\treturn this._state;\n\t}\n}\n"
  },
  {
    "path": "extension/src/VisualizationWatchModel/index.ts",
    "content": "export * from \"./VisualizationWatchModelImpl\";\nexport * from \"./VisualizationWatchModel\";\n"
  },
  {
    "path": "extension/src/extension.ts",
    "content": "import { window, ExtensionContext, commands } from \"vscode\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport {\n\tenableHotReload,\n\thotRequireExportedFn,\n\tregisterUpdateReconciler,\n\tgetReloadCount,\n} from \"@hediet/node-reload\";\n\nif (process.env.HOT_RELOAD) {\n\tenableHotReload({ entryModule: module, loggingEnabled: true });\n}\nregisterUpdateReconciler(module);\n\nimport { InternalWebviewManager } from \"./webview/InternalWebviewManager\";\nimport { WebviewServer } from \"./webview/WebviewServer\";\nimport { Config } from \"./Config\";\nimport { DebuggerProxy } from \"./proxies/DebuggerProxy\";\nimport { DebuggerViewProxy } from \"./proxies/DebuggerViewProxy\";\nimport { VisualizationWatchModelImpl } from \"./VisualizationWatchModel\";\nimport {\n\tComposedVisualizationSupport,\n\tJsEvaluationEngine,\n\tPyEvaluationEngine,\n\tRbEvaluationEngine,\n\tGenericVisualizationSupport,\n\tConfigurableVisualizationSupport,\n} from \"./VisualizationBackend\";\nimport { DispatchingVisualizationBackend } from \"./VisualizationBackend/DispatchingVisualizationBackend\";\n\nexport function activate(context: ExtensionContext) {\n\tcontext.subscriptions.push(\n\t\thotRequireExportedFn(module, Extension, Extension => new Extension())\n\t);\n}\n\nexport function deactivate() { }\n\nexport class Extension {\n\tpublic readonly dispose = Disposable.fn();\n\n\tprivate readonly config = new Config();\n\tprivate readonly debugger = this.dispose.track(new DebuggerProxy());\n\tprivate readonly debuggerView = this.dispose.track(\n\t\tnew DebuggerViewProxy(this.debugger)\n\t);\n\n\tpublic readonly dataSource = new VisualizationWatchModelImpl(\n\t\tnew DispatchingVisualizationBackend(\n\t\t\tnew ComposedVisualizationSupport([\n\t\t\t\tnew ConfigurableVisualizationSupport(\n\t\t\t\t\tthis.config,\n\t\t\t\t\tthis.debuggerView\n\t\t\t\t),\n\t\t\t\tnew JsEvaluationEngine(this.debuggerView, this.config),\n\t\t\t\tnew PyEvaluationEngine(this.debuggerView, this.config),\n\t\t\t\tnew RbEvaluationEngine(this.debuggerView, this.config),\n\t\t\t\tnew GenericVisualizationSupport(this.debuggerView),\n\t\t\t]),\n\t\t\tthis.debuggerView\n\t\t)\n\t);\n\n\tprivate readonly server = new WebviewServer(this.dataSource, this.config);\n\tprivate readonly views = this.dispose.track(\n\t\tnew InternalWebviewManager(this.server, this.config)\n\t);\n\n\tconstructor() {\n\t\tif (getReloadCount(module) > 0) {\n\t\t\tconst i = this.dispose.track(window.createStatusBarItem());\n\t\t\ti.text = \"reload\" + getReloadCount(module);\n\t\t\ti.show();\n\t\t}\n\n\t\tthis.dispose.track(\n\t\t\tcommands.registerCommand(\n\t\t\t\t\"vscode-debug-visualizer.new-visualizer\",\n\t\t\t\t() => {\n\t\t\t\t\tthis.views.createNew();\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\n\t\tthis.dispose.track(\n\t\t\tcommands.registerCommand(\n\t\t\t\t\"vscode-debug-visualizer.visualizer-set-expression\",\n\t\t\t\t() => {\n\t\t\t\t\tconst editor = window.activeTextEditor;\n\t\t\t\t\tif (!editor) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst selection = editor.selection;\n\n\t\t\t\t\tlet selectedText;\n\t\t\t\t\tif (selection.isEmpty) {\n\t\t\t\t\t\tconst lineText = editor.document.lineAt(selection.start)\n\t\t\t\t\t\t\t.text;\n\t\t\t\t\t\tconst regexp = /`(.*)`/g;\n\t\t\t\t\t\tselectedText = \"\";\n\t\t\t\t\t\tlet match;\n\t\t\t\t\t\twhile ((match = regexp.exec(lineText))) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tmatch.index <= selection.start.character &&\n\t\t\t\t\t\t\t\tselection.start.character <=\n\t\t\t\t\t\t\t\tmatch.index + match[0].length\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tselectedText = match[1];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tselectedText = editor.document.getText(selection);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!selectedText) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst connections = [...this.server.connections.values()];\n\t\t\t\t\tconst latestConnection =\n\t\t\t\t\t\tconnections[connections.length - 1];\n\n\t\t\t\t\tif (latestConnection) {\n\t\t\t\t\t\tlatestConnection.setExpression(selectedText);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.views.createNew(selectedText);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "extension/src/proxies/DebugSessionProxy.ts",
    "content": "import { observable } from \"mobx\";\nimport { DebugSession } from \"vscode\";\nimport { CompletionItem } from \"../webviewContract\";\n\nexport class DebugSessionProxy {\n\t@observable private _activeStackFrameId: number | undefined;\n\n\tconstructor(public readonly session: DebugSession) {}\n\n\tpublic async getStackTrace(args: {\n\t\tthreadId: number;\n\t\tstartFrame?: number;\n\t\tlevels?: number;\n\t}): Promise<StackTraceInfo> {\n\t\ttry {\n\t\t\tconst reply = (await this.session.customRequest(\"stackTrace\", {\n\t\t\t\tthreadId: args.threadId,\n\t\t\t\tlevels: args.levels,\n\t\t\t\tstartFrame: args.startFrame || 0,\n\t\t\t})) as { totalFrames?: number; stackFrames: StackFrame[] };\n\t\t\treturn reply;\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tpublic async getCompletions(args: {\n\t\ttext: string;\n\t\tcolumn: number;\n\t\tframeId: number | undefined;\n\t}): Promise<CompletionItem[]> {\n\t\ttry {\n\t\t\tconst reply = await this.session.customRequest(\"completions\", {\n\t\t\t\ttext: args.text,\n\t\t\t\tframeId: args.frameId,\n\t\t\t\tcolumn: args.column,\n\t\t\t});\n\t\t\tif (!reply) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn reply.targets;\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tpublic async getScopes(args: { frameId: number }): Promise<Scope[]> {\n\t\ttry {\n\t\t\tconst reply = await this.session.customRequest(\"scopes\", {\n\t\t\t\tframeId: args.frameId,\n\t\t\t});\n\t\t\tif (!reply) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn reply.scopes;\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tpublic async getVariables(args: { variablesReference: number }): Promise<Variable[]> {\n\t\ttry {\n\t\t\tconst reply = await this.session.customRequest(\"variables\", {\n\t\t\t\tvariablesReference: args.variablesReference,\n\t\t\t});\n\t\t\tif (!reply) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn reply.variables;\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Evaluates the given expression.\n\t * If context is \"watch\", long results are usually shortened.\n\t */\n\n\tpublic async evaluate(args: {\n\t\texpression: string;\n\t\tframeId: number | undefined;\n\t\tcontext: \"watch\" | \"repl\" | \"copy\";\n\t}): Promise<{ result: string; variablesReference: number }> {\n\t\tconst reply = await this.session.customRequest(\"evaluate\", {\n\t\t\texpression: args.expression,\n\t\t\tframeId: args.frameId,\n\t\t\tcontext: args.context,\n\t\t});\n\t\treturn {\n\t\t\tresult: reply.result,\n\t\t\tvariablesReference: reply.variablesReference,\n\t\t};\n\t}\n}\n\nexport interface StackTraceInfo {\n\ttotalFrames?: number;\n\tstackFrames: StackFrame[];\n}\n\ninterface Scope {\n\tname: string;\n\texpensive: boolean;\n\tvariablesReference: number;\n}\n\ninterface Variable {\n\tname: string;\n\tvalue: string;\n\tvariablesReference: number;\n}\n\nexport interface StackFrame {\n\tid: number;\n\tname: string;\n\tsource: { name: string; path: string };\n}\n"
  },
  {
    "path": "extension/src/proxies/DebuggerProxy.ts",
    "content": "import { Disposable } from \"@hediet/std/disposable\";\nimport { EventEmitter } from \"@hediet/std/events\";\nimport { debug, DebugSession } from \"vscode\";\nimport { DebugSessionProxy } from \"./DebugSessionProxy\";\n\n/**\n * Decorates DebugSession instances and emits an event for new debug sessions.\n */\nexport class DebuggerProxy {\n\tpublic readonly dispose = Disposable.fn();\n\tprivate readonly sessions = new Map<DebugSession, DebugSessionProxy>();\n\n\tprivate readonly _onDidStartDebugSession = new EventEmitter<{\n\t\tsession: DebugSessionProxy;\n\t}>();\n\tpublic readonly onDidStartDebugSession =\n\t\tthis._onDidStartDebugSession.asEvent();\n\n\tpublic getDebugSessionProxy(session: DebugSession): DebugSessionProxy {\n\t\tlet result = this.sessions.get(session);\n\t\tif (!result) {\n\t\t\tresult = new DebugSessionProxy(session);\n\t\t\tthis.sessions.set(session, result);\n\t\t}\n\t\treturn result;\n\t}\n\n\tconstructor() {\n\t\tthis.dispose.track([\n\t\t\tdebug.onDidStartDebugSession((session) => {\n\t\t\t\tconst e = this.sessions.get(session)!;\n\t\t\t\tthis._onDidStartDebugSession.emit({ session: e });\n\t\t\t}),\n\t\t\tdebug.onDidTerminateDebugSession((session) => {\n\t\t\t\tthis.sessions.delete(session);\n\t\t\t}),\n\t\t\tdebug.registerDebugAdapterTrackerFactory(\"*\", {\n\t\t\t\tcreateDebugAdapterTracker: (session) => {\n\t\t\t\t\tconst extendedSession = this.getDebugSessionProxy(session);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tonDidSendMessage: async (msg) => {\n\t\t\t\t\t\t\ttype Message =\n\t\t\t\t\t\t\t\t| StoppedEvent\n\t\t\t\t\t\t\t\t| ThreadsResponse\n\t\t\t\t\t\t\t\t| ContinueLikeResponse;\n\n\t\t\t\t\t\t\tinterface ContinueLikeResponse {\n\t\t\t\t\t\t\t\ttype: \"response\";\n\t\t\t\t\t\t\t\tcommand:\n\t\t\t\t\t\t\t\t\t| \"continue\"\n\t\t\t\t\t\t\t\t\t| \"stepIn\"\n\t\t\t\t\t\t\t\t\t| \"stepOut\"\n\t\t\t\t\t\t\t\t\t| \"next\";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tinterface StoppedEvent {\n\t\t\t\t\t\t\t\ttype: \"event\";\n\t\t\t\t\t\t\t\tevent: \"stopped\";\n\t\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\t\tthreadId: number;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tinterface ThreadsResponse {\n\t\t\t\t\t\t\t\ttype: \"response\";\n\t\t\t\t\t\t\t\tcommand: \"threads\";\n\t\t\t\t\t\t\t\tsuccess: boolean;\n\t\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\t\tthreads: ThreadInfo[];\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tinterface ThreadInfo {\n\t\t\t\t\t\t\t\tid: number;\n\t\t\t\t\t\t\t\tname: string;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst m = msg as Message;\n\t\t\t\t\t\t\tif (m.type === \"event\") {\n\t\t\t\t\t\t\t\tif (m.event === \"stopped\") {\n\t\t\t\t\t\t\t\t\tconst threadId = m.body.threadId;\n\t\t\t\t\t\t\t\t\tconst r =\n\t\t\t\t\t\t\t\t\t\tawait extendedSession.getStackTrace({\n\t\t\t\t\t\t\t\t\t\t\tthreadId,\n\t\t\t\t\t\t\t\t\t\t\tstartFrame: 0,\n\t\t\t\t\t\t\t\t\t\t\tlevels: 1,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\textendedSession[\"_activeStackFrameId\"] =\n\t\t\t\t\t\t\t\t\t\tr.stackFrames.length > 0\n\t\t\t\t\t\t\t\t\t\t\t? r.stackFrames[0].id\n\t\t\t\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (m.type === \"response\") {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tm.command === \"continue\" ||\n\t\t\t\t\t\t\t\t\tm.command === \"next\" ||\n\t\t\t\t\t\t\t\t\tm.command === \"stepIn\" ||\n\t\t\t\t\t\t\t\t\tm.command === \"stepOut\"\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\textendedSession[\"_activeStackFrameId\"] =\n\t\t\t\t\t\t\t\t\t\tundefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t}),\n\t\t]);\n\t}\n}\n"
  },
  {
    "path": "extension/src/proxies/DebuggerViewProxy.ts",
    "content": "import { Disposable } from \"@hediet/std/disposable\";\nimport { CancellationToken, debug, DebugSession, InlineValue, InlineValueContext, InlineValuesProvider, languages, ProviderResult, Range, TextDocument } from \"vscode\";\nimport { observable, action } from \"mobx\";\nimport { DebuggerProxy } from \"./DebuggerProxy\";\nimport { DebugSessionProxy } from \"./DebugSessionProxy\";\n\n/**\n * Tracks the currently active debug session and its currently active stack frame.\n * This is currently all faked. A proper API would be nice.\n */\nexport class DebuggerViewProxy {\n\tpublic readonly dispose = Disposable.fn();\n\n\t@observable private _activeDebugSession: DebugSessionProxy | undefined;\n\n\tpublic get activeDebugSession(): DebugSessionProxy | undefined {\n\t\treturn this._activeDebugSession;\n\t}\n\n\tpublic getActiveStackFrameId(\n\t\tsession: DebugSessionProxy\n\t): number | undefined {\n\t\treturn session[\"_activeStackFrameId\"];\n\t}\n\n\tconstructor(private debuggerProxy: DebuggerProxy) {\n\t\tthis.dispose.track(\n\t\t\tdebug.onDidChangeActiveDebugSession(activeSession => {\n\t\t\t\tthis.updateActiveDebugSession(activeSession);\n\t\t\t})\n\t\t);\n\t\tthis.updateActiveDebugSession(debug.activeDebugSession);\n\n\t\tthis.dispose.track(languages.registerInlineValuesProvider('*', new FrameIdGetter(this)));\n\t}\n\n\t@action\n\tprivate updateActiveDebugSession(activeSession: DebugSession | undefined) {\n\t\tthis._activeDebugSession = activeSession\n\t\t\t? this.debuggerProxy.getDebugSessionProxy(activeSession)\n\t\t\t: undefined;\n\t}\n}\n\nexport class FrameIdGetter implements InlineValuesProvider {\n\tconstructor(\n\t\tprivate readonly debuggerViewProxy: DebuggerViewProxy,\n\t) {\n\t}\n\n\tprovideInlineValues(document: TextDocument, viewPort: Range, context: InlineValueContext, token: CancellationToken): ProviderResult<InlineValue[]> {\n\t\tconst a = this.debuggerViewProxy.activeDebugSession;\n\t\tif (a) {\n\t\t\ta['_activeStackFrameId'] = context.frameId;\n\t\t}\n\t\treturn []\n\t}\n}\n"
  },
  {
    "path": "extension/src/types.d.ts",
    "content": "declare namespace NodeJS {\n\tdeclare interface ProcessEnv {\n\t\tHOT_RELOAD?: \"true\";\n\t\tUSE_DEV_UI?: \"true\";\n\t}\n}\n\ndeclare module \"debug-visualizer-webview\" {\n\texport const distPath: string;\n}\n"
  },
  {
    "path": "extension/src/utils/DebouncedRunner.ts",
    "content": "export class DebouncedRunner {\r\n\tprivate timeout: NodeJS.Timeout | undefined;\r\n\r\n\tconstructor(private readonly debounceTimeout: number) {}\r\n\r\n\tpublic run(action: () => void): void {\r\n\t\tthis.clear();\r\n\t\tthis.timeout = setTimeout(action, this.debounceTimeout);\r\n\t}\r\n\r\n\tprivate clear() {\r\n\t\tif (this.timeout) {\r\n\t\t\tclearTimeout(this.timeout);\r\n\t\t\tthis.timeout = undefined;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic dispose(): void {\r\n\t\tthis.clear();\r\n\t}\r\n}\r\n"
  },
  {
    "path": "extension/src/utils/IncrementalMap.ts",
    "content": "import { Disposable } from \"@hediet/std/disposable\";\r\nimport { observable, autorun } from \"mobx\";\r\n\r\nexport class IncrementalMap<TKey, TValue extends Disposable> {\r\n\tpublic readonly map: Map<TKey, TValue> = new Map();\r\n\r\n\tconstructor(\r\n\t\tprivate readonly getKeys: () => TKey[],\r\n\t\tprivate readonly getValue: (key: TKey) => TValue\r\n\t) {\r\n\t\tthis.dispose.track({\r\n\t\t\tdispose: autorun(() => {\r\n\t\t\t\tconst keys = this.getKeys();\r\n\t\t\t\tconst toRemove = new Set(this.map.keys());\r\n\t\t\t\tfor (const key of keys) {\r\n\t\t\t\t\ttoRemove.delete(key);\r\n\t\t\t\t\tif (!this.map.has(key)) {\r\n\t\t\t\t\t\tthis.map.set(key, this.getValue(key));\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tfor (const key of toRemove) {\r\n\t\t\t\t\tthis.map.get(key)!.dispose();\r\n\t\t\t\t\tthis.map.delete(key);\r\n\t\t\t\t}\r\n\t\t\t}),\r\n\t\t});\r\n\t}\r\n\r\n\tpublic readonly dispose = Disposable.fn();\r\n}\r\n"
  },
  {
    "path": "extension/src/utils/VsCodeSettings.ts",
    "content": "import { Uri, workspace, ConfigurationTarget, Disposable } from \"vscode\";\nimport { fromResource } from \"mobx-utils\";\nimport { computed, runInAction } from \"mobx\";\nimport { EventEmitter } from \"@hediet/std/events\";\n\nexport interface Serializer<T> {\n\tdeserialize: (val: any) => T;\n\tserializer: (val: T) => any;\n}\n\nexport function serializerWithDefault<T>(defaultValue: T): Serializer<T> {\n\treturn {\n\t\tdeserialize: val => (val === undefined ? defaultValue : val),\n\t\tserializer: val => val,\n\t};\n}\n\nexport class VsCodeSetting<T> {\n\tpublic get T(): T {\n\t\tthrow new Error();\n\t}\n\n\tpublic readonly serializer: Serializer<T>;\n\tpublic readonly scope: Uri | undefined;\n\tprivate readonly settingResource: VsCodeSettingResource;\n\n\tpublic constructor(\n\t\tpublic readonly id: string,\n\t\toptions: {\n\t\t\tserializer?: Serializer<T>;\n\t\t\tscope?: Uri;\n\t\t} = {}\n\t) {\n\t\tthis.scope = options.scope;\n\t\tthis.serializer = options.serializer || {\n\t\t\tdeserialize: val => val,\n\t\t\tserializer: val => val,\n\t\t};\n\t\tthis.settingResource = new VsCodeSettingResource(this.id, this.scope);\n\t}\n\n\tpublic get(): T {\n\t\tconst result = this.settingResource.value;\n\t\treturn this.serializer.deserialize(result);\n\t}\n\n\tpublic async set(value: T): Promise<void> {\n\t\tconst value2 = this.serializer.serializer(value);\n\t\tconst c = workspace.getConfiguration(undefined, this.scope);\n\t\tconst result = c.inspect(this.id);\n\t\tlet target: ConfigurationTarget;\n\n\t\tif (\n\t\t\tresult &&\n\t\t\t[result.workspaceFolderValue].some(i => i !== undefined)\n\t\t) {\n\t\t\ttarget = ConfigurationTarget.WorkspaceFolder;\n\t\t}\n\t\tif (result && [result.workspaceValue].some(i => i !== undefined)) {\n\t\t\ttarget = ConfigurationTarget.Workspace;\n\t\t} else {\n\t\t\ttarget = ConfigurationTarget.Global;\n\t\t}\n\n\t\tawait c.update(this.id, value2, target);\n\t}\n}\n\nclass VsCodeSettingResource {\n\tpublic static onConfigChange = new EventEmitter();\n\n\tprivate subscription: Disposable | undefined;\n\tprivate readonly resource = fromResource<any>(\n\t\tupdate => {\n\t\t\tupdate(this.readValue());\n\t\t\tthis.subscription = VsCodeSettingResource.onConfigChange.sub(() => {\n\t\t\t\tupdate(this.readValue());\n\t\t\t});\n\t\t},\n\t\t() => this.subscription!.dispose(),\n\t\tthis.readValue()\n\t);\n\n\tconstructor(\n\t\tprivate readonly id: string,\n\t\tprivate readonly scope: Uri | undefined\n\t) {}\n\n\tprivate readValue(): any {\n\t\tconst val = workspace\n\t\t\t.getConfiguration(undefined, this.scope)\n\t\t\t.get(this.id);\n\t\treturn val;\n\t}\n\n\t/**\n\t * This improves change detection.\n\t */\n\tprivate readonly stringifiedSettingValue = computed(\n\t\t() => JSON.stringify(this.resource.current()),\n\t\t{\n\t\t\tname: `VsCodeSettingResource[${this.id}].value`,\n\t\t\tcontext: this,\n\t\t}\n\t);\n\n\tpublic get value() {\n\t\tconst v = this.stringifiedSettingValue.get();\n\t\tif (v === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn JSON.parse(v);\n\t}\n}\n\nworkspace.onDidChangeConfiguration(() => {\n\trunInAction(\"Update Configuration\", () => {\n\t\tVsCodeSettingResource.onConfigChange.emit();\n\t});\n});\n"
  },
  {
    "path": "extension/src/webview/InternalWebviewManager.ts",
    "content": "import { window, ViewColumn, WebviewPanel } from \"vscode\";\nimport { WebviewServer } from \"./WebviewServer\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { WindowWithWebviewData } from \"../webviewContract\";\nimport { Config } from \"../Config\";\n\nexport const debugVisualizer = \"debugVisualizer\";\n\nexport class InternalWebviewManager {\n\tprivate readonly openedWebviews = new Map<\n\t\tWebviewPanel,\n\t\tDebugVisualizerWebview\n\t>();\n\n\tpublic readonly dispose = Disposable.fn();\n\n\tconstructor(\n\t\tprivate readonly server: WebviewServer,\n\t\tprivate readonly config: Config\n\t) {\n\t\tthis.dispose.track(\n\t\t\twindow.registerWebviewPanelSerializer(debugVisualizer, {\n\t\t\t\tdeserializeWebviewPanel: async (panel, state) => {\n\t\t\t\t\tthis.restore(panel);\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\n\t\tthis.dispose.track({\n\t\t\tdispose: () => {\n\t\t\t\tfor (const panel of this.openedWebviews.keys()) {\n\t\t\t\t\tpanel.dispose();\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t}\n\n\tpublic createNew(expression: string | undefined = undefined) {\n\t\tconst webviewPanel = window.createWebviewPanel(\n\t\t\tdebugVisualizer,\n\t\t\t\"Debug Visualizer\",\n\t\t\tViewColumn.Two,\n\t\t\t{\n\t\t\t\tenableScripts: true,\n\t\t\t\tretainContextWhenHidden: true,\n\t\t\t\tportMapping: [\n\t\t\t\t\t{\n\t\t\t\t\t\twebviewPort: this.server.port,\n\t\t\t\t\t\textensionHostPort: this.server.port,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}\n\t\t);\n\n\t\tthis.initializeView(webviewPanel, expression);\n\t}\n\n\tprivate restore(webviewPanel: WebviewPanel) {\n\t\tthis.initializeView(webviewPanel);\n\t}\n\n\tprivate initializeView(\n\t\twebviewPanel: WebviewPanel,\n\t\texpression: string | undefined = undefined\n\t) {\n\t\twebviewPanel.webview.html = getDebugVisualizerWebviewHtml(\n\t\t\tthis.server,\n\t\t\texpression,\n\t\t\tthis.config\n\t\t);\n\t\tconst view = new DebugVisualizerWebview(webviewPanel);\n\t\tthis.openedWebviews.set(webviewPanel, view);\n\t\twebviewPanel.onDidDispose(() => {\n\t\t\tthis.openedWebviews.delete(webviewPanel);\n\t\t});\n\t}\n}\n\nexport class DebugVisualizerWebview {\n\tconstructor(private readonly webviewPanel: WebviewPanel) {}\n}\n\nfunction getDebugVisualizerWebviewHtml(\n\tserver: WebviewServer,\n\tinitialExpression: string | undefined = undefined,\n\tconfig: Config\n) {\n\tconst isDev = !!process.env.USE_DEV_UI;\n\treturn `\n        <html>\n\t\t\t<head>\n\t\t\t<meta charset=\"UTF-8\">\n\t\t\t<meta http-equiv=\"Content-Security-Policy\" content=\"default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src *; style-src * 'unsafe-inline'; worker-src * data: blob: data: 'unsafe-inline' 'unsafe-eval'; font-src * 'unsafe-inline' 'unsafe-eval' 'self' data: blob:;\">\n            <style>\n                html { height: 100%; width: 100%; padding: 0; margin: 0; }\n                body { height: 100%; width: 100%; padding: 0; margin: 0; }\n\t\t\t\tiframe { height: 100%; width: 100%; padding: 0; margin: 0; border: 0; display: block; }\n            </style>\n            </head>\n\t\t\t<body>\n\t\t\t\t<script>\n\t\t\t\t\tObject.assign(window, ${JSON.stringify({\n\t\t\t\t\t\twebviewData: {\n\t\t\t\t\t\t\tserverSecret: server.secret,\n\t\t\t\t\t\t\tserverPort: server.port,\n\t\t\t\t\t\t\tpublicPath: server.publicPath,\n\t\t\t\t\t\t\texpression: initialExpression,\n\t\t\t\t\t\t\ttheme: config.theme,\n\t\t\t\t\t\t},\n\t\t\t\t\t} as WindowWithWebviewData)});\n\t\t\t\t\tconst api = window.VsCodeApi = acquireVsCodeApi();\n\t\t\t\t\twindow.addEventListener('message', event => {\n\t\t\t\t\t\tif (event.source === window.frames[0]) {\n\t\t\t\t\t\t\tif (event.data.command === \"setState\") {\n\t\t\t\t\t\t\t\t// console.log(\"setState\", event.data.state);\n\t\t\t\t\t\t\t\tapi.setState(event.data.state);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.data.command === \"getState\") {\n\t\t\t\t\t\t\t\t// console.log(\"getState, sent \", api.getState());\n\t\t\t\t\t\t\t\twindow.frames[0].postMessage({ command: \"getStateResult\", state: api.getState() }, \"*\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t</script>\n\t\t\t\t\n\t\t\t\t${\n\t\t\t\t\tisDev\n\t\t\t\t\t\t? `<iframe sandbox=\"allow-top-navigation allow-scripts allow-same-origin allow-popups allow-pointer-lock allow-forms\" src=\"${server.getWebviewPageUrl(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmode: \"webviewIFrame\",\n\t\t\t\t\t\t\t\t\texpression: initialExpression,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t  )}\"></iframe>`\n\t\t\t\t\t\t: `<script type=\"text/javascript\" src=\"${server.webviewBundleUrl}\"></script>`\n\t\t\t\t}\n            </body>\n        </html>\n    `;\n}\n"
  },
  {
    "path": "extension/src/webview/WebviewConnection.ts",
    "content": "import { Disposable } from \"@hediet/std/disposable\";\nimport { ConsoleRpcLogger, RequestHandlingError } from \"@hediet/typed-json-rpc\";\nimport { WebSocketStream } from \"@hediet/typed-json-rpc-websocket\";\nimport { existsSync, readFileSync, watch } from \"fs\";\nimport { autorun, observable } from \"mobx\";\nimport * as open from \"open\";\nimport { window } from \"vscode\";\nimport { Config } from \"../Config\";\nimport { VisualizationWatch, VisualizationWatchModel } from \"../VisualizationWatchModel\";\nimport { DebouncedRunner } from \"../utils/DebouncedRunner\";\nimport { IncrementalMap } from \"../utils/IncrementalMap\";\nimport { webviewContract } from \"../webviewContract\";\nimport { WebviewServer } from \"./WebviewServer\";\nimport chromeLauncher = require(\"chrome-launcher\");\n\nexport class WebviewConnection {\n\tpublic readonly dispose = Disposable.fn();\n\n\t@observable\n\tprivate watcher: VisualizationWatch | undefined = undefined;\n\n\tprivate readonly client: (typeof webviewContract)[\"TClientInterface\"];\n\n\tconstructor(\n\t\tevaluationWatchService: VisualizationWatchModel,\n\t\tstream: WebSocketStream,\n\t\tserver: WebviewServer,\n\t\tconfig: Config,\n\t\tserverSecret: string\n\t) {\n\t\tlet authenticated = false;\n\n\t\tfunction throwIfNotAuthenticated() {\n\t\t\tif (!authenticated) {\n\t\t\t\tthrow new RequestHandlingError(\"Not authenticated\");\n\t\t\t}\n\t\t}\n\n\t\tconst { client, channel } = webviewContract.registerServerToStream(stream, new ConsoleRpcLogger(), {\n\t\t\tauthenticate: async ({ secret }, { newErr }) => {\n\t\t\t\tif (secret !== serverSecret) {\n\t\t\t\t\treturn newErr({ errorMessage: \"Invalid Secret\" });\n\t\t\t\t} else {\n\t\t\t\t\tauthenticated = true;\n\t\t\t\t}\n\t\t\t},\n\t\t\trefresh: async () => {\n\t\t\t\tthrowIfNotAuthenticated();\n\n\t\t\t\tif (this.watcher) {\n\t\t\t\t\tthis.watcher.refresh();\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetExpression: async ({ newExpression }) => {\n\t\t\t\tthrowIfNotAuthenticated();\n\n\t\t\t\tif (this.watcher?.expression === newExpression) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet oldPreferredDataExtractor: VisualizationWatch[\"preferredDataExtractor\"];\n\t\t\t\tlet oldSessionState: unknown;\n\t\t\t\tif (this.watcher) {\n\t\t\t\t\toldPreferredDataExtractor = this.watcher.preferredDataExtractor;\n\t\t\t\t\toldSessionState = this.watcher.sessionState;\n\t\t\t\t\tthis.dispose.untrack(this.watcher).dispose();\n\t\t\t\t}\n\t\t\t\tthis.watcher = this.dispose.track(\n\t\t\t\t\tevaluationWatchService.createWatch(newExpression, {\n\t\t\t\t\t\tpreferredDataExtractor: oldPreferredDataExtractor,\n\t\t\t\t\t\tsessionState: oldSessionState,\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t},\n\t\t\topenInBrowser: async ({}) => {\n\t\t\t\tthrowIfNotAuthenticated();\n\n\t\t\t\tconst url = server.getWebviewPageUrl({\n\t\t\t\t\tmode: \"standalone\",\n\t\t\t\t\texpression: this.watcher ? this.watcher.expression : undefined,\n\t\t\t\t});\n\n\t\t\t\tlet opened = false;\n\t\t\t\tif (config.useChromeKioskMode) {\n\t\t\t\t\topened = await launchChrome(url);\n\t\t\t\t}\n\t\t\t\tif (!opened) {\n\t\t\t\t\topen(url);\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetPreferredDataExtractor: async ({ dataExtractorId }) => {\n\t\t\t\tthrowIfNotAuthenticated();\n\n\t\t\t\tif (this.watcher) {\n\t\t\t\t\tthis.watcher.setPreferredDataExtractor(dataExtractorId);\n\t\t\t\t}\n\t\t\t},\n\t\t\tgetCompletions: async ({ text, column }) => {\n\t\t\t\tthrowIfNotAuthenticated();\n\n\t\t\t\tconst completions = await evaluationWatchService.getCompletions(text, column);\n\t\t\t\treturn {\n\t\t\t\t\tcompletions,\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\n\t\tthis.client = client;\n\n\t\tthis.dispose.track(\n\t\t\tnew FileWatcher(\n\t\t\t\t() => config.customVisualizerScriptPaths,\n\t\t\t\tasync (files) => {\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tif (!file.fileExists) {\n\t\t\t\t\t\t\twindow.showErrorMessage(`The file ${file.path} does not exist.`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait client.setCustomVisualizerScript({\n\t\t\t\t\t\t\t\tid: file.path,\n\t\t\t\t\t\t\t\tjsSource: file.content || null,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\twindow.showErrorMessage(\n\t\t\t\t\t\t\t\t'Error while running custom visualization extractor script \"' +\n\t\t\t\t\t\t\t\t\tfile.path +\n\t\t\t\t\t\t\t\t\t'\": ' +\n\t\t\t\t\t\t\t\t\te.message\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\n\t\tthis.dispose.track([\n\t\t\tDisposable.create(\n\t\t\t\tautorun(() => {\n\t\t\t\t\tif (this.watcher) {\n\t\t\t\t\t\tclient.updateState({\n\t\t\t\t\t\t\tnewState: this.watcher.state,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t),\n\t\t\tDisposable.create(\n\t\t\t\tautorun(() => {\n\t\t\t\t\tclient.updateLanguageId({\n\t\t\t\t\t\tlanguageId: evaluationWatchService.languageId || null,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t),\n\t\t]);\n\n\t\tstream.onClosed.then(() => {\n\t\t\tthis.dispose();\n\t\t});\n\t}\n\n\tpublic setExpression(expression: string) {\n\t\tthis.client.setExpression({ expression });\n\t}\n\n\tpublic setTheme(theme: \"light\" | \"dark\"): void {\n\t\tthis.client.setTheme({ theme });\n\t}\n}\n\nasync function launchChrome(url: string): Promise<boolean> {\n\ttry {\n\t\tconst _chrome = await chromeLauncher.launch({\n\t\t\tstartingUrl: url,\n\t\t\t// `--window-size=${width},${height}`\n\t\t\tchromeFlags: [\"--app=\" + url],\n\t\t});\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}\n\nexport class FileWatcher {\n\tpublic readonly dispose = Disposable.fn();\n\n\tconstructor(\n\t\tgetFilePaths: () => string[],\n\t\thandleFileContents: (\n\t\t\tfiles: {\n\t\t\t\tpath: string;\n\t\t\t\tfileExists: boolean;\n\t\t\t\tcontent: string | undefined;\n\t\t\t}[]\n\t\t) => void\n\t) {\n\t\tconst scheduleRefresh = new Set<SingleFileWatcher>();\n\t\tconst debouncer = new DebouncedRunner(200);\n\n\t\tconst map = this.dispose.track(\n\t\t\tnew IncrementalMap(\n\t\t\t\tgetFilePaths,\n\t\t\t\t(path) =>\n\t\t\t\t\tnew SingleFileWatcher(path, (w) => {\n\t\t\t\t\t\tscheduleRefresh.add(w);\n\t\t\t\t\t\tdebouncer.run(() => {\n\t\t\t\t\t\t\tconst changedWatchers = [...scheduleRefresh].filter((w) => w.refresh());\n\t\t\t\t\t\t\thandleFileContents(\n\t\t\t\t\t\t\t\tchangedWatchers.map((w) => ({\n\t\t\t\t\t\t\t\t\tpath: w.path,\n\t\t\t\t\t\t\t\t\tcontent: w.content,\n\t\t\t\t\t\t\t\t\tfileExists: w.exists,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t)\n\t\t);\n\n\t\thandleFileContents(\n\t\t\t[...map.map].map(([path, o]) => {\n\t\t\t\treturn {\n\t\t\t\t\tpath,\n\t\t\t\t\tcontent: o.content,\n\t\t\t\t\tfileExists: o.exists,\n\t\t\t\t};\n\t\t\t})\n\t\t);\n\t}\n}\n\nclass SingleFileWatcher {\n\tprivate readonly watcher = watch(this.path, { encoding: \"utf-8\" }, () => this.scheduleRefresh(this));\n\tprivate isDisposed = false;\n\tpublic content: string | undefined;\n\tpublic exists: boolean = true;\n\n\tconstructor(public readonly path: string, private readonly scheduleRefresh: (self: SingleFileWatcher) => void) {\n\t\tthis.refresh();\n\t}\n\n\tpublic dispose() {\n\t\tthis.isDisposed = true;\n\t\tthis.content = undefined;\n\t\tthis.scheduleRefresh(this);\n\t\tthis.watcher.close();\n\t}\n\n\tpublic refresh() {\n\t\tif (this.isDisposed) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (!existsSync(this.path)) {\n\t\t\tthis.exists = false;\n\t\t\tthis.content = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tconst newContent = readFileSync(this.path, \"utf-8\");\n\t\tif (newContent !== this.content) {\n\t\t\tthis.content = newContent;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n}\n"
  },
  {
    "path": "extension/src/webview/WebviewServer.ts",
    "content": "import { WebSocketStream } from \"@hediet/typed-json-rpc-websocket\";\nimport { AddressInfo } from \"net\";\nimport WebSocket = require(\"ws\");\nimport { WebviewConnection } from \"./WebviewConnection\";\nimport * as express from \"express\";\nimport * as http from \"http\";\nimport * as serveStatic from \"serve-static\";\nimport { Config } from \"../Config\";\nimport cryptoRandomString = require(\"crypto-random-string\");\nimport { distPath } from \"debug-visualizer-webview\";\nimport { VisualizationWatchModel } from \"../VisualizationWatchModel/VisualizationWatchModel\";\nimport { URLSearchParams } from \"url\";\nimport { autorun, reaction } from \"mobx\";\n\nexport class WebviewServer {\n\tprivate readonly server: http.Server;\n\tpublic readonly secret = cryptoRandomString({ length: 30 });\n\n\tpublic readonly connections = new Set<WebviewConnection>();\n\n\tconstructor(\n\t\tdataSource: VisualizationWatchModel,\n\t\tprivate readonly config: Config\n\t) {\n\t\tconst app = express();\n\n\t\tapp.use(serveStatic(distPath));\n\n\t\tthis.server = app.listen();\n\n\t\t/*\n\t\tconsole.log(\n\t\t\t`Serving \"${distPath}\" on port ${\n\t\t\t\t(this.server.address() as AddressInfo).port\n\t\t\t}`\n\t\t);\n\t\t*/\n\n\t\tconst wss = new WebSocket.Server({ server: this.server });\n\t\twss.on(\"connection\", async ws => {\n\t\t\tconst stream = new WebSocketStream(ws);\n\t\t\tconst c = new WebviewConnection(\n\t\t\t\tdataSource,\n\t\t\t\tstream,\n\t\t\t\tthis,\n\t\t\t\tconfig,\n\t\t\t\tthis.secret\n\t\t\t);\n\t\t\tthis.connections.add(c);\n\t\t\tawait stream.onClosed;\n\t\t\tthis.connections.delete(c);\n\t\t});\n\n\t\treaction(\n\t\t\t() => config.theme,\n\t\t\ttheme => {\n\t\t\t\tfor (const c of this.connections) {\n\t\t\t\t\tc.setTheme(theme);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\tpublic getWebviewPageUrl(args: {\n\t\texpression?: string;\n\t\tmode: \"standalone\" | \"webviewIFrame\";\n\t}): string {\n\t\tconst port = process.env.USE_DEV_UI ? 8080 : this.port;\n\t\tconst params: Record<string, string> = {\n\t\t\tserverPort: this.port.toString(),\n\t\t\tserverSecret: this.secret,\n\t\t\tmode: args.mode,\n\t\t\ttheme: this.config.theme,\n\t\t};\n\t\tif (args.expression !== undefined) {\n\t\t\tparams.expression = args.expression;\n\t\t}\n\n\t\treturn `http://localhost:${port}/index.html?${new URLSearchParams(\n\t\t\tparams\n\t\t).toString()}`;\n\t}\n\n\tpublic get publicPath(): string {\n\t\treturn `http://localhost:${this.port}/`;\n\t}\n\n\tpublic get webviewBundleUrl(): string {\n\t\treturn `${this.publicPath}main.js`;\n\t}\n\n\tpublic get port(): number {\n\t\tconst httpPort = (this.server.address() as AddressInfo).port;\n\t\treturn httpPort;\n\t}\n}\n"
  },
  {
    "path": "extension/src/webviewContract.ts",
    "content": "import {\n\tcontract,\n\tnotificationContract,\n\ttypes,\n\trequestContract,\n} from \"@hediet/typed-json-rpc\";\nimport {\n\tDataExtractionResult,\n\tDataExtractorId,\n} from \"@hediet/debug-visualizer-data-extraction\";\n\ninterface WebviewConfig {\n\tserverSecret: string;\n\tserverPort: number;\n\tpublicPath: string;\n\texpression?: string;\n\ttheme: \"light\" | \"dark\";\n}\n\nexport interface WebviewUrlParams {\n\tserverPort: string;\n\tserverSecret: string;\n\tmode: \"standalone\" | \"webviewIFrame\";\n\texpression: string;\n\ttheme: \"light\" | \"dark\";\n}\n\nexport interface WindowWithWebviewData {\n\twebviewData?: WebviewConfig;\n}\n\nexport const webviewContract = contract({\n\tclient: {\n\t\tupdateState: notificationContract({\n\t\t\tparams: types.type({\n\t\t\t\tnewState: unchecked<DataExtractionState>(),\n\t\t\t}),\n\t\t}),\n\t\tupdateLanguageId: notificationContract({\n\t\t\tparams: types.type({\n\t\t\t\tlanguageId: types.union([types.null, types.string]),\n\t\t\t}),\n\t\t}),\n\t\tsetExpression: requestContract({\n\t\t\tparams: types.type({\n\t\t\t\texpression: types.string,\n\t\t\t}),\n\t\t}),\n\t\tsetTheme: notificationContract({\n\t\t\tparams: types.type({\n\t\t\t\ttheme: types.union([\n\t\t\t\t\ttypes.literal(\"light\"),\n\t\t\t\t\ttypes.literal(\"dark\"),\n\t\t\t\t]),\n\t\t\t}),\n\t\t}),\n\n\t\tsetCustomVisualizerScript: notificationContract({\n\t\t\tparams: types.type({\n\t\t\t\tid: types.string,\n\t\t\t\tjsSource: types.union([types.string, types.null]),\n\t\t\t}),\n\t\t}),\n\t},\n\tserver: {\n\t\tauthenticate: requestContract({\n\t\t\tparams: types.type({\n\t\t\t\tsecret: types.string,\n\t\t\t}),\n\t\t}),\n\t\tsetPreferredDataExtractor: notificationContract({\n\t\t\tparams: types.type({\n\t\t\t\tdataExtractorId: unchecked<DataExtractorId>(),\n\t\t\t}),\n\t\t}),\n\t\tsetExpression: notificationContract({\n\t\t\tparams: types.type({\n\t\t\t\tnewExpression: types.string,\n\t\t\t}),\n\t\t}),\n\t\trefresh: notificationContract({}),\n\t\topenInBrowser: notificationContract({}),\n\n\t\tgetCompletions: requestContract({\n\t\t\tparams: types.type({\n\t\t\t\ttext: types.string,\n\t\t\t\tcolumn: types.number,\n\t\t\t}),\n\t\t\tresult: types.type({\n\t\t\t\tcompletions: types.array(unchecked<CompletionItem>()),\n\t\t\t}),\n\t\t}),\n\t},\n});\n\nfunction unchecked<T>(): types.Type<T, any, unknown> {\n\treturn new types.Type<T, T, unknown>(\n\t\t\"unchecked\",\n\t\t(u): u is T => true,\n\t\t(value) => types.success(value as T),\n\t\t(value) => value\n\t);\n}\n\nexport type FormattedMessage =\n\t| string\n\t| {\n\t\t\tkind: \"list\";\n\t\t\titems: FormattedMessage[];\n\t  }\n\t| {\n\t\t\tkind: \"inlineList\";\n\t\t\titems: FormattedMessage[];\n\t  }\n\t| {\n\t\t\tkind: \"code\";\n\t\t\tcontent: string;\n\t  };\n\nexport type DataExtractionState =\n\t| { kind: \"loading\" }\n\t| { kind: \"error\"; message: FormattedMessage }\n\t| { kind: \"noDebugSession\" }\n\t| {\n\t\t\tkind: \"data\";\n\t\t\tresult: DataExtractionResult;\n\t  };\n\n// https://microsoft.github.io/debug-adapter-protocol/specification#CompletionItem\ntype CompletionItemType =\n\t| \"method\"\n\t| \"function\"\n\t| \"constructor\"\n\t| \"field\"\n\t| \"variable\"\n\t| \"class\"\n\t| \"interface\"\n\t| \"module\"\n\t| \"property\"\n\t| \"unit\"\n\t| \"value\"\n\t| \"enum\"\n\t| \"keyword\"\n\t| \"snippet\"\n\t| \"text\"\n\t| \"color\"\n\t| \"file\"\n\t| \"reference\"\n\t| \"customcolor\";\n\nexport interface CompletionItem {\n\t/**\n\t * The label of this completion item. By default this is also the text that is inserted when selecting this completion.\n\t */\n\tlabel: string;\n\n\t/**\n\t * If text is not falsy then it is inserted instead of the label.\n\t */\n\ttext?: string;\n\n\t/**\n\t * The item's type. Typically the client uses this information to render the item in the UI with an icon.\n\t */\n\ttype?: CompletionItemType;\n\n\t/**\n\t * This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is added.\n\t * If missing the text is added at the location specified by the CompletionsRequest's 'column' attribute.\n\t */\n\tstart?: number;\n\n\t/**\n\t * This value determines how many characters are overwritten by the completion text.\n\t * If missing the value 0 is assumed which results in the completion text being inserted.\n\t */\n\tlength?: number;\n}\n"
  },
  {
    "path": "extension/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"ES2017\",\n\t\t\"outDir\": \"dist\",\n\t\t\"lib\": [\"ES2017\"],\n\t\t\"sourceMap\": true,\n\t\t\"rootDir\": \"src\",\n\t\t\"strict\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"experimentalDecorators\": true\n\t},\n\t\"include\": [\"src/**/*\", \"../js-data-extractors/src/Extractors/TypeScriptDataExtractors.ts\"]\n}\n"
  },
  {
    "path": "extension/webpack.config.ts",
    "content": "import { CleanWebpackPlugin } from \"clean-webpack-plugin\";\nimport * as CopyPlugin from \"copy-webpack-plugin\";\nimport { readFileSync } from \"fs\";\nimport * as path from \"path\";\nimport * as webpack from \"webpack\";\n\nconst r = (file: string) => path.resolve(__dirname, file);\n\nmodule.exports = {\n\ttarget: \"node\",\n\tentry: r(\"./src/extension\"),\n\toutput: {\n\t\tpath: r(\"./dist\"),\n\t\tfilename: \"extension.js\",\n\t\tlibraryTarget: \"commonjs2\",\n\t\tdevtoolModuleFilenameTemplate: \"../[resource-path]\",\n\t},\n\tdevtool: \"source-map\",\n\texternals: {\n\t\tvscode: \"commonjs vscode\",\n\t\t\"@hediet/debug-visualizer-data-extraction\":\n\t\t\t\"@hediet/debug-visualizer-data-extraction\",\n\t\t\"debug-visualizer-webview\": \"debug-visualizer-webview\",\n\t\tfsevents: \"require('fsevents')\",\n\t},\n\tresolve: {\n\t\textensions: [\".ts\", \".js\"],\n\t},\n\tmodule: {\n\t\trules: [\n\t\t\t{\n\t\t\t\ttest: /\\.ts$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\tuse: [\n\t\t\t\t\t{\n\t\t\t\t\t\tloader: \"ts-loader\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n\tnode: {\n\t\t__dirname: false,\n\t},\n\tplugins: [\n\t\tnew CleanWebpackPlugin(),\n\t\tincludeDependency(r(\"../data-extraction/\")),\n\t\tincludeDependency(r(\"../webview/\")),\n\t],\n} as webpack.Configuration;\n\nfunction includeDependency(location: string) {\n\tconst content = readFileSync(path.join(location, \"package.json\"), {\n\t\tencoding: \"utf8\",\n\t});\n\tconst pkgName = JSON.parse(content).name;\n\n\treturn new CopyPlugin({\n\t\tpatterns: [\n\t\t\t{\n\t\t\t\tfrom: location,\n\t\t\t\tto: r(`./dist/node_modules/${pkgName}`),\n\t\t\t\tglobOptions: {\n\t\t\t\t\tignore: [\"**/node_modules/**/*\"],\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"private\": true,\n\t\"workspaces\": [\n\t\t\"./data-extraction\",\n\t\t\"./extension\",\n\t\t\"./webview\"\n\t],\n\t\"scripts\": {\n\t\t\"build\": \"yarn build-data-extraction && yarn build-ui && yarn build-extension\",\n\t\t\"build-data-extraction\": \"yarn workspace @hediet/debug-visualizer-data-extraction build\",\n\t\t\"build-ui\": \"yarn workspace debug-visualizer-webview build\",\n\t\t\"build-extension\": \"yarn workspace debug-visualizer build\"\n\t},\n\t\"devDependencies\": {\n\t\t\"prettier\": \"^2.8.8\"\n\t}\n}\n"
  },
  {
    "path": "tslint.json",
    "content": "{\n\t\"extends\": \"recommended\",\n\t\"rules\": {\n\t\t\"await-promise\": true\n\t}\n}\n"
  },
  {
    "path": "webview/index.js",
    "content": "// This is the entry point when this package is used as library from the extension.\n// This package MUST NOT be bundled.\nconst path = require(\"path\");\n\nmodule.exports.distPath = path.join(__dirname, \"dist\");\n"
  },
  {
    "path": "webview/package.json",
    "content": "{\n\t\"name\": \"debug-visualizer-webview\",\n\t\"version\": \"0.0.1\",\n\t\"license\": \"GPL-3.0\",\n\t\"scripts\": {\n\t\t\"dev\": \"webpack-dev-server --hot\",\n\t\t\"build\": \"node --max_old_space_size=4096 ../node_modules/webpack/bin/webpack.js --mode development\"\n\t},\n\t\"main\": \"./index.js\",\n\t\"dependencies\": {\n\t\t\"@blueprintjs/core\": \"^3.23.1\",\n\t\t\"@hediet/std\": \"^0.6.0\",\n\t\t\"blueprintjs\": \"^0.0.8\",\n\t\t\"classnames\": \"^2.2.6\",\n\t\t\"mobx\": \"^5.15.4\",\n\t\t\"mobx-react\": \"^6.1.8\",\n\t\t\"monaco-editor\": \"^0.25.2\",\n\t\t\"popper.js\": \"^1.16.1\",\n\t\t\"react\": \"^16.12.0\",\n\t\t\"react-dom\": \"^16.12.0\",\n\t\t\"react-measure\": \"^2.3.0\",\n\t\t\"@hediet/debug-visualizer-data-extraction\": \"*\",\n\t\t\"@hediet/visualization-bundle\": \"^0.2.5\",\n\t\t\"@hediet/visualization-core\": \"^0.3.1\",\n\t\t\"@knuddels/mobx-logger\": \"^1.1.1\",\n\t\t\"less-loader\": \"^6.2.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@types/html-webpack-plugin\": \"^3.2.2\",\n\t\t\"@types/react-measure\": \"^2.0.6\",\n\t\t\"@types/classnames\": \"^2.2.9\",\n\t\t\"@types/react\": \"^16.9.22\",\n\t\t\"@types/react-dom\": \"^16.9.5\",\n\t\t\"clean-webpack-plugin\": \"^4.0.0\",\n\t\t\"css-loader\": \"^6.8.1\",\n\t\t\"file-loader\": \"^6.2.0\",\n\t\t\"fork-ts-checker-webpack-plugin\": \"^8.0.0\",\n\t\t\"html-webpack-plugin\": \"^5.5.3\",\n\t\t\"monaco-editor-webpack-plugin\": \"^4.0.0\",\n\t\t\"sass\": \"^1.25.0\",\n\t\t\"raw-loader\": \"^4.0.0\",\n\t\t\"sass-loader\": \"^8.0.2\",\n\t\t\"style-loader\": \"^1.1.3\",\n\t\t\"ts-loader\": \"^9.4.4\",\n\t\t\"ts-node\": \"^10.9.1\",\n\t\t\"typescript\": \"^5.1.6\",\n\t\t\"webpack\": \"^5.88.1\",\n\t\t\"webpack-cli\": \"^5.1.4\",\n\t\t\"webpack-dev-server\": \"^4.15.1\"\n\t}\n}\n"
  },
  {
    "path": "webview/src/components/App.tsx",
    "content": "import * as React from \"react\";\nimport { hotComponent } from \"../hotComponent\";\nimport { GUI } from \"./GUI\";\nimport { Model } from \"../model/Model\";\n\n@hotComponent(module)\nexport class App extends React.Component {\n\tprivate readonly model = new Model();\n\n\tconstructor(props: any) {\n\t\tsuper(props);\n\n\t\tif (this.model.runningMode !== \"webview\") {\n\t\t\tif (this.model.theme === \"light\") {\n\t\t\t\trequire(\"../vscode-light.scss\");\n\t\t\t} else {\n\t\t\t\trequire(\"../vscode-dark.scss\");\n\t\t\t}\n\t\t}\n\t}\n\n\trender() {\n\t\treturn <GUI model={this.model} />;\n\t}\n}\n"
  },
  {
    "path": "webview/src/components/ExpressionInput.tsx",
    "content": "import * as React from \"react\";\nimport { Model } from \"../model/Model\";\nimport { observer, disposeOnUnmount } from \"mobx-react\";\nimport { observable, action, autorun } from \"mobx\";\nimport * as monaco from \"monaco-editor\";\n\n@observer\nexport class ExpressionInput extends React.Component<{ model: Model }> {\n\t@observable private editor: monaco.editor.IStandaloneCodeEditor | undefined;\n\t@observable private contentHeight: number | undefined = undefined;\n\n\tprivate _model: monaco.editor.ITextModel | undefined = undefined;\n\tprivate get model() {\n\t\tif (!this._model) {\n\t\t\tthis._model = monaco.editor.createModel(\n\t\t\t\t\"\",\n\t\t\t\t\"javascript\",\n\t\t\t\tmonaco.Uri.parse(`file:///main.ts`)\n\t\t\t);\n\t\t}\n\t\treturn this._model;\n\t}\n\n\trender() {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName=\"component-monaco-editor\"\n\t\t\t\tstyle={{\n\t\t\t\t\t// The monaco editor does not have a padding, so we add our own.\n\t\t\t\t\t// We have to match the colors of monaco's background.\n\t\t\t\t\tbackgroundColor:\n\t\t\t\t\t\tthis.props.model.theme === \"light\"\n\t\t\t\t\t\t\t? \"white\"\n\t\t\t\t\t\t\t: \"#263238\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"part-editor\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\theight: this.contentHeight,\n\t\t\t\t\t}}\n\t\t\t\t\tref={this.setEditorDiv}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tcomponentWillUnmount() {\n\t\tif (this.editor) {\n\t\t\tthis.editor.dispose();\n\t\t}\n\t\tthis.model.dispose();\n\t}\n\n\t@disposeOnUnmount\n\tprivate _updateText = autorun(() => {\n\t\tconst val = this.model.getValue();\n\t\tconst newVal = this.props.model.expression;\n\t\tif (val !== newVal) {\n\t\t\tthis.model.setValue(newVal);\n\t\t}\n\t});\n\n\t@disposeOnUnmount\n\tprivate _updateLanguageId = autorun(() => {\n\t\tmonaco.editor.setModelLanguage(this.model, this.props.model.languageId);\n\t});\n\n\tprivate readonly setEditorDiv = (editorDiv: HTMLDivElement) => {\n\t\tif (!editorDiv) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.editor = monaco.editor.create(editorDiv, {\n\t\t\tmodel: this.model,\n\t\t\tscrollBeyondLastLine: false,\n\t\t\tminimap: { enabled: false },\n\t\t\tfixedOverflowWidgets: true,\n\t\t\tlineNumbers: \"off\",\n\t\t\tglyphMargin: false,\n\t\t\tfolding: false,\n\t\t\tlineDecorationsWidth: 0,\n\t\t\tlineNumbersMinChars: 0,\n\t\t\tautomaticLayout: true,\n\t\t\tscrollbar: {\n\t\t\t\thorizontal: \"hidden\",\n\t\t\t\tvertical: \"hidden\",\n\t\t\t\thorizontalScrollbarSize: 0,\n\t\t\t\tverticalScrollbarSize: 0,\n\t\t\t},\n\t\t});\n\n\t\tthis.editor.onDidContentSizeChange((e) => {\n\t\t\tthis.contentHeight = e.contentHeight;\n\t\t});\n\n\t\tthis.editor.onDidBlurEditorText(() => {\n\t\t\tthis.submit();\n\t\t});\n\n\t\tthis.editor.onKeyDown((e) => {\n\t\t\tif (e.keyCode == monaco.KeyCode.Enter) {\n\t\t\t\tif (\n\t\t\t\t\t(this.model.getLineCount() <= 1 || e.ctrlKey) &&\n\t\t\t\t\t!e.shiftKey\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tthis.submit();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n\n\t@action.bound\n\tsubmit() {\n\t\tconst val = this.model.getValue();\n\t\t//console.log(val);\n\t\tthis.props.model.setExpression(val);\n\t}\n}\n"
  },
  {
    "path": "webview/src/components/GUI.tsx",
    "content": "import { Button, Spinner } from \"@blueprintjs/core\";\nimport { action, observable } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport * as React from \"react\";\nimport { Model } from \"../model/Model\";\nimport { ExpressionInput } from \"./ExpressionInput\";\nimport { Visualizer } from \"./Visualizer\";\nimport { VisualizerHeaderDetails } from \"./VisualizerHeaderDetails\";\nimport classnames = require(\"classnames\");\n\n@observer\nexport class GUI extends React.Component<{ model: Model }> {\n\trender() {\n\t\tconst m = this.props.model;\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName=\"component-GUI\"\n\t\t\t\ttabIndex={0}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\tflexDirection: \"column\",\n\t\t\t\t\theight: \"100%\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className=\"part-Header\">\n\t\t\t\t\t<VisualizerHeader model={m} />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"part-Visualizer\" style={{ flex: 1, minHeight: 0 }}>\n\t\t\t\t\t<Visualizer model={m} />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n}\n\n@observer\nexport class VisualizerHeader extends React.Component<{ model: Model }> {\n\t@observable expanded = false;\n\n\trender() {\n\t\tconst m = this.props.model;\n\t\treturn (\n\t\t\t<div className=\"component-VisualizerHeader\" style={{ display: \"flex\", flexDirection: \"row\" }}>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classnames(\"part-ExpandButton\", this.expanded && \"expanded\")}\n\t\t\t\t\tonClick={this.toggleExpanded}\n\t\t\t\t/>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"part-HeaderContent\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\tflexDirection: \"column\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"part-HeaderMain\">\n\t\t\t\t\t\t<VisualizerHeaderMain model={m} />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{this.expanded && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<div style={{ height: 6 }} />\n\t\t\t\t\t\t\t<VisualizerHeaderDetails model={m} />\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t@action.bound\n\ttoggleExpanded() {\n\t\tthis.expanded = !this.expanded;\n\t}\n}\n\n@observer\nexport class VisualizerHeaderMain extends React.Component<{ model: Model }> {\n\trender() {\n\t\tconst Spinner_ = Spinner as any; // WTF typescript??\n\t\tconst m = this.props.model;\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName=\"component-VisualizerHeaderMain\"\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className=\"part-ExpressionInput \" style={{ flex: 1, minWidth: 0 }}>\n\t\t\t\t\t<ExpressionInput model={m} />\n\t\t\t\t</div>\n\t\t\t\t<div style={{ width: 4 }} />\n\t\t\t\t{!m.isPolling &&\n\t\t\t\t\t(m.loading ? (\n\t\t\t\t\t\t<div style={{ padding: \"0 4px\" }}>\n\t\t\t\t\t\t\t<Spinner_ size={Spinner.SIZE_SMALL} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Button minimal small className=\"part-Icon\" icon=\"refresh\" onClick={() => m.refresh()} />\n\t\t\t\t\t))}\n\t\t\t\t<Button minimal small className=\"part-Icon\" icon=\"log-in\" onClick={() => m.openBrowser()} />\n\t\t\t\t{/*\n\t\t\t\t\tTODO\n\t\t\t\t\t<Button\n\t\t\t\t\t\tminimal\n\t\t\t\t\t\tsmall\n\t\t\t\t\t\tclassName=\"part-Icon\"\n\t\t\t\t\t\ticon=\"locate\"\n\t\t\t\t\t\tonClick={() => m.useSelectionAsExpression()}\n\t\t\t\t\t/>\n\t\t\t\t\t*/}\n\t\t\t</div>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "webview/src/components/NoData.tsx",
    "content": "import * as React from \"react\";\nimport { observer } from \"mobx-react\";\nimport { observable } from \"mobx\";\nimport Measure from \"react-measure\";\n\n@observer\nexport class NoData extends React.Component<{ children: React.ReactChild }> {\n\t@observable size = { width: 0, height: 0 };\n\t@observable innerSize = { width: 0, height: 0 };\n\n\trender() {\n\t\tconst { width, height } = this.size;\n\t\tconst { width: innerWidth, height: innerHeight } = this.innerSize;\n\t\treturn (\n\t\t\t<Measure\n\t\t\t\tclient={true}\n\t\t\t\tonResize={e => {\n\t\t\t\t\tif (e.client) {\n\t\t\t\t\t\tthis.size = {\n\t\t\t\t\t\t\theight: e.client.height,\n\t\t\t\t\t\t\twidth: e.client.width,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{({ measureRef }) => (\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"component-NoData\"\n\t\t\t\t\t\tref={measureRef}\n\t\t\t\t\t\tstyle={{ position: \"relative\" }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg>\n\t\t\t\t\t\t\t<line x1={0} y1={0} x2={width} y2={height} />\n\t\t\t\t\t\t\t<line x1={width} y1={0} x2={0} y2={height} />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"part-content\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\toverflow: \"auto\",\n\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\theight: \"100%\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Measure\n\t\t\t\t\t\t\t\tclient={true}\n\t\t\t\t\t\t\t\tonResize={e => {\n\t\t\t\t\t\t\t\t\tif (e.client) {\n\t\t\t\t\t\t\t\t\t\tthis.innerSize = {\n\t\t\t\t\t\t\t\t\t\t\theight: e.client.height,\n\t\t\t\t\t\t\t\t\t\t\twidth: e.client.width,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{({ measureRef }) => (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName=\"part-content-inner\"\n\t\t\t\t\t\t\t\t\t\tref={measureRef}\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\t\t\t\t\t\twidth: \"fit-content\",\n\t\t\t\t\t\t\t\t\t\t\theight: \"fit-content\",\n\t\t\t\t\t\t\t\t\t\t\tpadding: 10,\n\t\t\t\t\t\t\t\t\t\t\tleft: Math.max(\n\t\t\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t\t\t\twidth / 2 - innerWidth / 2\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\ttop: Math.max(\n\t\t\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t\t\t\theight / 2 - innerHeight / 2\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{this.props.children}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Measure>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</Measure>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "webview/src/components/Visualizer.tsx",
    "content": "import * as React from \"react\";\nimport { Model } from \"../model/Model\";\nimport { observer } from \"mobx-react\";\nimport { NoData } from \"./NoData\";\nimport { FormattedMessage } from \"debug-visualizer/src/webviewContract\";\nimport { VisualizationView, Theme } from \"@hediet/visualization-core\";\n\n@observer\nexport class Visualizer extends React.Component<{ model: Model }> {\n\trender() {\n\t\treturn (\n\t\t\t<div style={{ width: \"100%\", height: \"100%\", overflow: \"hidden\" }}>\n\t\t\t\t{this.renderContent()}\n\t\t\t</div>\n\t\t);\n\t}\n\n\trenderContent(): JSX.Element {\n\t\tconst s = this.props.model.state;\n\t\tif (s.kind === \"loading\") {\n\t\t\treturn <NoData>Loading</NoData>;\n\t\t} else if (s.kind === \"error\") {\n\t\t\treturn (\n\t\t\t\t<NoData>\n\t\t\t\t\t<Message message={s.message} />\n\t\t\t\t</NoData>\n\t\t\t);\n\t\t} else if (s.kind === \"noExpression\") {\n\t\t\treturn <NoData>No Expression Entered</NoData>;\n\t\t} else if (s.kind === \"visualizationError\") {\n\t\t\treturn <NoData>Visualization Error</NoData>;\n\t\t} else if (s.kind === \"noDebugSession\") {\n\t\t\treturn <NoData>No Active Debug Session</NoData>;\n\t\t} else if (s.kind === \"data\") {\n\t\t\tconst vis = this.props.model.visualizations;\n\t\t\tif (!vis || !vis.visualization) {\n\t\t\t\treturn <NoData>No Visualization Available</NoData>;\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<VisualizationView\n\t\t\t\t\ttheme={\n\t\t\t\t\t\tthis.props.model.theme === \"dark\"\n\t\t\t\t\t\t\t? Theme.dark\n\t\t\t\t\t\t\t: Theme.light\n\t\t\t\t\t}\n\t\t\t\t\tvisualization={vis.visualization}\n\t\t\t\t/>\n\t\t\t);\n\t\t} else {\n\t\t\tconst nvr: never = s;\n\t\t\treturn <div />;\n\t\t}\n\t}\n}\n\nfunction Message(props: { message: FormattedMessage }): React.ReactElement {\n\tif (typeof props.message === \"string\") {\n\t\treturn <span>{props.message}</span>;\n\t} else if (props.message.kind === \"list\") {\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t{props.message.items.map((i, idx) => (\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<Message key={idx} message={i} />\n\t\t\t\t\t</p>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t);\n\t} else if (props.message.kind === \"inlineList\") {\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t{props.message.items.map((i, idx) => (\n\t\t\t\t\t<Message key={idx} message={i} />\n\t\t\t\t))}\n\t\t\t</div>\n\t\t);\n\t} else if (props.message.kind === \"code\") {\n\t\treturn <pre>{props.message.content}</pre>;\n\t}\n\n\tthrow new Error(\"Bug\");\n}\n"
  },
  {
    "path": "webview/src/components/VisualizerHeaderDetails.tsx",
    "content": "import * as React from \"react\";\nimport { Popover, Checkbox } from \"@blueprintjs/core\";\nimport { DataExtractorInfo } from \"@hediet/debug-visualizer-data-extraction\";\nimport { computed } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { Model } from \"../model/Model\";\nimport { VisualizationId } from \"@hediet/visualization-core\";\n\n@observer\nexport class VisualizerHeaderDetails extends React.Component<{ model: Model }> {\n\trender() {\n\t\tconst m = this.props.model;\n\t\tlet availableExtractors = new Array<DataExtractorInfo>();\n\t\tlet selectedExtractor = -1;\n\t\tif (m.state.kind === \"data\") {\n\t\t\tconst result = m.state.result;\n\t\t\tavailableExtractors = result.availableExtractors;\n\t\t\tselectedExtractor = result.availableExtractors.findIndex(\n\t\t\t\ti => i.id === result.usedExtractor.id\n\t\t\t);\n\t\t}\n\n\t\tlet visualizations = new Array<{\n\t\t\tlabel: string;\n\t\t\tid: VisualizationId;\n\t\t}>();\n\t\tlet selectedVisualization = -1;\n\t\tif (m.visualizations) {\n\t\t\tvisualizations = m.visualizations.allVisualizations.map(v => ({\n\t\t\t\tlabel: v.name,\n\t\t\t\tid: v.id,\n\t\t\t}));\n\t\t\tif (m.visualizations.visualization) {\n\t\t\t\tselectedVisualization = visualizations.findIndex(\n\t\t\t\t\tv => v.id === m.visualizations!.visualization!.id\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName=\"component-VisualizerHeaderDetails\"\n\t\t\t\tstyle={{ display: \"flex\", alignItems: \"center\" }}\n\t\t\t>\n\t\t\t\t{/*\n\t\t\t\t\t<NamedSelect\n\t\t\t\t\t\tname=\"Source\"\n\t\t\t\t\t\tselected={0}\n\t\t\t\t\t\toptions={[{ label: \"js\" }]}\n\t\t\t\t\t\tonSelected={item => {}}\n\t\t\t\t\t/>\n\t\t\t\t*/}\n\t\t\t\t<div style={{ width: 10 }} />\n\n\t\t\t\t<NamedSelect\n\t\t\t\t\tname=\"Extractor\"\n\t\t\t\t\tselected={selectedExtractor}\n\t\t\t\t\toptions={availableExtractors.map(e => ({\n\t\t\t\t\t\tlabel: e.name,\n\t\t\t\t\t\tid: e.id,\n\t\t\t\t\t}))}\n\t\t\t\t\tonSelected={item => {\n\t\t\t\t\t\tm.setPreferredExtractorId(item.id);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<div style={{ width: 10 }} />\n\n\t\t\t\t<NamedSelect\n\t\t\t\t\tname=\"Visualizer\"\n\t\t\t\t\tselected={selectedVisualization}\n\t\t\t\t\tonSelected={item => {\n\t\t\t\t\t\tm.setPreferredVisualizationId(item.id);\n\t\t\t\t\t}}\n\t\t\t\t\toptions={\n\t\t\t\t\t\tm.visualizations\n\t\t\t\t\t\t\t? m.visualizations.allVisualizations.map(v => ({\n\t\t\t\t\t\t\t\t\tlabel: v.name,\n\t\t\t\t\t\t\t\t\tid: v.id,\n\t\t\t\t\t\t\t  }))\n\t\t\t\t\t\t\t: []\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t\t<div style={{ width: 10 }} />\n\t\t\t\t<Checkbox\n\t\t\t\t\tlabel=\"Poll\"\n\t\t\t\t\tchecked={m.isPolling}\n\t\t\t\t\tonChange={e => m.setPolling(e.currentTarget.checked)}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n}\n\nfunction NamedSelect<T extends SelectableItem>(props: {\n\tname: string;\n\tselected: number;\n\tonSelected: (item: T) => void;\n\toptions: T[];\n}) {\n\treturn (\n\t\t<div\n\t\t\tclassName=\"component-NamedSelect\"\n\t\t\tstyle={{\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexDirection: \"column\",\n\t\t\t\talignItems: \"center\",\n\t\t\t}}\n\t\t>\n\t\t\t<div className=\"part-Select\" style={{ minWidth: 100 }}>\n\t\t\t\t<Select {...props} />\n\t\t\t</div>\n\t\t\t<div className=\"part-Name\">{props.name}</div>\n\t\t</div>\n\t);\n}\n\ninterface SelectableItem {\n\tlabel: string;\n}\n\n@observer\nclass Select<T extends SelectableItem> extends React.Component<{\n\tselected: number;\n\tonSelected: (item: T) => void;\n\toptions: T[];\n}> {\n\t@computed get selected(): T | undefined {\n\t\treturn this.props.options[this.props.selected];\n\t}\n\n\trender() {\n\t\treturn (\n\t\t\t<div className=\"component-Select\">\n\t\t\t\t<Popover\n\t\t\t\t\tposition=\"auto-start\"\n\t\t\t\t\tmodifiers={{ arrow: { enabled: false } }}\n\t\t\t\t\tusePortal={false}\n\t\t\t\t>\n\t\t\t\t\t<button className=\"part-Button\">\n\t\t\t\t\t\t{this.selected ? this.selected.label : \"(none)\"}\n\t\t\t\t\t</button>\n\t\t\t\t\t<div className=\"part-Items\">\n\t\t\t\t\t\t{this.props.options.map((o, idx) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={idx}\n\t\t\t\t\t\t\t\tclassName=\"part-Item\"\n\t\t\t\t\t\t\t\tonClick={() => this.props.onSelected(o)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{o.label}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</Popover>\n\t\t\t</div>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "webview/src/hotComponent.tsx",
    "content": "import Module = require(\"module\");\nimport { observer } from \"mobx-react\";\nimport * as React from \"react\";\nimport { observable, runInAction } from \"mobx\";\n\ntype ReactComponent<P = any> =\n\t| React.ComponentClass<P>\n\t| React.FunctionComponent<P>;\n\nconst allComponents = new Map<string, { component: ReactComponent }>();\n\nexport function hotComponent(\n\tmodule: Module\n): <T extends ReactComponent>(Component: T) => T {\n\treturn <T extends ReactComponent>(component: T): T => {\n\t\tconst key = JSON.stringify({ id: module.id, name: component.name });\n\n\t\tlet result = allComponents.get(key);\n\t\tif (!result) {\n\t\t\tresult = observable({ component: component });\n\t\t\tallComponents.set(key, result);\n\t\t} else {\n\t\t\tsetTimeout(() => {\n\t\t\t\trunInAction(`Update Component ${component.name}`, () => {\n\t\t\t\t\tresult!.component = component;\n\t\t\t\t});\n\t\t\t}, 0);\n\t\t}\n\n\t\tconst m = module as {\n\t\t\thot?: {\n\t\t\t\taccept: ((\n\t\t\t\t\tcomponentName: string,\n\t\t\t\t\tcallback: () => void\n\t\t\t\t) => void) &\n\t\t\t\t\t((callback: () => void) => void);\n\t\t\t};\n\t\t};\n\n\t\tif (m.hot) {\n\t\t\tm.hot.accept(() => {});\n\t\t}\n\n\t\treturn observer((props: any) => {\n\t\t\tconst C = result!.component;\n\t\t\tconst C_ = C as any; // WTF typescript/yarn??\n\t\t\treturn <C_ {...props} />;\n\t\t}) as any;\n\t};\n}\n"
  },
  {
    "path": "webview/src/index.tsx",
    "content": "import * as monaco from \"monaco-editor\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { App } from \"./components/App\";\nimport \"./style.scss\";\n\n(globalThis as any).monaco = monaco;\n\nconst elem = document.createElement(\"div\");\nelem.className = \"react-root\";\ndocument.body.append(elem);\nReactDOM.render(<App />, elem);\n"
  },
  {
    "path": "webview/src/model/Model.ts",
    "content": "import { DataExtractorId, VisualizationData } from \"@hediet/debug-visualizer-data-extraction\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { EventTimer } from \"@hediet/std/timer\";\nimport { ConsoleRpcLogger } from \"@hediet/typed-json-rpc\";\nimport { WebSocketStream } from \"@hediet/typed-json-rpc-websocket\";\nimport \"@hediet/visualization-bundle\";\nimport {\n\tRegisterVisualizerFn,\n\tVisualization,\n\tVisualizationFactory,\n\tVisualizationId,\n\tcreateVisualizer,\n\tglobalVisualizationFactory,\n\tlibImplementation,\n} from \"@hediet/visualization-core\";\nimport {\n\tDataExtractionState,\n\tWebviewUrlParams,\n\tWindowWithWebviewData,\n\twebviewContract,\n} from \"debug-visualizer/src/webviewContract\";\nimport { ObservableMap, action, computed, observable, runInAction, when } from \"mobx\";\nimport { MonacoBridge } from \"./MonacoBridge\";\nimport { getApi as getVsCodeApi } from \"./VsCodeApi\";\n\ndeclare const window: Window & WindowWithWebviewData;\n\ndeclare let __webpack_public_path__: string;\n\nexport class Model {\n\tpublic readonly dispose = Disposable.fn();\n\tpublic readonly runningMode: \"standalone\" | \"webview\" | \"webviewIFrame\" = \"webview\";\n\n\t@observable\n\tpublic theme: \"dark\" | \"light\" = \"light\";\n\n\tprivate port: number;\n\tprivate serverSecret: string;\n\n\t@observable expression: string = \"\";\n\t@observable.ref state:\n\t\t| DataExtractionState\n\t\t| { kind: \"noExpression\" }\n\t\t| { kind: \"visualizationError\"; data: VisualizationData } = {\n\t\tkind: \"noExpression\",\n\t};\n\n\t@observable languageId: string = \"text\";\n\n\t@observable private preferredVisualizationId: VisualizationId | undefined = undefined;\n\n\t@observable isPolling = false;\n\tprivate readonly pollingTimer = this.dispose.track(new EventTimer(500, \"stopped\"));\n\n\t@action\n\tpublic setPreferredVisualizationId(id: VisualizationId) {\n\t\tthis.preferredVisualizationId = id;\n\t}\n\n\t@action\n\tpublic setVisualizationError(data: VisualizationData) {\n\t\tthis.state = { kind: \"visualizationError\", data: data };\n\t}\n\n\t@action\n\tpublic setPolling(value: boolean) {\n\t\tthis.isPolling = value;\n\t\tif (value) {\n\t\t\tthis.pollingTimer.start();\n\t\t} else {\n\t\t\tthis.pollingTimer.stop();\n\t\t}\n\t}\n\n\t@computed get visualizations():\n\t\t| {\n\t\t\t\tvisualization: Visualization | undefined;\n\t\t\t\tallVisualizations: Visualization[];\n\t\t  }\n\t\t| undefined {\n\t\tif (this.state.kind === \"data\") {\n\t\t\tconst vis = visualizerRegistry\n\t\t\t\t.get()\n\t\t\t\t.getVisualizations(this.state.result.data, this.preferredVisualizationId);\n\t\t\treturn {\n\t\t\t\tvisualization: vis.bestVisualization,\n\t\t\t\tallVisualizations: vis.allVisualizations,\n\t\t\t};\n\t\t} else {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@observable.ref\n\tpublic server: typeof webviewContract.TServerInterface | undefined = undefined;\n\n\tprivate readonly vsCodeApi = getVsCodeApi<{ expression: string }>();\n\n\t@observable private _loading = false;\n\n\tpublic get loading(): boolean {\n\t\treturn this._loading;\n\t}\n\n\tprivate readonly _bridge = new MonacoBridge(this);\n\n\tconstructor() {\n\t\tif (window.webviewData) {\n\t\t\tconst data = window.webviewData;\n\t\t\tthis.port = data.serverPort;\n\t\t\tthis.serverSecret = data.serverSecret;\n\t\t\tthis.runningMode = \"webview\";\n\t\t\t__webpack_public_path__ = data.publicPath;\n\n\t\t\tthis.theme = window.webviewData.theme;\n\n\t\t\tif (data.expression !== undefined) {\n\t\t\t\tthis.setExpression(data.expression);\n\t\t\t}\n\t\t} else {\n\t\t\tconst url = new URL(window.location.href);\n\t\t\tconst urlParams = Object.fromEntries(url.searchParams.entries()) as unknown as WebviewUrlParams;\n\t\t\tconst portStr = urlParams.serverPort;\n\t\t\tif (!portStr) {\n\t\t\t\tthrow new Error(\"No port given.\");\n\t\t\t}\n\t\t\tthis.port = parseInt(portStr);\n\n\t\t\tconst expr = urlParams.expression;\n\t\t\tif (expr) {\n\t\t\t\tthis.setExpression(expr);\n\t\t\t}\n\n\t\t\tconst secret = urlParams.serverSecret;\n\t\t\tif (!secret) {\n\t\t\t\tthrow new Error(\"Server secret not set.\");\n\t\t\t}\n\t\t\tthis.serverSecret = secret;\n\n\t\t\tconst theme = urlParams.theme;\n\t\t\tif (theme) {\n\t\t\t\tthis.theme = theme;\n\t\t\t}\n\n\t\t\tconst mode = urlParams.mode;\n\t\t\tif (mode) {\n\t\t\t\tthis.runningMode = mode as any;\n\t\t\t} else {\n\t\t\t\tthis.runningMode = \"standalone\";\n\t\t\t}\n\t\t}\n\n\t\tthis.stayConnected();\n\n\t\tthis.vsCodeApi.getState().then((state) => {\n\t\t\tif (state) {\n\t\t\t\tthis.setExpression(state.expression);\n\t\t\t}\n\t\t});\n\n\t\tthis.pollingTimer.onTick.sub(() => {\n\t\t\tthis.refresh();\n\t\t});\n\t}\n\n\t@action\n\tsetExpression(newExpression: string) {\n\t\tthis.expression = newExpression;\n\t\twhen(() => !!this.server).then(() => {\n\t\t\tthis.server!.setExpression({ newExpression });\n\t\t});\n\n\t\tthis.vsCodeApi.setState({\n\t\t\texpression: newExpression,\n\t\t});\n\n\t\tconst url = new URL(window.location.href);\n\t\turl.searchParams.set(\"expression\", newExpression);\n\t\thistory.replaceState(null, document.title, url.toString());\n\t}\n\n\tsetPreferredExtractorId(id: DataExtractorId) {\n\t\tif (this.server) {\n\t\t\tthis.server.setPreferredDataExtractor({\n\t\t\t\tdataExtractorId: id,\n\t\t\t});\n\t\t}\n\t}\n\n\trefresh() {\n\t\tif (this.server) {\n\t\t\tthis.server.refresh();\n\t\t}\n\t}\n\n\tasync stayConnected(): Promise<void> {\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\tconst stream = await WebSocketStream.connectTo({\n\t\t\t\t\thost: \"localhost\",\n\t\t\t\t\tport: this.port,\n\t\t\t\t});\n\t\t\t\tconst { server } = webviewContract.getServerFromStream(stream, new ConsoleRpcLogger(), {\n\t\t\t\t\tupdateState: async ({ newState }) => {\n\t\t\t\t\t\trunInAction(() => {\n\t\t\t\t\t\t\tthis._loading = newState.kind === \"loading\";\n\t\t\t\t\t\t\tif (!this._loading) {\n\t\t\t\t\t\t\t\tthis.state = newState;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tsetExpression: async ({ expression }) => {\n\t\t\t\t\t\tthis.setExpression(expression);\n\t\t\t\t\t},\n\t\t\t\t\tupdateLanguageId: async ({ languageId }) => {\n\t\t\t\t\t\tthis.languageId = languageId || \"text\";\n\t\t\t\t\t},\n\t\t\t\t\tsetTheme: async ({ theme }) => {\n\t\t\t\t\t\tthis.theme = theme;\n\t\t\t\t\t},\n\t\t\t\t\tsetCustomVisualizerScript: async ({ id, jsSource }) => {\n\t\t\t\t\t\teval(`\n\t\t\t\t\t\t\t\t((load) => {\n\t\t\t\t\t\t\t\t\tlet fn = undefined;\n\t\t\t\t\t\t\t\t\tif (load) {\n\t\t\t\t\t\t\t\t\t\tconst module = {};\n\t\t\t\t\t\t\t\t\t\tload(module);\n\t\t\t\t\t\t\t\t\t\tfn = module.exports;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsetVisualizationModule(${JSON.stringify(id)}, fn);\n\t\t\t\t\t\t\t\t})(\n\t\t\t\t\t\t\t\t\t${jsSource ? `function (module) { ${jsSource} }` : \"undefined\"}\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t`);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tawait server.authenticate({ secret: this.serverSecret });\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t}\n\t\t\t\tthis.server = server;\n\n\t\t\t\tawait stream.onClosed;\n\t\t\t} catch (e) {}\n\t\t}\n\t}\n\n\topenBrowser() {\n\t\tif (this.server) {\n\t\t\tthis.server.openInBrowser();\n\t\t}\n\t}\n\n\tuseSelectionAsExpression() {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n}\n\nconst fns = new ObservableMap<string, RegisterVisualizerFn>();\nconst visualizerRegistry = computed(() => {\n\tconst result = new VisualizationFactory();\n\tfor (const visualization of globalVisualizationFactory.getRegisteredVisualizers()) {\n\t\tresult.addVisualizer(visualization);\n\t}\n\tfor (const visualization of globalVisualizationFactory.getRegisteredHiddenVisualizer()) {\n\t\tresult.addHiddenVisualizer(visualization);\n\t}\n\tfns.forEach((fn) => {\n\t\tfn((options) => result.addVisualizer(createVisualizer(options)), libImplementation);\n\t});\n\treturn result;\n});\n\nfunction setVisualizationModule(id: string, moduleFn: RegisterVisualizerFn | undefined) {\n\tif (moduleFn) {\n\t\tfns.set(id, moduleFn);\n\t} else {\n\t\tfns.delete(id);\n\t}\n}\n\n(globalThis as any).setVisualizationModule = setVisualizationModule;\n"
  },
  {
    "path": "webview/src/model/MonacoBridge.ts",
    "content": "import * as monaco from \"monaco-editor\";\nimport { Model } from \"./Model\";\nimport { Disposable } from \"@hediet/std/disposable\";\nimport { autorun } from \"mobx\";\n\ndeclare const require: {\n\t(path: string): { default: string };\n\tcontext: (\n\t\tpath: string,\n\t\tincludeSubDirs: boolean,\n\t\tregex: RegExp\n\t) => { (fileName: string): { default: string }; keys(): string[] };\n};\n\nexport class MonacoBridge {\n\tpublic readonly dispose = Disposable.fn();\n\n\tconstructor(private readonly model: Model) {\n\t\tmonaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({\n\t\t\tnoSemanticValidation: true,\n\t\t\tnoSyntaxValidation: true,\n\t\t});\n\t\tmonaco.languages.typescript.javascriptDefaults.setCompilerOptions({\n\t\t\ttarget: monaco.languages.typescript.ScriptTarget.ES5,\n\t\t\tallowNonTsExtensions: true,\n\t\t\tmoduleResolution:\n\t\t\t\tmonaco.languages.typescript.ModuleResolutionKind.NodeJs,\n\t\t\tmodule: monaco.languages.typescript.ModuleKind.CommonJS,\n\t\t\tstrict: true,\n\t\t});\n\n\t\tconst es5Lib = require(\"!!raw-loader!./lib.es5.d.ts.txt\").default;\n\t\tconst commonTypes = require.context(\n\t\t\t\"!!raw-loader!@hediet/debug-visualizer-data-extraction/dist/\",\n\t\t\ttrue,\n\t\t\t/.*.d.ts$/\n\t\t);\n\n\t\tfor (const file of commonTypes.keys()) {\n\t\t\tthis.dispose.track(\n\t\t\t\tmonaco.languages.typescript.javascriptDefaults.addExtraLib(\n\t\t\t\t\tcommonTypes(file).default,\n\t\t\t\t\t`file:///node_modules/debug-visualizer-data-extraction/${file}`\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tthis.dispose.track([\n\t\t\tmonaco.languages.typescript.javascriptDefaults.addExtraLib(es5Lib),\n\t\t\tmonaco.languages.typescript.javascriptDefaults.addExtraLib(\n\t\t\t\t`declare const hedietDbgVis: typeof import(\"debug-visualizer-data-extraction/js/helpers\")`,\n\t\t\t\t`file:///types.d.ts`\n\t\t\t),\n\t\t]);\n\n\t\tconst debugSessionCompletionProvider = new DebugSessionCompletionProvider(\n\t\t\tthis.model\n\t\t);\n\n\t\tthis.dispose.track([\n\t\t\tmonaco.languages.registerCompletionItemProvider(\n\t\t\t\t\"javascript\",\n\t\t\t\tdebugSessionCompletionProvider\n\t\t\t),\n\t\t\tmonaco.languages.registerCompletionItemProvider(\n\t\t\t\t\"text\",\n\t\t\t\tdebugSessionCompletionProvider\n\t\t\t),\n\t\t]);\n\n\t\tthis.dispose.track({\n\t\t\tdispose: autorun(() => {\n\t\t\t\tmonaco.editor.setTheme(\n\t\t\t\t\tmodel.theme === \"light\" ? \"vs-light\" : \"vs-dark\"\n\t\t\t\t);\n\t\t\t}),\n\t\t});\n\t}\n}\n\nclass DebugSessionCompletionProvider\n\timplements monaco.languages.CompletionItemProvider {\n\tpublic readonly triggerCharacters = [\".\"];\n\n\tprivate readonly map = {\n\t\tmethod: monaco.languages.CompletionItemKind.Method,\n\t\tfunction: monaco.languages.CompletionItemKind.Function,\n\t\tconstructor: monaco.languages.CompletionItemKind.Constructor,\n\t\tfield: monaco.languages.CompletionItemKind.Field,\n\t\tvariable: monaco.languages.CompletionItemKind.Variable,\n\t\tclass: monaco.languages.CompletionItemKind.Class,\n\t\tinterface: monaco.languages.CompletionItemKind.Interface,\n\t\tmodule: monaco.languages.CompletionItemKind.Module,\n\t\tproperty: monaco.languages.CompletionItemKind.Property,\n\t\tunit: monaco.languages.CompletionItemKind.Unit,\n\t\tvalue: monaco.languages.CompletionItemKind.Value,\n\t\tenum: monaco.languages.CompletionItemKind.Enum,\n\t\tkeyword: monaco.languages.CompletionItemKind.Keyword,\n\t\tsnippet: monaco.languages.CompletionItemKind.Snippet,\n\t\ttext: monaco.languages.CompletionItemKind.Text,\n\t\tcolor: monaco.languages.CompletionItemKind.Color,\n\t\tfile: monaco.languages.CompletionItemKind.File,\n\t\treference: monaco.languages.CompletionItemKind.Reference,\n\t\tcustomcolor: monaco.languages.CompletionItemKind.Customcolor,\n\t};\n\n\tconstructor(private readonly model: Model) {}\n\n\tpublic async provideCompletionItems(\n\t\tmodel: monaco.editor.ITextModel,\n\t\tposition: monaco.Position,\n\t\tcontext: monaco.languages.CompletionContext\n\t): Promise<monaco.languages.CompletionList> {\n\t\tconst expression = model.getValue();\n\n\t\tif (!this.model.server) {\n\t\t\treturn { suggestions: [] };\n\t\t}\n\t\tconst completions = (\n\t\t\tawait this.model.server.getCompletions({\n\t\t\t\ttext: expression,\n\t\t\t\tcolumn: position.column,\n\t\t\t})\n\t\t).completions;\n\n\t\tconst p = model.getWordAtPosition(position);\n\n\t\treturn {\n\t\t\tsuggestions: completions.map<monaco.languages.CompletionItem>(c => {\n\t\t\t\tconst startColumn =\n\t\t\t\t\tc.start || (p && p.startColumn) || position.column;\n\n\t\t\t\treturn {\n\t\t\t\t\tinsertText: c.text || c.label,\n\t\t\t\t\tlabel: c.label,\n\t\t\t\t\tkind: this.map[c.type || \"text\"],\n\t\t\t\t\trange: {\n\t\t\t\t\t\tstartColumn,\n\t\t\t\t\t\tendColumn: startColumn + (c.length || 0),\n\t\t\t\t\t\tstartLineNumber: 0,\n\t\t\t\t\t\tendLineNumber: 0,\n\t\t\t\t\t},\n\t\t\t\t\tsortText: c.type === \"property\" ? \"zzzzzzz\" : c.label,\n\t\t\t\t};\n\t\t\t}),\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "webview/src/model/VsCodeApi.ts",
    "content": "import { Barrier } from \"@hediet/std/synchronization\";\n\nexport interface VSCodeApi<TState> {\n\tgetState(): Promise<TState | undefined>;\n\tsetState(state: TState): Promise<void>;\n}\n\ntype IncomingCommand = {\n\tcommand: \"getStateResult\";\n\tstate: unknown;\n};\n\ntype OutgoingCommand =\n\t| {\n\t\t\tcommand: \"setState\";\n\t\t\tstate: unknown;\n\t  }\n\t| { command: \"getState\" };\n\ninterface VsCodeApi {\n\tgetState<TState>(): TState | undefined;\n\tsetState(state: unknown): void;\n}\n\nexport function getApi<TState>(): VSCodeApi<TState> {\n\treturn window.VsCodeApi\n\t\t? new DirectVSCodeApi<TState>(window.VsCodeApi)\n\t\t: new IFrameVSCodeApi<TState>();\n}\n\ndeclare const window: Window & {\n\tVsCodeApi?: VsCodeApi;\n};\n\nexport class IFrameVSCodeApi<TState> implements VSCodeApi<TState> {\n\tprivate currentGetStatePromise: Barrier<TState> | undefined = undefined;\n\n\tconstructor() {\n\t\twindow.addEventListener(\"message\", event => {\n\t\t\tconst data = event.data as IncomingCommand;\n\t\t\tif (data.command === \"getStateResult\") {\n\t\t\t\tthis.currentGetStatePromise!.unlock(data.state as any);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate sendCommand(command: OutgoingCommand) {\n\t\twindow.parent.postMessage(command, \"*\");\n\t}\n\n\tgetState(): Promise<TState | undefined> {\n\t\tthis.sendCommand({ command: \"getState\" });\n\t\tif (this.currentGetStatePromise) {\n\t\t\tthrow new Error(\"Get state already in progress.\");\n\t\t}\n\t\tthis.currentGetStatePromise = new Barrier();\n\t\treturn this.currentGetStatePromise.onUnlocked;\n\t}\n\n\tasync setState(state: TState): Promise<void> {\n\t\tthis.sendCommand({ command: \"setState\", state });\n\t}\n}\n\nexport class DirectVSCodeApi<TState> implements VSCodeApi<TState> {\n\tconstructor(private readonly vsCodeApi: VsCodeApi) {}\n\n\tasync getState(): Promise<TState | undefined> {\n\t\treturn this.vsCodeApi.getState<TState | undefined>();\n\t}\n\n\tasync setState(state: TState): Promise<void> {\n\t\tthis.vsCodeApi.setState(state);\n\t}\n}\n"
  },
  {
    "path": "webview/src/model/lib.es5.d.ts.txt",
    "content": "/*! *****************************************************************************\nCopyright (c) Microsoft Corporation. All rights reserved. \nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthis file except in compliance with the License. You may obtain a copy of the\nLicense at http://www.apache.org/licenses/LICENSE-2.0  \n \nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, \nMERCHANTABLITY OR NON-INFRINGEMENT. \n \nSee the Apache Version 2.0 License for specific language governing permissions\nand limitations under the License.\n***************************************************************************** */\n\n\n\n/// <reference no-default-lib=\"true\"/>\n\n\n/////////////////////////////\n/// ECMAScript APIs\n/////////////////////////////\n\ndeclare var NaN: number;\ndeclare var Infinity: number;\n\n/**\n  * Evaluates JavaScript code and executes it.\n  * @param x A String value that contains valid JavaScript code.\n  */\ndeclare function eval(x: string): any;\n\n/**\n  * Converts a string to an integer.\n  * @param s A string to convert into a number.\n  * @param radix A value between 2 and 36 that specifies the base of the number in numString.\n  * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\n  * All other strings are considered decimal.\n  */\ndeclare function parseInt(s: string, radix?: number): number;\n\n/**\n  * Converts a string to a floating-point number.\n  * @param string A string that contains a floating-point number.\n  */\ndeclare function parseFloat(string: string): number;\n\n/**\n  * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).\n  * @param number A numeric value.\n  */\ndeclare function isNaN(number: number): boolean;\n\n/**\n  * Determines whether a supplied number is finite.\n  * @param number Any numeric value.\n  */\ndeclare function isFinite(number: number): boolean;\n\n/**\n  * Gets the unencoded version of an encoded Uniform Resource Identifier (URI).\n  * @param encodedURI A value representing an encoded URI.\n  */\ndeclare function decodeURI(encodedURI: string): string;\n\n/**\n  * Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI).\n  * @param encodedURIComponent A value representing an encoded URI component.\n  */\ndeclare function decodeURIComponent(encodedURIComponent: string): string;\n\n/**\n  * Encodes a text string as a valid Uniform Resource Identifier (URI)\n  * @param uri A value representing an encoded URI.\n  */\ndeclare function encodeURI(uri: string): string;\n\n/**\n  * Encodes a text string as a valid component of a Uniform Resource Identifier (URI).\n  * @param uriComponent A value representing an encoded URI component.\n  */\ndeclare function encodeURIComponent(uriComponent: string | number | boolean): string;\n\n/**\n  * Computes a new string in which certain characters have been replaced by a hexadecimal escape sequence.\n  * @param string A string value\n  */\ndeclare function escape(string: string): string;\n\n/**\n  * Computes a new string in which hexadecimal escape sequences are replaced with the character that it represents.\n  * @param string A string value\n  */\ndeclare function unescape(string: string): string;\n\ninterface Symbol {\n  /** Returns a string representation of an object. */\n  toString(): string;\n\n  /** Returns the primitive value of the specified object. */\n  valueOf(): symbol;\n}\n\ndeclare type PropertyKey = string | number | symbol;\n\ninterface PropertyDescriptor {\n    configurable?: boolean;\n    enumerable?: boolean;\n    value?: any;\n    writable?: boolean;\n    get?(): any;\n    set?(v: any): void;\n}\n\ninterface PropertyDescriptorMap {\n    [s: string]: PropertyDescriptor;\n}\n\ninterface Object {\n    /** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */\n    constructor: Function;\n\n    /** Returns a string representation of an object. */\n    toString(): string;\n\n    /** Returns a date converted to a string using the current locale. */\n    toLocaleString(): string;\n\n    /** Returns the primitive value of the specified object. */\n    valueOf(): Object;\n\n    /**\n      * Determines whether an object has a property with the specified name.\n      * @param v A property name.\n      */\n    hasOwnProperty(v: PropertyKey): boolean;\n\n    /**\n      * Determines whether an object exists in another object's prototype chain.\n      * @param v Another object whose prototype chain is to be checked.\n      */\n    isPrototypeOf(v: Object): boolean;\n\n    /**\n      * Determines whether a specified property is enumerable.\n      * @param v A property name.\n      */\n    propertyIsEnumerable(v: PropertyKey): boolean;\n}\n\ninterface ObjectConstructor {\n    new(value?: any): Object;\n    (): any;\n    (value: any): any;\n\n    /** A reference to the prototype for a class of objects. */\n    readonly prototype: Object;\n\n    /**\n      * Returns the prototype of an object.\n      * @param o The object that references the prototype.\n      */\n    getPrototypeOf(o: any): any;\n\n    /**\n      * Gets the own property descriptor of the specified object.\n      * An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype.\n      * @param o Object that contains the property.\n      * @param p Name of the property.\n    */\n    getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined;\n\n    /**\n      * Returns the names of the own properties of an object. The own properties of an object are those that are defined directly\n      * on that object, and are not inherited from the object's prototype. The properties of an object include both fields (objects) and functions.\n      * @param o Object that contains the own properties.\n      */\n    getOwnPropertyNames(o: any): string[];\n\n    /**\n      * Creates an object that has the specified prototype or that has null prototype.\n      * @param o Object to use as a prototype. May be null.\n      */\n    create(o: object | null): any;\n\n    /**\n      * Creates an object that has the specified prototype, and that optionally contains specified properties.\n      * @param o Object to use as a prototype. May be null\n      * @param properties JavaScript object that contains one or more property descriptors.\n      */\n    create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;\n\n    /**\n      * Adds a property to an object, or modifies attributes of an existing property.\n      * @param o Object on which to add or modify the property. This can be a native JavaScript object (that is, a user-defined object or a built in object) or a DOM object.\n      * @param p The property name.\n      * @param attributes Descriptor for the property. It can be for a data property or an accessor property.\n      */\n    defineProperty(o: any, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): any;\n\n    /**\n      * Adds one or more properties to an object, and/or modifies attributes of existing properties.\n      * @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.\n      * @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.\n      */\n    defineProperties(o: any, properties: PropertyDescriptorMap & ThisType<any>): any;\n\n    /**\n      * Prevents the modification of attributes of existing properties, and prevents the addition of new properties.\n      * @param o Object on which to lock the attributes.\n      */\n    seal<T>(o: T): T;\n\n    /**\n      * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.\n      * @param o Object on which to lock the attributes.\n      */\n    freeze<T>(a: T[]): ReadonlyArray<T>;\n\n    /**\n      * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.\n      * @param o Object on which to lock the attributes.\n      */\n    freeze<T extends Function>(f: T): T;\n\n    /**\n      * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.\n      * @param o Object on which to lock the attributes.\n      */\n    freeze<T>(o: T): Readonly<T>;\n\n    /**\n      * Prevents the addition of new properties to an object.\n      * @param o Object to make non-extensible.\n      */\n    preventExtensions<T>(o: T): T;\n\n    /**\n      * Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object.\n      * @param o Object to test.\n      */\n    isSealed(o: any): boolean;\n\n    /**\n      * Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object.\n      * @param o Object to test.\n      */\n    isFrozen(o: any): boolean;\n\n    /**\n      * Returns a value that indicates whether new properties can be added to an object.\n      * @param o Object to test.\n      */\n    isExtensible(o: any): boolean;\n\n    /**\n      * Returns the names of the enumerable string properties and methods of an object.\n      * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\n      */\n     keys(o: object): string[];\n}\n\n/**\n  * Provides functionality common to all JavaScript objects.\n  */\ndeclare var Object: ObjectConstructor;\n\n/**\n  * Creates a new function.\n  */\ninterface Function {\n    /**\n      * Calls the function, substituting the specified object for the this value of the function, and the specified array for the arguments of the function.\n      * @param thisArg The object to be used as the this object.\n      * @param argArray A set of arguments to be passed to the function.\n      */\n    apply(this: Function, thisArg: any, argArray?: any): any;\n\n    /**\n      * Calls a method of an object, substituting another object for the current object.\n      * @param thisArg The object to be used as the current object.\n      * @param argArray A list of arguments to be passed to the method.\n      */\n    call(this: Function, thisArg: any, ...argArray: any[]): any;\n\n    /**\n      * For a given function, creates a bound function that has the same body as the original function.\n      * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\n      * @param thisArg An object to which the this keyword can refer inside the new function.\n      * @param argArray A list of arguments to be passed to the new function.\n      */\n    bind(this: Function, thisArg: any, ...argArray: any[]): any;\n\n    /** Returns a string representation of a function. */\n    toString(): string;\n\n    prototype: any;\n    readonly length: number;\n\n    // Non-standard extensions\n    arguments: any;\n    caller: Function;\n}\n\ninterface FunctionConstructor {\n    /**\n      * Creates a new function.\n      * @param args A list of arguments the function accepts.\n      */\n    new(...args: string[]): Function;\n    (...args: string[]): Function;\n    readonly prototype: Function;\n}\n\ndeclare var Function: FunctionConstructor;\n\n/**\n * Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter.\n */\ntype ThisParameterType<T> = T extends (this: unknown, ...args: any[]) => any ? unknown : T extends (this: infer U, ...args: any[]) => any ? U : unknown;\n\n/**\n * Removes the 'this' parameter from a function type.\n */\ntype OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;\n\ninterface CallableFunction extends Function {\n    /**\n      * Calls the function with the specified object as the this value and the elements of specified array as the arguments.\n      * @param thisArg The object to be used as the this object.\n      * @param args An array of argument values to be passed to the function.\n      */\n    apply<T, R>(this: (this: T) => R, thisArg: T): R;\n    apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;\n\n    /**\n      * Calls the function with the specified object as the this value and the specified rest arguments as the arguments.\n      * @param thisArg The object to be used as the this object.\n      * @param args Argument values to be passed to the function.\n      */\n    call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;\n\n    /**\n      * For a given function, creates a bound function that has the same body as the original function.\n      * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\n      * @param thisArg The object to be used as the this object.\n      * @param args Arguments to bind to the parameters of the function.\n      */\n    bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;\n    bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;\n    bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;\n    bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;\n    bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;\n    bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;\n}\n\ninterface NewableFunction extends Function {\n    /**\n      * Calls the function with the specified object as the this value and the elements of specified array as the arguments.\n      * @param thisArg The object to be used as the this object.\n      * @param args An array of argument values to be passed to the function.\n      */\n    apply<T>(this: new () => T, thisArg: T): void;\n    apply<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, args: A): void;\n\n    /**\n      * Calls the function with the specified object as the this value and the specified rest arguments as the arguments.\n      * @param thisArg The object to be used as the this object.\n      * @param args Argument values to be passed to the function.\n      */\n    call<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, ...args: A): void;\n\n    /**\n      * For a given function, creates a bound function that has the same body as the original function.\n      * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\n      * @param thisArg The object to be used as the this object.\n      * @param args Arguments to bind to the parameters of the function.\n      */\n    bind<T>(this: T, thisArg: any): T;\n    bind<A0, A extends any[], R>(this: new (arg0: A0, ...args: A) => R, thisArg: any, arg0: A0): new (...args: A) => R;\n    bind<A0, A1, A extends any[], R>(this: new (arg0: A0, arg1: A1, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1): new (...args: A) => R;\n    bind<A0, A1, A2, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2): new (...args: A) => R;\n    bind<A0, A1, A2, A3, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2, arg3: A3): new (...args: A) => R;\n    bind<AX, R>(this: new (...args: AX[]) => R, thisArg: any, ...args: AX[]): new (...args: AX[]) => R;\n}\n\ninterface IArguments {\n    [index: number]: any;\n    length: number;\n    callee: Function;\n}\n\ninterface String {\n    /** Returns a string representation of a string. */\n    toString(): string;\n\n    /**\n      * Returns the character at the specified index.\n      * @param pos The zero-based index of the desired character.\n      */\n    charAt(pos: number): string;\n\n    /**\n      * Returns the Unicode value of the character at the specified location.\n      * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.\n      */\n    charCodeAt(index: number): number;\n\n    /**\n      * Returns a string that contains the concatenation of two or more strings.\n      * @param strings The strings to append to the end of the string.\n      */\n    concat(...strings: string[]): string;\n\n    /**\n      * Returns the position of the first occurrence of a substring.\n      * @param searchString The substring to search for in the string\n      * @param position The index at which to begin searching the String object. If omitted, search starts at the beginning of the string.\n      */\n    indexOf(searchString: string, position?: number): number;\n\n    /**\n      * Returns the last occurrence of a substring in the string.\n      * @param searchString The substring to search for.\n      * @param position The index at which to begin searching. If omitted, the search begins at the end of the string.\n      */\n    lastIndexOf(searchString: string, position?: number): number;\n\n    /**\n      * Determines whether two strings are equivalent in the current locale.\n      * @param that String to compare to target string\n      */\n    localeCompare(that: string): number;\n\n    /**\n      * Matches a string with a regular expression, and returns an array containing the results of that search.\n      * @param regexp A variable name or string literal containing the regular expression pattern and flags.\n      */\n    match(regexp: string | RegExp): RegExpMatchArray | null;\n\n    /**\n      * Replaces text in a string, using a regular expression or search string.\n      * @param searchValue A string to search for.\n      * @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.\n      */\n    replace(searchValue: string | RegExp, replaceValue: string): string;\n\n    /**\n      * Replaces text in a string, using a regular expression or search string.\n      * @param searchValue A string to search for.\n      * @param replacer A function that returns the replacement text.\n      */\n    replace(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string;\n\n    /**\n      * Finds the first substring match in a regular expression search.\n      * @param regexp The regular expression pattern and applicable flags.\n      */\n    search(regexp: string | RegExp): number;\n\n    /**\n      * Returns a section of a string.\n      * @param start The index to the beginning of the specified portion of stringObj.\n      * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end.\n      * If this value is not specified, the substring continues to the end of stringObj.\n      */\n    slice(start?: number, end?: number): string;\n\n    /**\n      * Split a string into substrings using the specified separator and return them as an array.\n      * @param separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned.\n      * @param limit A value used to limit the number of elements returned in the array.\n      */\n    split(separator: string | RegExp, limit?: number): string[];\n\n    /**\n      * Returns the substring at the specified location within a String object.\n      * @param start The zero-based index number indicating the beginning of the substring.\n      * @param end Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end.\n      * If end is omitted, the characters from start through the end of the original string are returned.\n      */\n    substring(start: number, end?: number): string;\n\n    /** Converts all the alphabetic characters in a string to lowercase. */\n    toLowerCase(): string;\n\n    /** Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. */\n    toLocaleLowerCase(): string;\n\n    /** Converts all the alphabetic characters in a string to uppercase. */\n    toUpperCase(): string;\n\n    /** Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale. */\n    toLocaleUpperCase(): string;\n\n    /** Removes the leading and trailing white space and line terminator characters from a string. */\n    trim(): string;\n\n    /** Returns the length of a String object. */\n    readonly length: number;\n\n    // IE extensions\n    /**\n      * Gets a substring beginning at the specified location and having the specified length.\n      * @param from The starting position of the desired substring. The index of the first character in the string is zero.\n      * @param length The number of characters to include in the returned substring.\n      */\n    substr(from: number, length?: number): string;\n\n    /** Returns the primitive value of the specified object. */\n    valueOf(): string;\n\n    readonly [index: number]: string;\n}\n\ninterface StringConstructor {\n    new(value?: any): String;\n    (value?: any): string;\n    readonly prototype: String;\n    fromCharCode(...codes: number[]): string;\n}\n\n/**\n  * Allows manipulation and formatting of text strings and determination and location of substrings within strings.\n  */\ndeclare var String: StringConstructor;\n\ninterface Boolean {\n    /** Returns the primitive value of the specified object. */\n    valueOf(): boolean;\n}\n\ninterface BooleanConstructor {\n    new(value?: any): Boolean;\n    <T>(value?: T): boolean;\n    readonly prototype: Boolean;\n}\n\ndeclare var Boolean: BooleanConstructor;\n\ninterface Number {\n    /**\n      * Returns a string representation of an object.\n      * @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers.\n      */\n    toString(radix?: number): string;\n\n    /**\n      * Returns a string representing a number in fixed-point notation.\n      * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.\n      */\n    toFixed(fractionDigits?: number): string;\n\n    /**\n      * Returns a string containing a number represented in exponential notation.\n      * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.\n      */\n    toExponential(fractionDigits?: number): string;\n\n    /**\n      * Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.\n      * @param precision Number of significant digits. Must be in the range 1 - 21, inclusive.\n      */\n    toPrecision(precision?: number): string;\n\n    /** Returns the primitive value of the specified object. */\n    valueOf(): number;\n}\n\ninterface NumberConstructor {\n    new(value?: any): Number;\n    (value?: any): number;\n    readonly prototype: Number;\n\n    /** The largest number that can be represented in JavaScript. Equal to approximately 1.79E+308. */\n    readonly MAX_VALUE: number;\n\n    /** The closest number to zero that can be represented in JavaScript. Equal to approximately 5.00E-324. */\n    readonly MIN_VALUE: number;\n\n    /**\n      * A value that is not a number.\n      * In equality comparisons, NaN does not equal any value, including itself. To test whether a value is equivalent to NaN, use the isNaN function.\n      */\n    readonly NaN: number;\n\n    /**\n      * A value that is less than the largest negative number that can be represented in JavaScript.\n      * JavaScript displays NEGATIVE_INFINITY values as -infinity.\n      */\n    readonly NEGATIVE_INFINITY: number;\n\n    /**\n      * A value greater than the largest number that can be represented in JavaScript.\n      * JavaScript displays POSITIVE_INFINITY values as infinity.\n      */\n    readonly POSITIVE_INFINITY: number;\n}\n\n/** An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers. */\ndeclare var Number: NumberConstructor;\n\ninterface TemplateStringsArray extends ReadonlyArray<string> {\n    readonly raw: ReadonlyArray<string>;\n}\n\n/**\n * The type of `import.meta`.\n *\n * If you need to declare that a given property exists on `import.meta`,\n * this type may be augmented via interface merging.\n */\ninterface ImportMeta {\n}\n\ninterface Math {\n    /** The mathematical constant e. This is Euler's number, the base of natural logarithms. */\n    readonly E: number;\n    /** The natural logarithm of 10. */\n    readonly LN10: number;\n    /** The natural logarithm of 2. */\n    readonly LN2: number;\n    /** The base-2 logarithm of e. */\n    readonly LOG2E: number;\n    /** The base-10 logarithm of e. */\n    readonly LOG10E: number;\n    /** Pi. This is the ratio of the circumference of a circle to its diameter. */\n    readonly PI: number;\n    /** The square root of 0.5, or, equivalently, one divided by the square root of 2. */\n    readonly SQRT1_2: number;\n    /** The square root of 2. */\n    readonly SQRT2: number;\n    /**\n      * Returns the absolute value of a number (the value without regard to whether it is positive or negative).\n      * For example, the absolute value of -5 is the same as the absolute value of 5.\n      * @param x A numeric expression for which the absolute value is needed.\n      */\n    abs(x: number): number;\n    /**\n      * Returns the arc cosine (or inverse cosine) of a number.\n      * @param x A numeric expression.\n      */\n    acos(x: number): number;\n    /**\n      * Returns the arcsine of a number.\n      * @param x A numeric expression.\n      */\n    asin(x: number): number;\n    /**\n      * Returns the arctangent of a number.\n      * @param x A numeric expression for which the arctangent is needed.\n      */\n    atan(x: number): number;\n    /**\n      * Returns the angle (in radians) from the X axis to a point.\n      * @param y A numeric expression representing the cartesian y-coordinate.\n      * @param x A numeric expression representing the cartesian x-coordinate.\n      */\n    atan2(y: number, x: number): number;\n    /**\n      * Returns the smallest integer greater than or equal to its numeric argument.\n      * @param x A numeric expression.\n      */\n    ceil(x: number): number;\n    /**\n      * Returns the cosine of a number.\n      * @param x A numeric expression that contains an angle measured in radians.\n      */\n    cos(x: number): number;\n    /**\n      * Returns e (the base of natural logarithms) raised to a power.\n      * @param x A numeric expression representing the power of e.\n      */\n    exp(x: number): number;\n    /**\n      * Returns the greatest integer less than or equal to its numeric argument.\n      * @param x A numeric expression.\n      */\n    floor(x: number): number;\n    /**\n      * Returns the natural logarithm (base e) of a number.\n      * @param x A numeric expression.\n      */\n    log(x: number): number;\n    /**\n      * Returns the larger of a set of supplied numeric expressions.\n      * @param values Numeric expressions to be evaluated.\n      */\n    max(...values: number[]): number;\n    /**\n      * Returns the smaller of a set of supplied numeric expressions.\n      * @param values Numeric expressions to be evaluated.\n      */\n    min(...values: number[]): number;\n    /**\n      * Returns the value of a base expression taken to a specified power.\n      * @param x The base value of the expression.\n      * @param y The exponent value of the expression.\n      */\n    pow(x: number, y: number): number;\n    /** Returns a pseudorandom number between 0 and 1. */\n    random(): number;\n    /**\n      * Returns a supplied numeric expression rounded to the nearest number.\n      * @param x The value to be rounded to the nearest number.\n      */\n    round(x: number): number;\n    /**\n      * Returns the sine of a number.\n      * @param x A numeric expression that contains an angle measured in radians.\n      */\n    sin(x: number): number;\n    /**\n      * Returns the square root of a number.\n      * @param x A numeric expression.\n      */\n    sqrt(x: number): number;\n    /**\n      * Returns the tangent of a number.\n      * @param x A numeric expression that contains an angle measured in radians.\n      */\n    tan(x: number): number;\n}\n/** An intrinsic object that provides basic mathematics functionality and constants. */\ndeclare var Math: Math;\n\n/** Enables basic storage and retrieval of dates and times. */\ninterface Date {\n    /** Returns a string representation of a date. The format of the string depends on the locale. */\n    toString(): string;\n    /** Returns a date as a string value. */\n    toDateString(): string;\n    /** Returns a time as a string value. */\n    toTimeString(): string;\n    /** Returns a value as a string value appropriate to the host environment's current locale. */\n    toLocaleString(): string;\n    /** Returns a date as a string value appropriate to the host environment's current locale. */\n    toLocaleDateString(): string;\n    /** Returns a time as a string value appropriate to the host environment's current locale. */\n    toLocaleTimeString(): string;\n    /** Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. */\n    valueOf(): number;\n    /** Gets the time value in milliseconds. */\n    getTime(): number;\n    /** Gets the year, using local time. */\n    getFullYear(): number;\n    /** Gets the year using Universal Coordinated Time (UTC). */\n    getUTCFullYear(): number;\n    /** Gets the month, using local time. */\n    getMonth(): number;\n    /** Gets the month of a Date object using Universal Coordinated Time (UTC). */\n    getUTCMonth(): number;\n    /** Gets the day-of-the-month, using local time. */\n    getDate(): number;\n    /** Gets the day-of-the-month, using Universal Coordinated Time (UTC). */\n    getUTCDate(): number;\n    /** Gets the day of the week, using local time. */\n    getDay(): number;\n    /** Gets the day of the week using Universal Coordinated Time (UTC). */\n    getUTCDay(): number;\n    /** Gets the hours in a date, using local time. */\n    getHours(): number;\n    /** Gets the hours value in a Date object using Universal Coordinated Time (UTC). */\n    getUTCHours(): number;\n    /** Gets the minutes of a Date object, using local time. */\n    getMinutes(): number;\n    /** Gets the minutes of a Date object using Universal Coordinated Time (UTC). */\n    getUTCMinutes(): number;\n    /** Gets the seconds of a Date object, using local time. */\n    getSeconds(): number;\n    /** Gets the seconds of a Date object using Universal Coordinated Time (UTC). */\n    getUTCSeconds(): number;\n    /** Gets the milliseconds of a Date, using local time. */\n    getMilliseconds(): number;\n    /** Gets the milliseconds of a Date object using Universal Coordinated Time (UTC). */\n    getUTCMilliseconds(): number;\n    /** Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). */\n    getTimezoneOffset(): number;\n    /**\n      * Sets the date and time value in the Date object.\n      * @param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT.\n      */\n    setTime(time: number): number;\n    /**\n      * Sets the milliseconds value in the Date object using local time.\n      * @param ms A numeric value equal to the millisecond value.\n      */\n    setMilliseconds(ms: number): number;\n    /**\n      * Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC).\n      * @param ms A numeric value equal to the millisecond value.\n      */\n    setUTCMilliseconds(ms: number): number;\n\n    /**\n      * Sets the seconds value in the Date object using local time.\n      * @param sec A numeric value equal to the seconds value.\n      * @param ms A numeric value equal to the milliseconds value.\n      */\n    setSeconds(sec: number, ms?: number): number;\n    /**\n      * Sets the seconds value in the Date object using Universal Coordinated Time (UTC).\n      * @param sec A numeric value equal to the seconds value.\n      * @param ms A numeric value equal to the milliseconds value.\n      */\n    setUTCSeconds(sec: number, ms?: number): number;\n    /**\n      * Sets the minutes value in the Date object using local time.\n      * @param min A numeric value equal to the minutes value.\n      * @param sec A numeric value equal to the seconds value.\n      * @param ms A numeric value equal to the milliseconds value.\n      */\n    setMinutes(min: number, sec?: number, ms?: number): number;\n    /**\n      * Sets the minutes value in the Date object using Universal Coordinated Time (UTC).\n      * @param min A numeric value equal to the minutes value.\n      * @param sec A numeric value equal to the seconds value.\n      * @param ms A numeric value equal to the milliseconds value.\n      */\n    setUTCMinutes(min: number, sec?: number, ms?: number): number;\n    /**\n      * Sets the hour value in the Date object using local time.\n      * @param hours A numeric value equal to the hours value.\n      * @param min A numeric value equal to the minutes value.\n      * @param sec A numeric value equal to the seconds value.\n      * @param ms A numeric value equal to the milliseconds value.\n      */\n    setHours(hours: number, min?: number, sec?: number, ms?: number): number;\n    /**\n      * Sets the hours value in the Date object using Universal Coordinated Time (UTC).\n      * @param hours A numeric value equal to the hours value.\n      * @param min A numeric value equal to the minutes value.\n      * @param sec A numeric value equal to the seconds value.\n      * @param ms A numeric value equal to the milliseconds value.\n      */\n    setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number;\n    /**\n      * Sets the numeric day-of-the-month value of the Date object using local time.\n      * @param date A numeric value equal to the day of the month.\n      */\n    setDate(date: number): number;\n    /**\n      * Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC).\n      * @param date A numeric value equal to the day of the month.\n      */\n    setUTCDate(date: number): number;\n    /**\n      * Sets the month value in the Date object using local time.\n      * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.\n      * @param date A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used.\n      */\n    setMonth(month: number, date?: number): number;\n    /**\n      * Sets the month value in the Date object using Universal Coordinated Time (UTC).\n      * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.\n      * @param date A numeric value representing the day of the month. If it is not supplied, the value from a call to the getUTCDate method is used.\n      */\n    setUTCMonth(month: number, date?: number): number;\n    /**\n      * Sets the year of the Date object using local time.\n      * @param year A numeric value for the year.\n      * @param month A zero-based numeric value for the month (0 for January, 11 for December). Must be specified if numDate is specified.\n      * @param date A numeric value equal for the day of the month.\n      */\n    setFullYear(year: number, month?: number, date?: number): number;\n    /**\n      * Sets the year value in the Date object using Universal Coordinated Time (UTC).\n      * @param year A numeric value equal to the year.\n      * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. Must be supplied if numDate is supplied.\n      * @param date A numeric value equal to the day of the month.\n      */\n    setUTCFullYear(year: number, month?: number, date?: number): number;\n    /** Returns a date converted to a string using Universal Coordinated Time (UTC). */\n    toUTCString(): string;\n    /** Returns a date as a string value in ISO format. */\n    toISOString(): string;\n    /** Used by the JSON.stringify method to enable the transformation of an object's data for JavaScript Object Notation (JSON) serialization. */\n    toJSON(key?: any): string;\n}\n\ninterface DateConstructor {\n    new(): Date;\n    new(value: number | string): Date;\n    new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;\n    (): string;\n    readonly prototype: Date;\n    /**\n      * Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.\n      * @param s A date string\n      */\n    parse(s: string): number;\n    /**\n      * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date.\n      * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.\n      * @param month The month as an number between 0 and 11 (January to December).\n      * @param date The date as an number between 1 and 31.\n      * @param hours Must be supplied if minutes is supplied. An number from 0 to 23 (midnight to 11pm) that specifies the hour.\n      * @param minutes Must be supplied if seconds is supplied. An number from 0 to 59 that specifies the minutes.\n      * @param seconds Must be supplied if milliseconds is supplied. An number from 0 to 59 that specifies the seconds.\n      * @param ms An number from 0 to 999 that specifies the milliseconds.\n      */\n    UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;\n    now(): number;\n}\n\ndeclare var Date: DateConstructor;\n\ninterface RegExpMatchArray extends Array<string> {\n    index?: number;\n    input?: string;\n}\n\ninterface RegExpExecArray extends Array<string> {\n    index: number;\n    input: string;\n}\n\ninterface RegExp {\n    /**\n      * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search.\n      * @param string The String object or string literal on which to perform the search.\n      */\n    exec(string: string): RegExpExecArray | null;\n\n    /**\n      * Returns a Boolean value that indicates whether or not a pattern exists in a searched string.\n      * @param string String on which to perform the search.\n      */\n    test(string: string): boolean;\n\n    /** Returns a copy of the text of the regular expression pattern. Read-only. The regExp argument is a Regular expression object. It can be a variable name or a literal. */\n    readonly source: string;\n\n    /** Returns a Boolean value indicating the state of the global flag (g) used with a regular expression. Default is false. Read-only. */\n    readonly global: boolean;\n\n    /** Returns a Boolean value indicating the state of the ignoreCase flag (i) used with a regular expression. Default is false. Read-only. */\n    readonly ignoreCase: boolean;\n\n    /** Returns a Boolean value indicating the state of the multiline flag (m) used with a regular expression. Default is false. Read-only. */\n    readonly multiline: boolean;\n\n    lastIndex: number;\n\n    // Non-standard extensions\n    compile(): this;\n}\n\ninterface RegExpConstructor {\n    new(pattern: RegExp | string): RegExp;\n    new(pattern: string, flags?: string): RegExp;\n    (pattern: RegExp | string): RegExp;\n    (pattern: string, flags?: string): RegExp;\n    readonly prototype: RegExp;\n\n    // Non-standard extensions\n    $1: string;\n    $2: string;\n    $3: string;\n    $4: string;\n    $5: string;\n    $6: string;\n    $7: string;\n    $8: string;\n    $9: string;\n    lastMatch: string;\n}\n\ndeclare var RegExp: RegExpConstructor;\n\ninterface Error {\n    name: string;\n    message: string;\n    stack?: string;\n}\n\ninterface ErrorConstructor {\n    new(message?: string): Error;\n    (message?: string): Error;\n    readonly prototype: Error;\n}\n\ndeclare var Error: ErrorConstructor;\n\ninterface EvalError extends Error {\n}\n\ninterface EvalErrorConstructor {\n    new(message?: string): EvalError;\n    (message?: string): EvalError;\n    readonly prototype: EvalError;\n}\n\ndeclare var EvalError: EvalErrorConstructor;\n\ninterface RangeError extends Error {\n}\n\ninterface RangeErrorConstructor {\n    new(message?: string): RangeError;\n    (message?: string): RangeError;\n    readonly prototype: RangeError;\n}\n\ndeclare var RangeError: RangeErrorConstructor;\n\ninterface ReferenceError extends Error {\n}\n\ninterface ReferenceErrorConstructor {\n    new(message?: string): ReferenceError;\n    (message?: string): ReferenceError;\n    readonly prototype: ReferenceError;\n}\n\ndeclare var ReferenceError: ReferenceErrorConstructor;\n\ninterface SyntaxError extends Error {\n}\n\ninterface SyntaxErrorConstructor {\n    new(message?: string): SyntaxError;\n    (message?: string): SyntaxError;\n    readonly prototype: SyntaxError;\n}\n\ndeclare var SyntaxError: SyntaxErrorConstructor;\n\ninterface TypeError extends Error {\n}\n\ninterface TypeErrorConstructor {\n    new(message?: string): TypeError;\n    (message?: string): TypeError;\n    readonly prototype: TypeError;\n}\n\ndeclare var TypeError: TypeErrorConstructor;\n\ninterface URIError extends Error {\n}\n\ninterface URIErrorConstructor {\n    new(message?: string): URIError;\n    (message?: string): URIError;\n    readonly prototype: URIError;\n}\n\ndeclare var URIError: URIErrorConstructor;\n\ninterface JSON {\n    /**\n      * Converts a JavaScript Object Notation (JSON) string into an object.\n      * @param text A valid JSON string.\n      * @param reviver A function that transforms the results. This function is called for each member of the object.\n      * If a member contains nested objects, the nested objects are transformed before the parent object is.\n      */\n    parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;\n    /**\n      * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.\n      * @param value A JavaScript value, usually an object or array, to be converted.\n      * @param replacer A function that transforms the results.\n      * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\n      */\n    stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;\n    /**\n      * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.\n      * @param value A JavaScript value, usually an object or array, to be converted.\n      * @param replacer An array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified.\n      * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\n      */\n    stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string;\n}\n\n/**\n  * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.\n  */\ndeclare var JSON: JSON;\n\n\n/////////////////////////////\n/// ECMAScript Array API (specially handled by compiler)\n/////////////////////////////\n\ninterface ReadonlyArray<T> {\n    /**\n      * Gets the length of the array. This is a number one higher than the highest element defined in an array.\n      */\n    readonly length: number;\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n    /**\n      * Returns a string representation of an array. The elements are converted to string using their toLocalString methods.\n      */\n    toLocaleString(): string;\n    /**\n      * Combines two or more arrays.\n      * @param items Additional items to add to the end of array1.\n      */\n    concat(...items: ConcatArray<T>[]): T[];\n    /**\n      * Combines two or more arrays.\n      * @param items Additional items to add to the end of array1.\n      */\n    concat(...items: (T | ConcatArray<T>)[]): T[];\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): T[];\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\n      */\n    indexOf(searchElement: T, fromIndex?: number): number;\n    /**\n      * Returns the index of the last occurrence of a specified value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.\n      */\n    lastIndexOf(searchElement: T, fromIndex?: number): number;\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => unknown, thisArg?: any): boolean;\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => unknown, thisArg?: any): boolean;\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => void, thisArg?: any): void;\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    map<U>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => U, thisArg?: any): U[];\n    /**\n     * Returns the elements of an array that meet the condition specified in a callback function.\n     * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n     */\n    filter<S extends T>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => value is S, thisArg?: any): S[];\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => unknown, thisArg?: any): T[];\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T): T;\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue: T): T;\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => U, initialValue: U): U;\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T): T;\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue: T): T;\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => U, initialValue: U): U;\n\n    readonly [n: number]: T;\n}\n\ninterface ConcatArray<T> {\n    readonly length: number;\n    readonly [n: number]: T;\n    join(separator?: string): string;\n    slice(start?: number, end?: number): T[];\n}\n\ninterface Array<T> {\n    /**\n      * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.\n      */\n    length: number;\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n    /**\n      * Returns a string representation of an array. The elements are converted to string using their toLocalString methods.\n      */\n    toLocaleString(): string;\n    /**\n      * Removes the last element from an array and returns it.\n      */\n    pop(): T | undefined;\n    /**\n      * Appends new elements to an array, and returns the new length of the array.\n      * @param items New elements of the Array.\n      */\n    push(...items: T[]): number;\n    /**\n      * Combines two or more arrays.\n      * @param items Additional items to add to the end of array1.\n      */\n    concat(...items: ConcatArray<T>[]): T[];\n    /**\n      * Combines two or more arrays.\n      * @param items Additional items to add to the end of array1.\n      */\n    concat(...items: (T | ConcatArray<T>)[]): T[];\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): T[];\n    /**\n      * Removes the first element from an array and returns it.\n      */\n    shift(): T | undefined;\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): T[];\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: T, b: T) => number): this;\n    /**\n      * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.\n      * @param start The zero-based location in the array from which to start removing elements.\n      * @param deleteCount The number of elements to remove.\n      */\n    splice(start: number, deleteCount?: number): T[];\n    /**\n      * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.\n      * @param start The zero-based location in the array from which to start removing elements.\n      * @param deleteCount The number of elements to remove.\n      * @param items Elements to insert into the array in place of the deleted elements.\n      */\n    splice(start: number, deleteCount: number, ...items: T[]): T[];\n    /**\n      * Inserts new elements at the start of an array.\n      * @param items  Elements to insert at the start of the Array.\n      */\n    unshift(...items: T[]): number;\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\n      */\n    indexOf(searchElement: T, fromIndex?: number): number;\n    /**\n      * Returns the index of the last occurrence of a specified value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.\n      */\n    lastIndexOf(searchElement: T, fromIndex?: number): number;\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];\n    /**\n     * Returns the elements of an array that meet the condition specified in a callback function.\n     * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n     */\n    filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;\n\n    [n: number]: T;\n}\n\ninterface ArrayConstructor {\n    new(arrayLength?: number): any[];\n    new <T>(arrayLength: number): T[];\n    new <T>(...items: T[]): T[];\n    (arrayLength?: number): any[];\n    <T>(arrayLength: number): T[];\n    <T>(...items: T[]): T[];\n    isArray(arg: any): arg is Array<any>;\n    readonly prototype: Array<any>;\n}\n\ndeclare var Array: ArrayConstructor;\n\ninterface TypedPropertyDescriptor<T> {\n    enumerable?: boolean;\n    configurable?: boolean;\n    writable?: boolean;\n    value?: T;\n    get?: () => T;\n    set?: (value: T) => void;\n}\n\ndeclare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;\ndeclare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;\ndeclare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;\ndeclare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;\n\ndeclare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;\n\ninterface PromiseLike<T> {\n    /**\n     * Attaches callbacks for the resolution and/or rejection of the Promise.\n     * @param onfulfilled The callback to execute when the Promise is resolved.\n     * @param onrejected The callback to execute when the Promise is rejected.\n     * @returns A Promise for the completion of which ever callback is executed.\n     */\n    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;\n}\n\n/**\n * Represents the completion of an asynchronous operation\n */\ninterface Promise<T> {\n    /**\n     * Attaches callbacks for the resolution and/or rejection of the Promise.\n     * @param onfulfilled The callback to execute when the Promise is resolved.\n     * @param onrejected The callback to execute when the Promise is rejected.\n     * @returns A Promise for the completion of which ever callback is executed.\n     */\n    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;\n\n    /**\n     * Attaches a callback for only the rejection of the Promise.\n     * @param onrejected The callback to execute when the Promise is rejected.\n     * @returns A Promise for the completion of the callback.\n     */\n    catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;\n}\n\ninterface ArrayLike<T> {\n    readonly length: number;\n    readonly [n: number]: T;\n}\n\n/**\n * Make all properties in T optional\n */\ntype Partial<T> = {\n    [P in keyof T]?: T[P];\n};\n\n/**\n * Make all properties in T required\n */\ntype Required<T> = {\n    [P in keyof T]-?: T[P];\n};\n\n/**\n * Make all properties in T readonly\n */\ntype Readonly<T> = {\n    readonly [P in keyof T]: T[P];\n};\n\n/**\n * From T, pick a set of properties whose keys are in the union K\n */\ntype Pick<T, K extends keyof T> = {\n    [P in K]: T[P];\n};\n\n/**\n * Construct a type with a set of properties K of type T\n */\ntype Record<K extends keyof any, T> = {\n    [P in K]: T;\n};\n\n/**\n * Exclude from T those types that are assignable to U\n */\ntype Exclude<T, U> = T extends U ? never : T;\n\n/**\n * Extract from T those types that are assignable to U\n */\ntype Extract<T, U> = T extends U ? T : never;\n\n/**\n * Construct a type with the properties of T except for those in type K.\n */\ntype Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;\n\n/**\n * Exclude null and undefined from T\n */\ntype NonNullable<T> = T extends null | undefined ? never : T;\n\n/**\n * Obtain the parameters of a function type in a tuple\n */\ntype Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;\n\n/**\n * Obtain the parameters of a constructor function type in a tuple\n */\ntype ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;\n\n/**\n * Obtain the return type of a function type\n */\ntype ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;\n\n/**\n * Obtain the return type of a constructor function type\n */\ntype InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;\n\n/**\n * Marker for contextual 'this' type\n */\ninterface ThisType<T> { }\n\n/**\n  * Represents a raw buffer of binary data, which is used to store data for the\n  * different typed arrays. ArrayBuffers cannot be read from or written to directly,\n  * but can be passed to a typed array or DataView Object to interpret the raw\n  * buffer as needed.\n  */\ninterface ArrayBuffer {\n    /**\n      * Read-only. The length of the ArrayBuffer (in bytes).\n      */\n    readonly byteLength: number;\n\n    /**\n      * Returns a section of an ArrayBuffer.\n      */\n    slice(begin: number, end?: number): ArrayBuffer;\n}\n\n/**\n * Allowed ArrayBuffer types for the buffer of an ArrayBufferView and related Typed Arrays.\n */\ninterface ArrayBufferTypes {\n    ArrayBuffer: ArrayBuffer;\n}\ntype ArrayBufferLike = ArrayBufferTypes[keyof ArrayBufferTypes];\n\ninterface ArrayBufferConstructor {\n    readonly prototype: ArrayBuffer;\n    new(byteLength: number): ArrayBuffer;\n    isView(arg: any): arg is ArrayBufferView;\n}\ndeclare var ArrayBuffer: ArrayBufferConstructor;\n\ninterface ArrayBufferView {\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    byteOffset: number;\n}\n\ninterface DataView {\n    readonly buffer: ArrayBuffer;\n    readonly byteLength: number;\n    readonly byteOffset: number;\n    /**\n      * Gets the Float32 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getFloat32(byteOffset: number, littleEndian?: boolean): number;\n\n    /**\n      * Gets the Float64 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getFloat64(byteOffset: number, littleEndian?: boolean): number;\n\n    /**\n      * Gets the Int8 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getInt8(byteOffset: number): number;\n\n    /**\n      * Gets the Int16 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getInt16(byteOffset: number, littleEndian?: boolean): number;\n    /**\n      * Gets the Int32 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getInt32(byteOffset: number, littleEndian?: boolean): number;\n\n    /**\n      * Gets the Uint8 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getUint8(byteOffset: number): number;\n\n    /**\n      * Gets the Uint16 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getUint16(byteOffset: number, littleEndian?: boolean): number;\n\n    /**\n      * Gets the Uint32 value at the specified byte offset from the start of the view. There is\n      * no alignment constraint; multi-byte values may be fetched from any offset.\n      * @param byteOffset The place in the buffer at which the value should be retrieved.\n      */\n    getUint32(byteOffset: number, littleEndian?: boolean): number;\n\n    /**\n      * Stores an Float32 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      * @param littleEndian If false or undefined, a big-endian value should be written,\n      * otherwise a little-endian value should be written.\n      */\n    setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void;\n\n    /**\n      * Stores an Float64 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      * @param littleEndian If false or undefined, a big-endian value should be written,\n      * otherwise a little-endian value should be written.\n      */\n    setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void;\n\n    /**\n      * Stores an Int8 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      */\n    setInt8(byteOffset: number, value: number): void;\n\n    /**\n      * Stores an Int16 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      * @param littleEndian If false or undefined, a big-endian value should be written,\n      * otherwise a little-endian value should be written.\n      */\n    setInt16(byteOffset: number, value: number, littleEndian?: boolean): void;\n\n    /**\n      * Stores an Int32 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      * @param littleEndian If false or undefined, a big-endian value should be written,\n      * otherwise a little-endian value should be written.\n      */\n    setInt32(byteOffset: number, value: number, littleEndian?: boolean): void;\n\n    /**\n      * Stores an Uint8 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      */\n    setUint8(byteOffset: number, value: number): void;\n\n    /**\n      * Stores an Uint16 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      * @param littleEndian If false or undefined, a big-endian value should be written,\n      * otherwise a little-endian value should be written.\n      */\n    setUint16(byteOffset: number, value: number, littleEndian?: boolean): void;\n\n    /**\n      * Stores an Uint32 value at the specified byte offset from the start of the view.\n      * @param byteOffset The place in the buffer at which the value should be set.\n      * @param value The value to set.\n      * @param littleEndian If false or undefined, a big-endian value should be written,\n      * otherwise a little-endian value should be written.\n      */\n    setUint32(byteOffset: number, value: number, littleEndian?: boolean): void;\n}\n\ninterface DataViewConstructor {\n    new(buffer: ArrayBufferLike, byteOffset?: number, byteLength?: number): DataView;\n}\ndeclare var DataView: DataViewConstructor;\n\n/**\n  * A typed array of 8-bit integer values. The contents are initialized to 0. If the requested\n  * number of bytes could not be allocated an exception is raised.\n  */\ninterface Int8Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Int8Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Int8Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Int8Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Int8Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Int8Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Int8Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\ninterface Int8ArrayConstructor {\n    readonly prototype: Int8Array;\n    new(length: number): Int8Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int8Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int8Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Int8Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Int8Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int8Array;\n\n\n}\ndeclare var Int8Array: Int8ArrayConstructor;\n\n/**\n  * A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the\n  * requested number of bytes could not be allocated an exception is raised.\n  */\ninterface Uint8Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Uint8Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Uint8Array) => any, thisArg?: any): Uint8Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Uint8Array) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Uint8Array) => number, thisArg?: any): Uint8Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Uint8Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Uint8Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Uint8Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Uint8Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Uint8ArrayConstructor {\n    readonly prototype: Uint8Array;\n    new(length: number): Uint8Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint8Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint8Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Uint8Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Uint8Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint8Array;\n\n}\ndeclare var Uint8Array: Uint8ArrayConstructor;\n\n/**\n  * A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.\n  * If the requested number of bytes could not be allocated an exception is raised.\n  */\ninterface Uint8ClampedArray {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => any, thisArg?: any): Uint8ClampedArray;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Uint8ClampedArray) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Uint8ClampedArray) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => number, thisArg?: any): Uint8ClampedArray;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Uint8ClampedArray;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Uint8ClampedArray;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Uint8ClampedArray view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Uint8ClampedArray;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Uint8ClampedArrayConstructor {\n    readonly prototype: Uint8ClampedArray;\n    new(length: number): Uint8ClampedArray;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint8ClampedArray;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint8ClampedArray;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Uint8ClampedArray;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Uint8ClampedArray;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint8ClampedArray;\n}\ndeclare var Uint8ClampedArray: Uint8ClampedArrayConstructor;\n\n/**\n  * A typed array of 16-bit signed integer values. The contents are initialized to 0. If the\n  * requested number of bytes could not be allocated an exception is raised.\n  */\ninterface Int16Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Int16Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Int16Array) => any, thisArg?: any): Int16Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Int16Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Int16Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Int16Array) => void, thisArg?: any): void;\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Int16Array) => number, thisArg?: any): Int16Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Int16Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Int16Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Int16Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Int16Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Int16Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Int16ArrayConstructor {\n    readonly prototype: Int16Array;\n    new(length: number): Int16Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int16Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int16Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Int16Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Int16Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int16Array;\n\n\n}\ndeclare var Int16Array: Int16ArrayConstructor;\n\n/**\n  * A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the\n  * requested number of bytes could not be allocated an exception is raised.\n  */\ninterface Uint16Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Uint16Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Uint16Array) => any, thisArg?: any): Uint16Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Uint16Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Uint16Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Uint16Array) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Uint16Array) => number, thisArg?: any): Uint16Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint16Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint16Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Uint16Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Uint16Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Uint16Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Uint16Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Uint16Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Uint16ArrayConstructor {\n    readonly prototype: Uint16Array;\n    new(length: number): Uint16Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint16Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint16Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Uint16Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Uint16Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint16Array;\n\n\n}\ndeclare var Uint16Array: Uint16ArrayConstructor;\n/**\n  * A typed array of 32-bit signed integer values. The contents are initialized to 0. If the\n  * requested number of bytes could not be allocated an exception is raised.\n  */\ninterface Int32Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Int32Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Int32Array) => any, thisArg?: any): Int32Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Int32Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Int32Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Int32Array) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Int32Array) => number, thisArg?: any): Int32Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Int32Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Int32Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Int32Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Int32Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Int32Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Int32ArrayConstructor {\n    readonly prototype: Int32Array;\n    new(length: number): Int32Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int32Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int32Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Int32Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Int32Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int32Array;\n\n}\ndeclare var Int32Array: Int32ArrayConstructor;\n\n/**\n  * A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the\n  * requested number of bytes could not be allocated an exception is raised.\n  */\ninterface Uint32Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Uint32Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Uint32Array) => any, thisArg?: any): Uint32Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Uint32Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Uint32Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Uint32Array) => void, thisArg?: any): void;\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Uint32Array) => number, thisArg?: any): Uint32Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint32Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint32Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Uint32Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Uint32Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Uint32Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Uint32Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Uint32Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Uint32ArrayConstructor {\n    readonly prototype: Uint32Array;\n    new(length: number): Uint32Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint32Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint32Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Uint32Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Uint32Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint32Array;\n\n}\ndeclare var Uint32Array: Uint32ArrayConstructor;\n\n/**\n  * A typed array of 32-bit float values. The contents are initialized to 0. If the requested number\n  * of bytes could not be allocated an exception is raised.\n  */\ninterface Float32Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Float32Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Float32Array) => any, thisArg?: any): Float32Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Float32Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Float32Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Float32Array) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Float32Array) => number, thisArg?: any): Float32Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Float32Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Float32Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Float32Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Float32Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Float32Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Float32ArrayConstructor {\n    readonly prototype: Float32Array;\n    new(length: number): Float32Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Float32Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Float32Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Float32Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Float32Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Float32Array;\n\n\n}\ndeclare var Float32Array: Float32ArrayConstructor;\n\n/**\n  * A typed array of 64-bit float values. The contents are initialized to 0. If the requested\n  * number of bytes could not be allocated an exception is raised.\n  */\ninterface Float64Array {\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * The ArrayBuffer instance referenced by the array.\n      */\n    readonly buffer: ArrayBufferLike;\n\n    /**\n      * The length in bytes of the array.\n      */\n    readonly byteLength: number;\n\n    /**\n      * The offset in bytes of the array.\n      */\n    readonly byteOffset: number;\n\n    /**\n      * Returns the this object after copying a section of the array identified by start and end\n      * to the same array starting at position target\n      * @param target If target is negative, it is treated as length+target where length is the\n      * length of the array.\n      * @param start If start is negative, it is treated as length+start. If end is negative, it\n      * is treated as length+end.\n      * @param end If not specified, length of the this object is used as its default value.\n      */\n    copyWithin(target: number, start: number, end?: number): this;\n\n    /**\n      * Determines whether all the members of an array satisfy the specified test.\n      * @param callbackfn A function that accepts up to three arguments. The every method calls\n      * the callbackfn function for each element in array1 until the callbackfn returns false,\n      * or until the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    every(callbackfn: (value: number, index: number, array: Float64Array) => boolean, thisArg?: any): boolean;\n\n    /**\n        * Returns the this object after filling the section identified by start and end with value\n        * @param value value to fill array section with\n        * @param start index to start filling the array at. If start is negative, it is treated as\n        * length+start where length is the length of the array.\n        * @param end index to stop filling the array at. If end is negative, it is treated as\n        * length+end.\n        */\n    fill(value: number, start?: number, end?: number): this;\n\n    /**\n      * Returns the elements of an array that meet the condition specified in a callback function.\n      * @param callbackfn A function that accepts up to three arguments. The filter method calls\n      * the callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    filter(callbackfn: (value: number, index: number, array: Float64Array) => any, thisArg?: any): Float64Array;\n\n    /**\n      * Returns the value of the first element in the array where predicate is true, and undefined\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found, find\n      * immediately returns that element value. Otherwise, find returns undefined.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    find(predicate: (value: number, index: number, obj: Float64Array) => boolean, thisArg?: any): number | undefined;\n\n    /**\n      * Returns the index of the first element in the array where predicate is true, and -1\n      * otherwise.\n      * @param predicate find calls predicate once for each element of the array, in ascending\n      * order, until it finds one where predicate returns true. If such an element is found,\n      * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\n      * @param thisArg If provided, it will be used as the this value for each invocation of\n      * predicate. If it is not provided, undefined is used instead.\n      */\n    findIndex(predicate: (value: number, index: number, obj: Float64Array) => boolean, thisArg?: any): number;\n\n    /**\n      * Performs the specified action for each element in an array.\n      * @param callbackfn  A function that accepts up to three arguments. forEach calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    forEach(callbackfn: (value: number, index: number, array: Float64Array) => void, thisArg?: any): void;\n\n    /**\n      * Returns the index of the first occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      *  search starts at index 0.\n      */\n    indexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * Adds all the elements of an array separated by the specified separator string.\n      * @param separator A string used to separate one element of an array from the next in the\n      * resulting String. If omitted, the array elements are separated with a comma.\n      */\n    join(separator?: string): string;\n\n    /**\n      * Returns the index of the last occurrence of a value in an array.\n      * @param searchElement The value to locate in the array.\n      * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\n      * search starts at index 0.\n      */\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\n\n    /**\n      * The length of the array.\n      */\n    readonly length: number;\n\n    /**\n      * Calls a defined callback function on each element of an array, and returns an array that\n      * contains the results.\n      * @param callbackfn A function that accepts up to three arguments. The map method calls the\n      * callbackfn function one time for each element in the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    map(callbackfn: (value: number, index: number, array: Float64Array) => number, thisArg?: any): Float64Array;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number;\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array. The return value of\n      * the callback function is the accumulated result, and is provided as an argument in the next\n      * call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\n      * callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U, initialValue: U): U;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an\n      * argument instead of an array value.\n      */\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number;\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number;\n\n    /**\n      * Calls the specified callback function for all the elements in an array, in descending order.\n      * The return value of the callback function is the accumulated result, and is provided as an\n      * argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\n      * the callbackfn function one time for each element in the array.\n      * @param initialValue If initialValue is specified, it is used as the initial value to start\n      * the accumulation. The first call to the callbackfn function provides this value as an argument\n      * instead of an array value.\n      */\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U, initialValue: U): U;\n\n    /**\n      * Reverses the elements in an Array.\n      */\n    reverse(): Float64Array;\n\n    /**\n      * Sets a value or an array of values.\n      * @param array A typed or untyped array of values to set.\n      * @param offset The index in the current array at which the values are to be written.\n      */\n    set(array: ArrayLike<number>, offset?: number): void;\n\n    /**\n      * Returns a section of an array.\n      * @param start The beginning of the specified portion of the array.\n      * @param end The end of the specified portion of the array.\n      */\n    slice(start?: number, end?: number): Float64Array;\n\n    /**\n      * Determines whether the specified callback function returns true for any element of an array.\n      * @param callbackfn A function that accepts up to three arguments. The some method calls the\n      * callbackfn function for each element in array1 until the callbackfn returns true, or until\n      * the end of the array.\n      * @param thisArg An object to which the this keyword can refer in the callbackfn function.\n      * If thisArg is omitted, undefined is used as the this value.\n      */\n    some(callbackfn: (value: number, index: number, array: Float64Array) => boolean, thisArg?: any): boolean;\n\n    /**\n      * Sorts an array.\n      * @param compareFn The name of the function used to determine the order of the elements. If\n      * omitted, the elements are sorted in ascending, ASCII character order.\n      */\n    sort(compareFn?: (a: number, b: number) => number): this;\n\n    /**\n      * Gets a new Float64Array view of the ArrayBuffer store for this array, referencing the elements\n      * at begin, inclusive, up to end, exclusive.\n      * @param begin The index of the beginning of the array.\n      * @param end The index of the end of the array.\n      */\n    subarray(begin: number, end?: number): Float64Array;\n\n    /**\n      * Converts a number to a string by using the current locale.\n      */\n    toLocaleString(): string;\n\n    /**\n      * Returns a string representation of an array.\n      */\n    toString(): string;\n\n    [index: number]: number;\n}\n\ninterface Float64ArrayConstructor {\n    readonly prototype: Float64Array;\n    new(length: number): Float64Array;\n    new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Float64Array;\n    new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Float64Array;\n\n    /**\n      * The size in bytes of each element in the array.\n      */\n    readonly BYTES_PER_ELEMENT: number;\n\n    /**\n      * Returns a new array from a set of elements.\n      * @param items A set of elements to include in the new array object.\n      */\n    of(...items: number[]): Float64Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      */\n    from(arrayLike: ArrayLike<number>): Float64Array;\n\n    /**\n      * Creates an array from an array-like or iterable object.\n      * @param arrayLike An array-like or iterable object to convert to an array.\n      * @param mapfn A mapping function to call on every element of the array.\n      * @param thisArg Value of 'this' used to invoke the mapfn.\n      */\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Float64Array;\n\n}\ndeclare var Float64Array: Float64ArrayConstructor;\n\n/////////////////////////////\n/// ECMAScript Internationalization API\n/////////////////////////////\n\ndeclare namespace Intl {\n    interface CollatorOptions {\n        usage?: string;\n        localeMatcher?: string;\n        numeric?: boolean;\n        caseFirst?: string;\n        sensitivity?: string;\n        ignorePunctuation?: boolean;\n    }\n\n    interface ResolvedCollatorOptions {\n        locale: string;\n        usage: string;\n        sensitivity: string;\n        ignorePunctuation: boolean;\n        collation: string;\n        caseFirst: string;\n        numeric: boolean;\n    }\n\n    interface Collator {\n        compare(x: string, y: string): number;\n        resolvedOptions(): ResolvedCollatorOptions;\n    }\n    var Collator: {\n        new(locales?: string | string[], options?: CollatorOptions): Collator;\n        (locales?: string | string[], options?: CollatorOptions): Collator;\n        supportedLocalesOf(locales: string | string[], options?: CollatorOptions): string[];\n    };\n\n    interface NumberFormatOptions {\n        localeMatcher?: string;\n        style?: string;\n        currency?: string;\n        currencyDisplay?: string;\n        useGrouping?: boolean;\n        minimumIntegerDigits?: number;\n        minimumFractionDigits?: number;\n        maximumFractionDigits?: number;\n        minimumSignificantDigits?: number;\n        maximumSignificantDigits?: number;\n    }\n\n    interface ResolvedNumberFormatOptions {\n        locale: string;\n        numberingSystem: string;\n        style: string;\n        currency?: string;\n        currencyDisplay?: string;\n        minimumIntegerDigits: number;\n        minimumFractionDigits: number;\n        maximumFractionDigits: number;\n        minimumSignificantDigits?: number;\n        maximumSignificantDigits?: number;\n        useGrouping: boolean;\n    }\n\n    interface NumberFormat {\n        format(value: number): string;\n        resolvedOptions(): ResolvedNumberFormatOptions;\n    }\n    var NumberFormat: {\n        new(locales?: string | string[], options?: NumberFormatOptions): NumberFormat;\n        (locales?: string | string[], options?: NumberFormatOptions): NumberFormat;\n        supportedLocalesOf(locales: string | string[], options?: NumberFormatOptions): string[];\n    };\n\n    interface DateTimeFormatOptions {\n        localeMatcher?: string;\n        weekday?: string;\n        era?: string;\n        year?: string;\n        month?: string;\n        day?: string;\n        hour?: string;\n        minute?: string;\n        second?: string;\n        timeZoneName?: string;\n        formatMatcher?: string;\n        hour12?: boolean;\n        timeZone?: string;\n    }\n\n    interface ResolvedDateTimeFormatOptions {\n        locale: string;\n        calendar: string;\n        numberingSystem: string;\n        timeZone: string;\n        hour12?: boolean;\n        weekday?: string;\n        era?: string;\n        year?: string;\n        month?: string;\n        day?: string;\n        hour?: string;\n        minute?: string;\n        second?: string;\n        timeZoneName?: string;\n    }\n\n    interface DateTimeFormat {\n        format(date?: Date | number): string;\n        resolvedOptions(): ResolvedDateTimeFormatOptions;\n    }\n    var DateTimeFormat: {\n        new(locales?: string | string[], options?: DateTimeFormatOptions): DateTimeFormat;\n        (locales?: string | string[], options?: DateTimeFormatOptions): DateTimeFormat;\n        supportedLocalesOf(locales: string | string[], options?: DateTimeFormatOptions): string[];\n    };\n}\n\ninterface String {\n    /**\n      * Determines whether two strings are equivalent in the current or specified locale.\n      * @param that String to compare to target string\n      * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details.\n      * @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details.\n      */\n    localeCompare(that: string, locales?: string | string[], options?: Intl.CollatorOptions): number;\n}\n\ninterface Number {\n    /**\n      * Converts a number to a string by using the current or specified locale.\n      * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\n      * @param options An object that contains one or more properties that specify comparison options.\n      */\n    toLocaleString(locales?: string | string[], options?: Intl.NumberFormatOptions): string;\n}\n\ninterface Date {\n    /**\n      * Converts a date and time to a string by using the current or specified locale.\n      * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\n      * @param options An object that contains one or more properties that specify comparison options.\n      */\n    toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;\n    /**\n      * Converts a date to a string by using the current or specified locale.\n      * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\n      * @param options An object that contains one or more properties that specify comparison options.\n      */\n    toLocaleDateString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;\n\n    /**\n      * Converts a time to a string by using the current or specified locale.\n      * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\n      * @param options An object that contains one or more properties that specify comparison options.\n      */\n    toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;\n}"
  },
  {
    "path": "webview/src/style.scss",
    "content": "@import \"~normalize.css\";\n@import \"~@blueprintjs/core/lib/css/blueprint.css\";\n@import \"~@blueprintjs/icons/lib/css/blueprint-icons.css\";\n@import \"~@hediet/visualization-bundle/style.scss\";\n\nhtml,\nbody,\n.react-root {\n\theight: 100%;\n}\n\nbody {\n\tfont-family: \"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif;\n\tmargin: 0px;\n\tpadding: 0px;\n\tborder: 0px;\n\n\tmargin: 0;\n\tpadding: 0;\n\n\tbackground-color: var(--vscode-editor-background);\n}\n\n.bp3-input,\n.bp3-button {\n\tborder-radius: 0;\n}\n\n.bp3-icon {\n\tsvg {\n\t\tcolor: lighten(black, 20);\n\t\twidth: 14px;\n\t}\n}\n\n.component-GUI {\n\t& > .part-Header {\n\t\tpadding: 6px 20px 6px 0;\n\t\tbackground-color: var(--vscode-sideBar-background);\n\n\t\t// border-top: solid 1px var(--vscode-button-background);\n\t\t// rgba(128, 128, 128, 0.15)\n\t}\n}\n\n.component-VisualizerHeader {\n\t.part-ExpandButton {\n\t\tbackground-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z'/%3E%3C/svg%3E\");\n\n\t\tbackground-position: 50%;\n\t\tbackground-position-x: 50%;\n\t\tbackground-position-y: center;\n\t\tbackground-repeat: no-repeat;\n\n\t\twidth: 15px;\n\t\tmargin: -6px 6px -6px 0px;\n\n\t\t&.expanded {\n\t\t\tbackground-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M11 10.07H5.344L11 4.414v5.656z'/%3E%3C/svg%3E\");\n\t\t}\n\n\t\t&:hover {\n\t\t\tbackground-color: var(--vscode-titleBar-activeBackground);\n\t\t}\n\t}\n}\n\n.component-VisualizerHeaderMain {\n\t.part-Icon {\n\t\tmargin-left: 4px;\n\t\tsvg {\n\t\t\tfill: var(--vscode-editor-foreground);\n\t\t}\n\t}\n}\n\n.component-NamedSelect {\n\t.part-Name {\n\t\tcolor: var(--vscode-editor-foreground);\n\t}\n}\n\n.component-Select {\n\t.part-Button {\n\t\tbackground-color: var(--vscode-button-background);\n\t\tcolor: var(--vscode-button-foreground);\n\t\tpadding: 4px 10px;\n\n\t\twidth: 100%;\n\n\t\tborder: none;\n\t\tcursor: pointer;\n\t\t&:hover,\n\t\t&:focus {\n\t\t\tbackground-color: var(--vscode-button-hoverBackground);\n\t\t}\n\t}\n\n\t.part-Items {\n\t\tbackground-color: var(--vscode-sideBar-background);\n\n\t\t.part-Item {\n\t\t\t//color: black;\n\t\t\tcolor: var(--vscode-editor-foreground);\n\t\t\tpadding: 12px 16px;\n\t\t\ttext-decoration: none;\n\t\t\tdisplay: block;\n\t\t\tcursor: pointer;\n\n\t\t\t&:hover {\n\t\t\t\tbackground-color: var(\n\t\t\t\t\t--vscode-titleBar-activeBackground\n\t\t\t\t); // #ddd;\n\t\t\t}\n\t\t}\n\t}\n\n\t.bp3-popover-wrapper {\n\t\twidth: 100%;\n\t}\n\n\t.bp3-popover-target {\n\t\twidth: 100%;\n\t}\n}\n\n.component-NoData {\n\twidth: 100%;\n\theight: 100%;\n\n\tsvg {\n\t\tfloat: left; // to prevent scrollbar.\n\t\t// I don't know why it works.\n\t\twidth: 100%;\n\t\theight: 100%;\n\n\t\tline {\n\t\t\tstroke: gray;\n\t\t}\n\t}\n\n\t.part-content-inner {\n\t\tbackground: var(--vscode-editor-background);\n\t\tcolor: var(--vscode-editor-foreground);\n\t}\n\n\tpre {\n\t\tmargin-top: 4px;\n\t\tmargin-bottom: 4px;\n\t}\n}\n\n.component-monaco-editor {\n\twidth: 100%;\n\tmin-width: 0;\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\tpadding: 2px;\n\tborder: 0.5px solid gray;\n\n\t.part-editor {\n\t\tmin-width: 0;\n\t\tmin-height: 0;\n\t\tflex: 1;\n\n\t\t.current-line {\n\t\t\tborder: none !important;\n\t\t}\n\t\t.selectionHighlight {\n\t\t\tbackground: transparent !important;\n\t\t}\n\t}\n}\n\n.svgViewer {\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.bp3-transition-container {\n\tz-index: 100000;\n}\n"
  },
  {
    "path": "webview/src/vscode-dark.scss",
    "content": ":root {\n    --background-color: #263238;\n    --color: #eeffff;\n    --font-family: -apple-system, BlinkMacSystemFont, \"Segoe WPC\", \"Segoe UI\", HelveticaNeue-Light, Ubuntu, \"Droid Sans\", sans-serif;\n    --font-size: 13px;\n    --font-weight: normal;\n    --link-active-color: #eeffff;\n    --link-color: #80cbc4;\n    --vscode-activityBar-background: #192227;\n    --vscode-activityBar-border: rgba(0, 0, 0, 0.38);\n    --vscode-activityBar-dropBackground: rgba(255, 255, 255, 0.12);\n    --vscode-activityBar-foreground: #eeffff;\n    --vscode-activityBar-inactiveForeground: rgba(238, 255, 255, 0.6);\n    --vscode-activityBarBadge-background: #80cbc4;\n    --vscode-activityBarBadge-foreground: #000000;\n    --vscode-badge-background: rgba(0, 0, 0, 0.19);\n    --vscode-badge-foreground: #546e7a;\n    --vscode-breadcrumb-activeSelectionForeground: #80cbc4;\n    --vscode-breadcrumb-background: #263238;\n    --vscode-breadcrumb-focusForeground: #eeffff;\n    --vscode-breadcrumb-foreground: #5f7a87;\n    --vscode-breadcrumbPicker-background: #192227;\n    --vscode-button-background: rgba(128, 203, 196, 0.13);\n    --vscode-button-foreground: #ffffff;\n    --vscode-button-hoverBackground: rgba(175, 222, 218, 0.13);\n    --vscode-debugExceptionWidget-background: #420b0d;\n    --vscode-debugExceptionWidget-border: #a31515;\n    --vscode-debugToolBar-background: #263238;\n    --vscode-descriptionForeground: rgba(204, 204, 204, 0.7);\n    --vscode-diffEditor-insertedTextBackground: rgba(195, 232, 141, 0.08);\n    --vscode-diffEditor-removedTextBackground: rgba(255, 83, 112, 0.13);\n    --vscode-dropdown-background: #263238;\n    --vscode-dropdown-border: rgba(255, 255, 255, 0.06);\n    --vscode-dropdown-foreground: #f0f0f0;\n    --vscode-editor-background: #263238;\n    --vscode-editor-findMatchBackground: #515c6a;\n    --vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);\n    --vscode-editor-findRangeHighlightBackground: rgba(58, 61, 65, 0.4);\n    --vscode-editor-focusedStackFrameHighlightBackground: rgba(122, 189, 122, 0.3);\n    --vscode-editor-font-family: -apple-system, BlinkMacSystemFont, \"Segoe WPC\", \"Segoe UI\", HelveticaNeue-Light, Ubuntu, \"Droid Sans\", sans-serif;\n    --vscode-editor-font-size: 13px;\n    --vscode-editor-font-weight: normal;\n    --vscode-editor-foreground: #eeffff;\n    --vscode-editor-hoverHighlightBackground: rgba(38, 79, 120, 0.25);\n    --vscode-editor-inactiveSelectionBackground: rgba(128, 203, 196, 0.06);\n    --vscode-editor-lineHighlightBackground: rgba(0, 0, 0, 0.31);\n    --vscode-editor-lineHighlightBorder: #282828;\n    --vscode-editor-rangeHighlightBackground: rgba(255, 255, 255, 0.04);\n    --vscode-editor-selectionBackground: rgba(128, 203, 196, 0.13);\n    --vscode-editor-selectionHighlightBackground: rgba(255, 204, 0, 0.13);\n    --vscode-editor-snippetFinalTabstopHighlightBorder: #525252;\n    --vscode-editor-snippetTabstopHighlightBackground: rgba(124, 124, 124, 0.3);\n    --vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 0, 0.2);\n    --vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.72);\n    --vscode-editor-wordHighlightStrongBackground: rgba(0, 73, 114, 0.72);\n    --vscode-editorActiveLineNumber-foreground: #c6c6c6;\n    --vscode-editorBracketMatch-background: #263238;\n    --vscode-editorBracketMatch-border: rgba(255, 204, 0, 0.31);\n    --vscode-editorCodeLens-foreground: #999999;\n    --vscode-editorCursor-foreground: #ffcc00;\n    --vscode-editorError-foreground: rgba(255, 83, 112, 0.44);\n    --vscode-editorGroup-border: rgba(0, 0, 0, 0.19);\n    --vscode-editorGroup-dropBackground: rgba(83, 89, 93, 0.5);\n    --vscode-editorGroupHeader-noTabsBackground: #263238;\n    --vscode-editorGroupHeader-tabsBackground: #263238;\n    --vscode-editorGutter-addedBackground: rgba(195, 232, 141, 0.38);\n    --vscode-editorGutter-background: #263238;\n    --vscode-editorGutter-commentRangeForeground: #c5c5c5;\n    --vscode-editorGutter-deletedBackground: rgba(255, 83, 112, 0.38);\n    --vscode-editorGutter-modifiedBackground: rgba(130, 170, 255, 0.38);\n    --vscode-editorHint-foreground: rgba(238, 238, 238, 0.7);\n    --vscode-editorHoverWidget-background: #263238;\n    --vscode-editorHoverWidget-border: rgba(255, 255, 255, 0.06);\n    --vscode-editorIndentGuide-activeBackground: #37474f;\n    --vscode-editorIndentGuide-background: rgba(55, 71, 79, 0.44);\n    --vscode-editorInfo-foreground: #008000;\n    --vscode-editorLineNumber-activeForeground: #5f7a87;\n    --vscode-editorLineNumber-foreground: #37474f;\n    --vscode-editorLink-activeForeground: #eeffff;\n    --vscode-editorMarkerNavigation-background: rgba(238, 255, 255, 0.02);\n    --vscode-editorMarkerNavigationError-background: rgba(255, 83, 112, 0.44);\n    --vscode-editorMarkerNavigationInfo-background: #008000;\n    --vscode-editorMarkerNavigationWarning-background: rgba(195, 232, 141, 0.44);\n    --vscode-editorOverviewRuler-addedForeground: rgba(0, 122, 204, 0.6);\n    --vscode-editorOverviewRuler-border: #263238;\n    --vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;\n    --vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);\n    --vscode-editorOverviewRuler-currentContentForeground: rgba(64, 200, 174, 0.5);\n    --vscode-editorOverviewRuler-deletedForeground: rgba(0, 122, 204, 0.6);\n    --vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);\n    --vscode-editorOverviewRuler-findMatchForeground: rgba(246, 185, 77, 0.7);\n    --vscode-editorOverviewRuler-incomingContentForeground: rgba(64, 166, 255, 0.5);\n    --vscode-editorOverviewRuler-infoForeground: rgba(18, 18, 136, 0.7);\n    --vscode-editorOverviewRuler-modifiedForeground: rgba(0, 122, 204, 0.6);\n    --vscode-editorOverviewRuler-rangeHighlightForeground: rgba(0, 122, 204, 0.6);\n    --vscode-editorOverviewRuler-selectionHighlightForeground: rgba(160, 160, 160, 0.8);\n    --vscode-editorOverviewRuler-warningForeground: rgba(18, 136, 18, 0.7);\n    --vscode-editorOverviewRuler-wordHighlightForeground: rgba(160, 160, 160, 0.8);\n    --vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(192, 160, 192, 0.8);\n    --vscode-editorPane-background: #263238;\n    --vscode-editorRuler-foreground: #37474f;\n    --vscode-editorSuggestWidget-background: #263238;\n    --vscode-editorSuggestWidget-border: rgba(255, 255, 255, 0.06);\n    --vscode-editorSuggestWidget-foreground: #eeffff;\n    --vscode-editorSuggestWidget-highlightForeground: #80cbc4;\n    --vscode-editorSuggestWidget-selectedBackground: rgba(0, 0, 0, 0.31);\n    --vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.67);\n    --vscode-editorWarning-foreground: rgba(195, 232, 141, 0.44);\n    --vscode-editorWhitespace-foreground: rgba(238, 255, 255, 0.25);\n    --vscode-editorWidget-background: #192227;\n    --vscode-editorWidget-border: #ff0000;\n    --vscode-editorWidget-resizeBorder: #80cbc4;\n    --vscode-errorForeground: #f48771;\n    --vscode-extensionButton-prominentBackground: rgba(195, 232, 141, 0.56);\n    --vscode-extensionButton-prominentForeground: #ffffff;\n    --vscode-extensionButton-prominentHoverBackground: #c3e88d;\n    --vscode-focusBorder: rgba(255, 255, 255, 0);\n    --vscode-foreground: #cccccc;\n    --vscode-gitDecoration-addedResourceForeground: #81b88b;\n    --vscode-gitDecoration-conflictingResourceForeground: rgba(255, 203, 107, 0.56);\n    --vscode-gitDecoration-deletedResourceForeground: rgba(255, 83, 112, 0.56);\n    --vscode-gitDecoration-ignoredResourceForeground: rgba(95, 122, 135, 0.56);\n    --vscode-gitDecoration-modifiedResourceForeground: rgba(130, 170, 255, 0.56);\n    --vscode-gitDecoration-submoduleResourceForeground: #8db9e2;\n    --vscode-gitDecoration-untrackedResourceForeground: rgba(195, 232, 141, 0.56);\n    --vscode-gitlens-gutterBackgroundColor: rgba(255, 255, 255, 0.07);\n    --vscode-gitlens-gutterForegroundColor: #bebebe;\n    --vscode-gitlens-gutterUncommittedForegroundColor: rgba(0, 188, 242, 0.6);\n    --vscode-gitlens-lineHighlightBackgroundColor: rgba(0, 188, 242, 0.2);\n    --vscode-gitlens-lineHighlightOverviewRulerColor: rgba(0, 188, 242, 0.6);\n    --vscode-gitlens-trailingLineBackgroundColor: rgba(0, 0, 0, 0);\n    --vscode-gitlens-trailingLineForegroundColor: rgba(153, 153, 153, 0.35);\n    --vscode-input-background: #303c41;\n    --vscode-input-border: rgba(255, 255, 255, 0.06);\n    --vscode-input-foreground: #eeffff;\n    --vscode-input-placeholderForeground: rgba(238, 255, 255, 0.38);\n    --vscode-inputOption-activeBorder: #007acc;\n    --vscode-inputValidation-errorBackground: #5a1d1d;\n    --vscode-inputValidation-errorBorder: rgba(255, 83, 112, 0.31);\n    --vscode-inputValidation-infoBackground: #063b49;\n    --vscode-inputValidation-infoBorder: rgba(130, 170, 255, 0.31);\n    --vscode-inputValidation-warningBackground: #352a05;\n    --vscode-inputValidation-warningBorder: rgba(255, 203, 107, 0.31);\n    --vscode-list-activeSelectionBackground: #192227;\n    --vscode-list-activeSelectionForeground: #80cbc4;\n    --vscode-list-dropBackground: rgba(238, 255, 255, 0.13);\n    --vscode-list-errorForeground: #f88070;\n    --vscode-list-focusBackground: rgba(238, 255, 255, 0.13);\n    --vscode-list-focusForeground: #eeffff;\n    --vscode-list-highlightForeground: #80cbc4;\n    --vscode-list-hoverBackground: #192227;\n    --vscode-list-hoverForeground: #ffffff;\n    --vscode-list-inactiveFocusBackground: #313135;\n    --vscode-list-inactiveSelectionBackground: rgba(0, 0, 0, 0.19);\n    --vscode-list-inactiveSelectionForeground: #80cbc4;\n    --vscode-list-invalidItemForeground: #b89500;\n    --vscode-list-warningForeground: #4d9e4d;\n    --vscode-menu-background: #263238;\n    --vscode-menu-foreground: #eeffff;\n    --vscode-menu-selectionBackground: rgba(0, 0, 0, 0.31);\n    --vscode-menu-selectionBorder: rgba(0, 0, 0, 0.19);\n    --vscode-menu-selectionForeground: #80cbc4;\n    --vscode-menu-separatorBackground: #eeffff;\n    --vscode-menubar-selectionBackground: rgba(0, 0, 0, 0.19);\n    --vscode-menubar-selectionBorder: rgba(0, 0, 0, 0.19);\n    --vscode-menubar-selectionForeground: #80cbc4;\n    --vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);\n    --vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);\n    --vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);\n    --vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);\n    --vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);\n    --vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);\n    --vscode-notificationCenterHeader-background: #314149;\n    --vscode-notificationLink-foreground: #80cbc4;\n    --vscode-notifications-background: #263238;\n    --vscode-notifications-border: #314149;\n    --vscode-notifications-foreground: #eeffff;\n    --vscode-panel-background: #192227;\n    --vscode-panel-border: rgba(0, 0, 0, 0.38);\n    --vscode-panel-dropBackground: #eeffff;\n    --vscode-panelTitle-activeBorder: #80cbc4;\n    --vscode-panelTitle-activeForeground: #ffffff;\n    --vscode-panelTitle-inactiveForeground: #eeffff;\n    --vscode-peekView-border: rgba(0, 0, 0, 0.19);\n    --vscode-peekViewEditor-background: rgba(238, 255, 255, 0.02);\n    --vscode-peekViewEditor-matchHighlightBackground: rgba(128, 203, 196, 0.13);\n    --vscode-peekViewEditorGutter-background: rgba(238, 255, 255, 0.02);\n    --vscode-peekViewResult-background: rgba(238, 255, 255, 0.02);\n    --vscode-peekViewResult-fileForeground: #ffffff;\n    --vscode-peekViewResult-lineForeground: #bbbbbb;\n    --vscode-peekViewResult-matchHighlightBackground: rgba(128, 203, 196, 0.13);\n    --vscode-peekViewResult-selectionBackground: rgba(95, 122, 135, 0.44);\n    --vscode-peekViewResult-selectionForeground: #ffffff;\n    --vscode-peekViewTitle-background: rgba(238, 255, 255, 0.02);\n    --vscode-peekViewTitleDescription-foreground: rgba(238, 255, 255, 0.38);\n    --vscode-peekViewTitleLabel-foreground: #ffffff;\n    --vscode-pickerGroup-border: #3f3f46;\n    --vscode-pickerGroup-foreground: #80cbc4;\n    --vscode-progressBar-background: #80cbc4;\n    --vscode-scrollbar-shadow: rgba(38, 50, 56, 0);\n    --vscode-scrollbarSlider-activeBackground: #80cbc4;\n    --vscode-scrollbarSlider-background: rgba(238, 255, 255, 0.13);\n    --vscode-scrollbarSlider-hoverBackground: rgba(238, 255, 255, 0.06);\n    --vscode-selection-background: #eeffff;\n    --vscode-settings-checkboxBackground: #192227;\n    --vscode-settings-checkboxBorder: rgba(255, 255, 255, 0.06);\n    --vscode-settings-checkboxForeground: #eeffff;\n    --vscode-settings-dropdownBackground: #192227;\n    --vscode-settings-dropdownBorder: rgba(255, 255, 255, 0.06);\n    --vscode-settings-dropdownForeground: #eeffff;\n    --vscode-settings-dropdownListBorder: #ff0000;\n    --vscode-settings-headerForeground: #80cbc4;\n    --vscode-settings-modifiedItemIndicator: #80cbc4;\n    --vscode-settings-numberInputBackground: #192227;\n    --vscode-settings-numberInputBorder: rgba(255, 255, 255, 0.06);\n    --vscode-settings-numberInputForeground: #eeffff;\n    --vscode-settings-textInputBackground: #192227;\n    --vscode-settings-textInputBorder: rgba(255, 255, 255, 0.06);\n    --vscode-settings-textInputForeground: #eeffff;\n    --vscode-sideBar-background: #192227;\n    --vscode-sideBar-border: rgba(0, 0, 0, 0.38);\n    --vscode-sideBar-dropBackground: rgba(255, 255, 255, 0.12);\n    --vscode-sideBar-foreground: #5f7a87;\n    --vscode-sideBarSectionHeader-background: #192227;\n    --vscode-sideBarSectionHeader-border: rgba(0, 0, 0, 0.38);\n    --vscode-sideBarSectionHeader-foreground: #5f7a87;\n    --vscode-sideBarTitle-foreground: #eeffff;\n    --vscode-statusBar-background: #192227;\n    --vscode-statusBar-border: rgba(0, 0, 0, 0.38);\n    --vscode-statusBar-debuggingBackground: #c792ea;\n    --vscode-statusBar-debuggingBorder: rgba(0, 0, 0, 0.38);\n    --vscode-statusBar-debuggingForeground: #ffffff;\n    --vscode-statusBar-foreground: #546e7a;\n    --vscode-statusBar-noFolderBackground: #263238;\n    --vscode-statusBar-noFolderBorder: rgba(0, 0, 0, 0.38);\n    --vscode-statusBar-noFolderForeground: #546e7a;\n    --vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);\n    --vscode-statusBarItem-hoverBackground: rgba(84, 110, 122, 0.13);\n    --vscode-statusBarItem-prominentBackground: #388a34;\n    --vscode-statusBarItem-prominentHoverBackground: #369432;\n    --vscode-tab-activeBackground: #263238;\n    --vscode-tab-activeBorder: #80cbc4;\n    --vscode-tab-activeForeground: #ffffff;\n    --vscode-tab-activeModifiedBorder: #5f7a87;\n    --vscode-tab-border: #263238;\n    --vscode-tab-inactiveBackground: #263238;\n    --vscode-tab-inactiveForeground: #5f7a87;\n    --vscode-tab-inactiveModifiedBorder: rgba(95, 122, 135, 0.5);\n    --vscode-tab-unfocusedActiveBorder: #546e7a;\n    --vscode-tab-unfocusedActiveForeground: #eeffff;\n    --vscode-tab-unfocusedActiveModifiedBorder: rgba(95, 122, 135, 0.5);\n    --vscode-tab-unfocusedInactiveForeground: rgba(95, 122, 135, 0.5);\n    --vscode-tab-unfocusedInactiveModifiedBorder: rgba(95, 122, 135, 0.25);\n    --vscode-terminal-ansiBlack: #000000;\n    --vscode-terminal-ansiBlue: #82aaff;\n    --vscode-terminal-ansiBrightBlack: #546e7a;\n    --vscode-terminal-ansiBrightBlue: #82aaff;\n    --vscode-terminal-ansiBrightCyan: #89ddff;\n    --vscode-terminal-ansiBrightGreen: #c3e88d;\n    --vscode-terminal-ansiBrightMagenta: #c792ea;\n    --vscode-terminal-ansiBrightRed: #ff5370;\n    --vscode-terminal-ansiBrightWhite: #ffffff;\n    --vscode-terminal-ansiBrightYellow: #ffcb6b;\n    --vscode-terminal-ansiCyan: #89ddff;\n    --vscode-terminal-ansiGreen: #c3e88d;\n    --vscode-terminal-ansiMagenta: #c792ea;\n    --vscode-terminal-ansiRed: #ff5370;\n    --vscode-terminal-ansiWhite: #ffffff;\n    --vscode-terminal-ansiYellow: #ffcb6b;\n    --vscode-terminal-background: #192227;\n    --vscode-terminal-border: rgba(0, 0, 0, 0.38);\n    --vscode-terminal-foreground: #cccccc;\n    --vscode-terminal-selectionBackground: rgba(255, 255, 255, 0.25);\n    --vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);\n    --vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);\n    --vscode-textCodeBlock-background: rgba(10, 10, 10, 0.4);\n    --vscode-textLink-activeForeground: #eeffff;\n    --vscode-textLink-foreground: #80cbc4;\n    --vscode-textPreformat-foreground: #d7ba7d;\n    --vscode-textSeparator-foreground: rgba(255, 255, 255, 0.18);\n    --vscode-titleBar-activeBackground: #192227;\n    --vscode-titleBar-activeForeground: #eeffff;\n    --vscode-titleBar-border: rgba(0, 0, 0, 0.38);\n    --vscode-titleBar-inactiveBackground: #192227;\n    --vscode-titleBar-inactiveForeground: #5f7a87;\n    --vscode-widget-shadow: rgba(0, 0, 0, 0.19);\n  }\n    "
  },
  {
    "path": "webview/src/vscode-light.scss",
    "content": ":root {\n\t--vscode-activityBar-background: #2c2c2c;\n\t--vscode-activityBar-dropBackground: rgba(255, 255, 255, 0.12);\n\t--vscode-activityBar-foreground: #ffffff;\n\t--vscode-activityBar-inactiveForeground: rgba(255, 255, 255, 0.6);\n\t--vscode-activityBarBadge-background: #007acc;\n\t--vscode-activityBarBadge-foreground: #ffffff;\n\t--vscode-badge-background: #c4c4c4;\n\t--vscode-badge-foreground: #333333;\n\t--vscode-breadcrumb-activeSelectionForeground: #4e4e4e;\n\t--vscode-breadcrumb-background: #ffffff;\n\t--vscode-breadcrumb-focusForeground: #4e4e4e;\n\t--vscode-breadcrumb-foreground: rgba(97, 97, 97, 0.8);\n\t--vscode-breadcrumbPicker-background: #f3f3f3;\n\t--vscode-button-background: #007acc;\n\t--vscode-button-foreground: #ffffff;\n\t--vscode-button-hoverBackground: #0062a3;\n\t--vscode-debugExceptionWidget-background: #f1dfde;\n\t--vscode-debugExceptionWidget-border: #a31515;\n\t--vscode-debugToolBar-background: #f3f3f3;\n\t--vscode-descriptionForeground: #717171;\n\t--vscode-diffEditor-insertedTextBackground: rgba(155, 185, 85, 0.2);\n\t--vscode-diffEditor-removedTextBackground: rgba(255, 0, 0, 0.2);\n\t--vscode-dropdown-background: #ffffff;\n\t--vscode-dropdown-border: #cecece;\n\t--vscode-editor-background: #ffffff;\n\t--vscode-editor-findMatchBackground: #a8ac94;\n\t--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);\n\t--vscode-editor-findRangeHighlightBackground: rgba(180, 180, 180, 0.3);\n\t--vscode-editor-focusedStackFrameHighlightBackground: rgba(\n\t\t206,\n\t\t231,\n\t\t206,\n\t\t0.45\n\t);\n\t--vscode-editor-font-family: Consolas, \"Courier New\", monospace;\n\t--vscode-editor-font-size: 14;\n\t--vscode-editor-font-weight: normal;\n\t--vscode-editor-foreground: #000000;\n\t--vscode-editor-hoverHighlightBackground: rgba(173, 214, 255, 0.15);\n\t--vscode-editor-inactiveSelectionBackground: #e5ebf1;\n\t--vscode-editor-lineHighlightBorder: #eeeeee;\n\t--vscode-editor-rangeHighlightBackground: rgba(253, 255, 0, 0.2);\n\t--vscode-editor-selectionBackground: #add6ff;\n\t--vscode-editor-selectionHighlightBackground: rgba(173, 214, 255, 0.5);\n\t--vscode-editor-snippetFinalTabstopHighlightBorder: rgba(10, 50, 100, 0.5);\n\t--vscode-editor-snippetTabstopHighlightBackground: rgba(10, 50, 100, 0.2);\n\t--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 102, 0.45);\n\t--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.25);\n\t--vscode-editor-wordHighlightStrongBackground: rgba(14, 99, 156, 0.25);\n\t--vscode-editorActiveLineNumber-foreground: #0b216f;\n\t--vscode-editorBracketMatch-background: rgba(0, 100, 0, 0.1);\n\t--vscode-editorBracketMatch-border: #b9b9b9;\n\t--vscode-editorCodeLens-foreground: #999999;\n\t--vscode-editorCursor-foreground: #000000;\n\t--vscode-editorError-foreground: #e51400;\n\t--vscode-editorGroup-border: #e7e7e7;\n\t--vscode-editorGroup-dropBackground: rgba(38, 119, 203, 0.18);\n\t--vscode-editorGroupHeader-noTabsBackground: #ffffff;\n\t--vscode-editorGroupHeader-tabsBackground: #f3f3f3;\n\t--vscode-editorGutter-addedBackground: #81b88b;\n\t--vscode-editorGutter-background: #ffffff;\n\t--vscode-editorGutter-commentRangeForeground: #c5c5c5;\n\t--vscode-editorGutter-deletedBackground: #ca4b51;\n\t--vscode-editorGutter-modifiedBackground: #66afe0;\n\t--vscode-editorHint-foreground: #6c6c6c;\n\t--vscode-editorHoverWidget-background: #f3f3f3;\n\t--vscode-editorHoverWidget-border: #c8c8c8;\n\t--vscode-editorHoverWidget-statusBarBackground: #e7e7e7;\n\t--vscode-editorIndentGuide-activeBackground: #939393;\n\t--vscode-editorIndentGuide-background: #d3d3d3;\n\t--vscode-editorInfo-foreground: #008000;\n\t--vscode-editorLineNumber-activeForeground: #0b216f;\n\t--vscode-editorLineNumber-foreground: #237893;\n\t--vscode-editorLink-activeForeground: #0000ff;\n\t--vscode-editorMarkerNavigation-background: #ffffff;\n\t--vscode-editorMarkerNavigationError-background: #e51400;\n\t--vscode-editorMarkerNavigationInfo-background: #008000;\n\t--vscode-editorMarkerNavigationWarning-background: #e9a700;\n\t--vscode-editorOverviewRuler-addedForeground: rgba(0, 122, 204, 0.6);\n\t--vscode-editorOverviewRuler-border: rgba(127, 127, 127, 0.3);\n\t--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;\n\t--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);\n\t--vscode-editorOverviewRuler-currentContentForeground: rgba(\n\t\t64,\n\t\t200,\n\t\t174,\n\t\t0.5\n\t);\n\t--vscode-editorOverviewRuler-deletedForeground: rgba(0, 122, 204, 0.6);\n\t--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);\n\t--vscode-editorOverviewRuler-findMatchForeground: rgba(209, 134, 22, 0.49);\n\t--vscode-editorOverviewRuler-incomingContentForeground: rgba(\n\t\t64,\n\t\t166,\n\t\t255,\n\t\t0.5\n\t);\n\t--vscode-editorOverviewRuler-infoForeground: #008000;\n\t--vscode-editorOverviewRuler-modifiedForeground: rgba(0, 122, 204, 0.6);\n\t--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(\n\t\t0,\n\t\t122,\n\t\t204,\n\t\t0.6\n\t);\n\t--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(\n\t\t160,\n\t\t160,\n\t\t160,\n\t\t0.8\n\t);\n\t--vscode-editorOverviewRuler-warningForeground: #e9a700;\n\t--vscode-editorOverviewRuler-wordHighlightForeground: rgba(\n\t\t160,\n\t\t160,\n\t\t160,\n\t\t0.8\n\t);\n\t--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(\n\t\t192,\n\t\t160,\n\t\t192,\n\t\t0.8\n\t);\n\t--vscode-editorPane-background: #ffffff;\n\t--vscode-editorRuler-foreground: #d3d3d3;\n\t--vscode-editorSuggestWidget-background: #f3f3f3;\n\t--vscode-editorSuggestWidget-border: #c8c8c8;\n\t--vscode-editorSuggestWidget-foreground: #000000;\n\t--vscode-editorSuggestWidget-highlightForeground: #0066bf;\n\t--vscode-editorSuggestWidget-selectedBackground: #d6ebff;\n\t--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.47);\n\t--vscode-editorWarning-foreground: #e9a700;\n\t--vscode-editorWhitespace-foreground: rgba(51, 51, 51, 0.2);\n\t--vscode-editorWidget-background: #f3f3f3;\n\t--vscode-editorWidget-border: #c8c8c8;\n\t--vscode-errorForeground: #a1260d;\n\t--vscode-extensionBadge-remoteBackground: #007acc;\n\t--vscode-extensionBadge-remoteForeground: #ffffff;\n\t--vscode-extensionButton-prominentBackground: #327e36;\n\t--vscode-extensionButton-prominentForeground: #ffffff;\n\t--vscode-extensionButton-prominentHoverBackground: #28632b;\n\t--vscode-focusBorder: rgba(0, 122, 204, 0.4);\n\t--vscode-font-family: -apple-system, BlinkMacSystemFont, \"Segoe WPC\",\n\t\t\"Segoe UI\", \"Ubuntu\", \"Droid Sans\", ans-serif;\n\t--vscode-font-size: 13px;\n\t--vscode-font-weight: normal;\n\t--vscode-foreground: #616161;\n\t--vscode-gitDecoration-addedResourceForeground: #587c0c;\n\t--vscode-gitDecoration-conflictingResourceForeground: #6c6cc4;\n\t--vscode-gitDecoration-deletedResourceForeground: #ad0707;\n\t--vscode-gitDecoration-ignoredResourceForeground: #8e8e90;\n\t--vscode-gitDecoration-modifiedResourceForeground: #895503;\n\t--vscode-gitDecoration-submoduleResourceForeground: #1258a7;\n\t--vscode-gitDecoration-untrackedResourceForeground: #007100;\n\t--vscode-gitlens-gutterBackgroundColor: rgba(0, 0, 0, 0.05);\n\t--vscode-gitlens-gutterForegroundColor: #747474;\n\t--vscode-gitlens-gutterUncommittedForegroundColor: rgba(0, 188, 242, 0.6);\n\t--vscode-gitlens-lineHighlightBackgroundColor: rgba(0, 188, 242, 0.2);\n\t--vscode-gitlens-lineHighlightOverviewRulerColor: rgba(0, 188, 242, 0.6);\n\t--vscode-gitlens-trailingLineBackgroundColor: rgba(0, 0, 0, 0);\n\t--vscode-gitlens-trailingLineForegroundColor: rgba(153, 153, 153, 0.35);\n\t--vscode-input-background: #ffffff;\n\t--vscode-input-foreground: #616161;\n\t--vscode-input-placeholderForeground: #767676;\n\t--vscode-inputOption-activeBorder: #007acc;\n\t--vscode-inputValidation-errorBackground: #f2dede;\n\t--vscode-inputValidation-errorBorder: #be1100;\n\t--vscode-inputValidation-infoBackground: #d6ecf2;\n\t--vscode-inputValidation-infoBorder: #007acc;\n\t--vscode-inputValidation-warningBackground: #f6f5d2;\n\t--vscode-inputValidation-warningBorder: #b89500;\n\t--vscode-list-activeSelectionBackground: #0074e8;\n\t--vscode-list-activeSelectionForeground: #ffffff;\n\t--vscode-list-dropBackground: #d6ebff;\n\t--vscode-list-errorForeground: #b01011;\n\t--vscode-list-focusBackground: #d6ebff;\n\t--vscode-list-highlightForeground: #0066bf;\n\t--vscode-list-hoverBackground: #e8e8e8;\n\t--vscode-list-inactiveSelectionBackground: #e4e6f1;\n\t--vscode-list-invalidItemForeground: #b89500;\n\t--vscode-list-warningForeground: #855f00;\n\t--vscode-listFilterWidget-background: #efc1ad;\n\t--vscode-listFilterWidget-noMatchesOutline: #be1100;\n\t--vscode-listFilterWidget-outline: rgba(0, 0, 0, 0);\n\t--vscode-menu-background: #ffffff;\n\t--vscode-menu-foreground: #616161;\n\t--vscode-menu-selectionBackground: #0074e8;\n\t--vscode-menu-selectionForeground: #ffffff;\n\t--vscode-menu-separatorBackground: #888888;\n\t--vscode-menubar-selectionBackground: rgba(0, 0, 0, 0.1);\n\t--vscode-menubar-selectionForeground: #333333;\n\t--vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);\n\t--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);\n\t--vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);\n\t--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);\n\t--vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);\n\t--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);\n\t--vscode-notificationCenterHeader-background: #e7e7e7;\n\t--vscode-notificationLink-foreground: #006ab1;\n\t--vscode-notifications-background: #f3f3f3;\n\t--vscode-notifications-border: #e7e7e7;\n\t--vscode-panel-background: #ffffff;\n\t--vscode-panel-border: rgba(128, 128, 128, 0.35);\n\t--vscode-panel-dropBackground: rgba(38, 119, 203, 0.18);\n\t--vscode-panelInput-border: #dddddd;\n\t--vscode-panelTitle-activeBorder: rgba(128, 128, 128, 0.35);\n\t--vscode-panelTitle-activeForeground: #424242;\n\t--vscode-panelTitle-inactiveForeground: rgba(66, 66, 66, 0.75);\n\t--vscode-peekView-border: #007acc;\n\t--vscode-peekViewEditor-background: #f2f8fc;\n\t--vscode-peekViewEditor-matchHighlightBackground: rgba(245, 216, 2, 0.87);\n\t--vscode-peekViewEditorGutter-background: #f2f8fc;\n\t--vscode-peekViewResult-background: #f3f3f3;\n\t--vscode-peekViewResult-fileForeground: #1e1e1e;\n\t--vscode-peekViewResult-lineForeground: #646465;\n\t--vscode-peekViewResult-matchHighlightBackground: rgba(234, 92, 0, 0.3);\n\t--vscode-peekViewResult-selectionBackground: rgba(51, 153, 255, 0.2);\n\t--vscode-peekViewResult-selectionForeground: #6c6c6c;\n\t--vscode-peekViewTitle-background: #ffffff;\n\t--vscode-peekViewTitleDescription-foreground: rgba(108, 108, 108, 0.7);\n\t--vscode-peekViewTitleLabel-foreground: #333333;\n\t--vscode-pickerGroup-border: #cccedb;\n\t--vscode-pickerGroup-foreground: #0066bf;\n\t--vscode-progressBar-background: #0e70c0;\n\t--vscode-quickInput-background: #f3f3f3;\n\t--vscode-scrollbar-shadow: #dddddd;\n\t--vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, 0.6);\n\t--vscode-scrollbarSlider-background: rgba(100, 100, 100, 0.4);\n\t--vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7);\n\t--vscode-settings-checkboxBackground: #ffffff;\n\t--vscode-settings-checkboxBorder: #cecece;\n\t--vscode-settings-dropdownBackground: #ffffff;\n\t--vscode-settings-dropdownBorder: #cecece;\n\t--vscode-settings-dropdownListBorder: #c8c8c8;\n\t--vscode-settings-headerForeground: #444444;\n\t--vscode-settings-modifiedItemIndicator: #66afe0;\n\t--vscode-settings-numberInputBackground: #ffffff;\n\t--vscode-settings-numberInputBorder: #cecece;\n\t--vscode-settings-numberInputForeground: #616161;\n\t--vscode-settings-textInputBackground: #ffffff;\n\t--vscode-settings-textInputBorder: #cecece;\n\t--vscode-settings-textInputForeground: #616161;\n\t--vscode-sideBar-background: #f3f3f3;\n\t--vscode-sideBar-dropBackground: rgba(0, 0, 0, 0.1);\n\t--vscode-sideBarSectionHeader-background: rgba(128, 128, 128, 0.2);\n\t--vscode-sideBarTitle-foreground: #6f6f6f;\n\t--vscode-statusBar-background: #007acc;\n\t--vscode-statusBar-debuggingBackground: #cc6633;\n\t--vscode-statusBar-debuggingForeground: #ffffff;\n\t--vscode-statusBar-foreground: #ffffff;\n\t--vscode-statusBar-noFolderBackground: #68217a;\n\t--vscode-statusBar-noFolderForeground: #ffffff;\n\t--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);\n\t--vscode-statusBarItem-hoverBackground: rgba(255, 255, 255, 0.12);\n\t--vscode-statusBarItem-prominentBackground: rgba(0, 0, 0, 0.5);\n\t--vscode-statusBarItem-prominentForeground: #ffffff;\n\t--vscode-statusBarItem-prominentHoverBackground: rgba(0, 0, 0, 0.3);\n\t--vscode-statusBarItem-remoteBackground: #16825d;\n\t--vscode-statusBarItem-remoteForeground: #ffffff;\n\t--vscode-tab-activeBackground: #ffffff;\n\t--vscode-tab-activeForeground: #333333;\n\t--vscode-tab-activeModifiedBorder: #33aaee;\n\t--vscode-tab-border: #f3f3f3;\n\t--vscode-tab-inactiveBackground: #ececec;\n\t--vscode-tab-inactiveForeground: rgba(51, 51, 51, 0.7);\n\t--vscode-tab-inactiveModifiedBorder: rgba(51, 170, 238, 0.5);\n\t--vscode-tab-unfocusedActiveBackground: #ffffff;\n\t--vscode-tab-unfocusedActiveForeground: rgba(51, 51, 51, 0.7);\n\t--vscode-tab-unfocusedActiveModifiedBorder: rgba(51, 170, 238, 0.7);\n\t--vscode-tab-unfocusedInactiveForeground: rgba(51, 51, 51, 0.35);\n\t--vscode-tab-unfocusedInactiveModifiedBorder: rgba(51, 170, 238, 0.25);\n\t--vscode-terminal-ansiBlack: #000000;\n\t--vscode-terminal-ansiBlue: #0451a5;\n\t--vscode-terminal-ansiBrightBlack: #666666;\n\t--vscode-terminal-ansiBrightBlue: #0451a5;\n\t--vscode-terminal-ansiBrightCyan: #0598bc;\n\t--vscode-terminal-ansiBrightGreen: #14ce14;\n\t--vscode-terminal-ansiBrightMagenta: #bc05bc;\n\t--vscode-terminal-ansiBrightRed: #cd3131;\n\t--vscode-terminal-ansiBrightWhite: #a5a5a5;\n\t--vscode-terminal-ansiBrightYellow: #b5ba00;\n\t--vscode-terminal-ansiCyan: #0598bc;\n\t--vscode-terminal-ansiGreen: #00bc00;\n\t--vscode-terminal-ansiMagenta: #bc05bc;\n\t--vscode-terminal-ansiRed: #cd3131;\n\t--vscode-terminal-ansiWhite: #555555;\n\t--vscode-terminal-ansiYellow: #949800;\n\t--vscode-terminal-background: #ffffff;\n\t--vscode-terminal-border: rgba(128, 128, 128, 0.35);\n\t--vscode-terminal-foreground: #333333;\n\t--vscode-terminal-selectionBackground: rgba(0, 0, 0, 0.25);\n\t--vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);\n\t--vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);\n\t--vscode-textCodeBlock-background: rgba(220, 220, 220, 0.4);\n\t--vscode-textLink-activeForeground: #006ab1;\n\t--vscode-textLink-foreground: #006ab1;\n\t--vscode-textPreformat-foreground: #a31515;\n\t--vscode-textSeparator-foreground: rgba(0, 0, 0, 0.18);\n\t--vscode-titleBar-activeBackground: #dddddd;\n\t--vscode-titleBar-activeForeground: #333333;\n\t--vscode-titleBar-inactiveBackground: rgba(221, 221, 221, 0.6);\n\t--vscode-titleBar-inactiveForeground: rgba(51, 51, 51, 0.6);\n\t--vscode-tree-indentGuidesStroke: #a9a9a9;\n\t--vscode-widget-shadow: #a8a8a8;\n}\n"
  },
  {
    "path": "webview/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ES2017\",\n\t\t\"module\": \"commonjs\",\n\t\t\"strict\": true,\n\t\t\"outDir\": \"dist\",\n\t\t\"lib\": [\"DOM\", \"ES2023\", \"DOM.Iterable\"],\n\t\t\"skipLibCheck\": true,\n\t\t\"rootDir\": \"./src\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"newLine\": \"LF\",\n\t\t\"sourceMap\": true,\n\t\t\"jsx\": \"react\",\n\t\t\"experimentalDecorators\": true,\n\t\t\"allowSyntheticDefaultImports\": true\n\t},\n\t\"include\": [\"src/**/*\"]\n}\n"
  },
  {
    "path": "webview/webpack.config.ts",
    "content": "import { CleanWebpackPlugin } from \"clean-webpack-plugin\";\nimport * as HtmlWebpackPlugin from \"html-webpack-plugin\";\nimport * as path from \"path\";\nimport * as webpack from \"webpack\";\nimport ForkTsCheckerWebpackPlugin = require(\"fork-ts-checker-webpack-plugin\");\nimport MonacoWebpackPlugin = require(\"monaco-editor-webpack-plugin\");\n\nconst r = (file: string) => path.resolve(__dirname, file);\n\nmodule.exports = {\n\tentry: [r(\"src/index.tsx\")],\n\toutput: {\n\t\tpath: r(\"dist\"),\n\t\tfilename: \"[name].js\",\n\t\tchunkFilename: \"[name]-[hash].js\",\n\t\tdevtoolModuleFilenameTemplate: (info: any) => {\n\t\t\tlet result = info.absoluteResourcePath.replace(/\\\\/g, \"/\");\n\t\t\tif (!result.startsWith(\"file:\")) {\n\t\t\t\t// Some paths already start with the file scheme.\n\t\t\t\tresult = \"file:///\" + result;\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t},\n\tresolve: {\n\t\textensions: [\".webpack.js\", \".web.js\", \".ts\", \".tsx\", \".js\"],\n\t},\n\tdevtool: \"source-map\",\n\tmodule: {\n\t\trules: [\n\t\t\t{\n\t\t\t\ttest: /\\.less$/,\n\t\t\t\tuse: [\"style-loader\", \"css-loader\", \"less-loader\"],\n\t\t\t},\n\t\t\t{ test: /\\.css$/, use: [\"style-loader\", \"css-loader\"] },\n\t\t\t{ test: /\\.scss$/, use: [\"style-loader\", \"css-loader\", \"sass-loader\"] },\n\t\t\t{\n\t\t\t\ttest: /\\.(jpe?g|png|gif|eot|ttf|svg|woff|woff2|md)$/i,\n\t\t\t\tloader: \"file-loader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\ttest: /\\.tsx?$/,\n\t\t\t\tloader: \"ts-loader\",\n\t\t\t\toptions: { transpileOnly: true },\n\t\t\t},\n\t\t],\n\t},\n\t/*node: {\n\t\tfs: \"empty\",\n\t},*/\n\tplugins: (() => {\n\t\tconst plugins: any[] = [\n\t\t\tnew HtmlWebpackPlugin({\n\t\t\t\ttitle: \"Debug Visualizer\",\n\t\t\t}),\n\t\t\tnew ForkTsCheckerWebpackPlugin(),\n\t\t\tnew CleanWebpackPlugin(),\n\t\t\tnew webpack.DefinePlugin({\n\t\t\t\t\"process.env\": JSON.stringify(process.env),\n\t\t\t}),\n\t\t\t/*new MonacoWebpackPlugin({\n\t\t\t\t// Add more languages here once webworker issues are solved.\n\t\t\t\tlanguages: [\"typescript\"],\n\t\t\t}),*/\n\t\t];\n\n\t\treturn plugins;\n\t})(),\n} as webpack.Configuration;\n"
  }
]